diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-01-31 22:22:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-01-31 22:22:27 +0000 |
commit | 825423e4c4f18289df2393951cfd2a7a31fc0464 (patch) | |
tree | 4ad80e981c3d9effa910d2247d118d254f9a5d09 /net/ipx/af_ipx.c | |
parent | c4693dc4856ab907a5c02187a8d398861bebfc7e (diff) |
Merge with Linux 2.4.1.
Diffstat (limited to 'net/ipx/af_ipx.c')
-rw-r--r-- | net/ipx/af_ipx.c | 1296 |
1 files changed, 577 insertions, 719 deletions
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 26cc63348..fb73651bf 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -61,6 +61,9 @@ * suggestions and guidance. * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, * November, 2000 + * Revision 043: Shared SKBs, don't mangle packets, some cleanups + * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, + * December, 2000 * * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT * pair. Also, now usage count is managed this way @@ -140,28 +143,23 @@ static ipx_interface *ipx_internal_net; atomic_t ipx_sock_nr; #endif -static int ipxcfg_set_auto_create(char val) +static void ipxcfg_set_auto_create(char val) { - if(ipxcfg_auto_create_interfaces != val) - { - if(val) + if (ipxcfg_auto_create_interfaces != val) { + if (val) MOD_INC_USE_COUNT; else MOD_DEC_USE_COUNT; ipxcfg_auto_create_interfaces = val; } - - return (0); } -static int ipxcfg_set_auto_select(char val) +static void ipxcfg_set_auto_select(char val) { ipxcfg_auto_select_primary = val; - if(val && (ipx_primary_net == NULL)) + if (val && !ipx_primary_net) ipx_primary_net = ipx_interfaces; - - return (0); } static int ipxcfg_get_config_data(ipx_config_data *arg) @@ -171,7 +169,7 @@ static int ipxcfg_get_config_data(ipx_config_data *arg) vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces; vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; - return (copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0); + return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0; } /**************************************************************************\ @@ -213,22 +211,19 @@ void ipx_remove_socket(struct sock *sk) /* Determine interface with which socket is associated */ intrfc = sk->protinfo.af_ipx.intrfc; - if(intrfc == NULL) + if (!intrfc) return; ipxitf_hold(intrfc); spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; - if(s == sk) - { + if (s == sk) { intrfc->if_sklist = s->next; goto out; } - while(s && s->next) - { - if(s->next == sk) - { + while (s && s->next) { + if (s->next == sk) { s->next = sk->next; goto out; } @@ -264,7 +259,7 @@ static ipx_route * ipxrtr_lookup(__u32); static void ipxitf_clear_primary_net(void) { - if(ipxcfg_auto_select_primary && (ipx_interfaces != NULL)) + if (ipxcfg_auto_select_primary && ipx_interfaces) ipx_primary_net = ipx_interfaces; else ipx_primary_net = NULL; @@ -273,14 +268,14 @@ static void ipxitf_clear_primary_net(void) static ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, unsigned short datalink) { - ipx_interface *i; + ipx_interface *i; - for(i = ipx_interfaces; - i && ((i->if_dev != dev) || (i->if_dlink_type != datalink)); + for (i = ipx_interfaces; + i && (i->if_dev != dev || i->if_dlink_type != datalink); i = i->if_next) ; - return (i); + return i; } static ipx_interface *ipxitf_find_using_phys(struct net_device *dev, @@ -298,12 +293,12 @@ static ipx_interface *ipxitf_find_using_phys(struct net_device *dev, static ipx_interface *ipxitf_find_using_net(__u32 net) { - ipx_interface *i; + ipx_interface *i; spin_lock_bh(&ipx_interfaces_lock); - if(net) - for(i = ipx_interfaces; i && (i->if_netnum != net); - i = i->if_next) + if (net) + for (i = ipx_interfaces; i && i->if_netnum != net; + i = i->if_next) ; else i = ipx_primary_net; @@ -311,7 +306,7 @@ static ipx_interface *ipxitf_find_using_net(__u32 net) ipxitf_hold(i); spin_unlock_bh(&ipx_interfaces_lock); - return (i); + return i; } /* Sockets are bound to a particular IPX interface. */ @@ -324,11 +319,10 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) spin_lock_bh(&intrfc->if_sklist_lock); sk->protinfo.af_ipx.intrfc = intrfc; sk->next = NULL; - if(intrfc->if_sklist == NULL) + if (!intrfc->if_sklist) intrfc->if_sklist = sk; - else - { - for (s = intrfc->if_sklist; s->next != NULL; s = s->next) + else { + for (s = intrfc->if_sklist; s->next; s = s->next) ; s->next = sk; } @@ -337,19 +331,21 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) } /* caller must hold intrfc->if_sklist_lock */ -static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, unsigned short port) +static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, + unsigned short port) { struct sock *s; - for(s = intrfc->if_sklist; - (s != NULL) && (s->protinfo.af_ipx.port != port); - s = s->next) + for (s = intrfc->if_sklist; + s && s->protinfo.af_ipx.port != port; + s = s->next) ; return s; } /* caller must hold a reference to intrfc */ -static struct sock *ipxitf_find_socket(ipx_interface *intrfc, unsigned short port) +static struct sock *ipxitf_find_socket(ipx_interface *intrfc, + unsigned short port) { struct sock *s; @@ -359,11 +355,10 @@ static struct sock *ipxitf_find_socket(ipx_interface *intrfc, unsigned short por sock_hold(s); spin_unlock_bh(&intrfc->if_sklist_lock); - return (s); + return s; } #ifdef CONFIG_IPX_INTERN - static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, unsigned char *node, unsigned short port) { @@ -373,19 +368,16 @@ static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; - while(s != NULL) - { - if((s->protinfo.af_ipx.port == port) - && (memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0)) - { + while (s) { + if (s->protinfo.af_ipx.port == port && + !memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN)) break; - } s = s->next; } spin_unlock_bh(&intrfc->if_sklist_lock); ipxitf_put(intrfc); - return (s); + return s; } #endif @@ -401,8 +393,7 @@ static void __ipxitf_down(ipx_interface *intrfc) spin_lock_bh(&intrfc->if_sklist_lock); /* error sockets */ - for(s = intrfc->if_sklist; s != NULL; ) - { + for (s = intrfc->if_sklist; s; ) { s->err = ENOLINK; s->error_report(s); s->protinfo.af_ipx.intrfc = NULL; @@ -416,30 +407,27 @@ static void __ipxitf_down(ipx_interface *intrfc) spin_unlock_bh(&intrfc->if_sklist_lock); /* remove this interface from list */ - if(intrfc == ipx_interfaces) + if (intrfc == ipx_interfaces) ipx_interfaces = intrfc->if_next; - else - { - for(i = ipx_interfaces; - (i != NULL) && (i->if_next != intrfc); - i = i->if_next) + else { + for (i = ipx_interfaces; + i && i->if_next != intrfc; + i = i->if_next) ; - if((i != NULL) && (i->if_next == intrfc)) + if (i && i->if_next == intrfc) i->if_next = intrfc->if_next; } /* remove this interface from *special* networks */ - if(intrfc == ipx_primary_net) + if (intrfc == ipx_primary_net) ipxitf_clear_primary_net(); - if(intrfc == ipx_internal_net) + if (intrfc == ipx_internal_net) ipx_internal_net = NULL; if (intrfc->if_dev) dev_put(intrfc->if_dev); kfree(intrfc); MOD_DEC_USE_COUNT; - - return; } static void ipxitf_down(ipx_interface *intrfc) @@ -449,36 +437,31 @@ static void ipxitf_down(ipx_interface *intrfc) spin_unlock_bh(&ipx_interfaces_lock); } -static int ipxitf_device_event(struct notifier_block *notifier, unsigned long event, void *ptr) +static int ipxitf_device_event(struct notifier_block *notifier, + unsigned long event, void *ptr) { struct net_device *dev = ptr; ipx_interface *i, *tmp; - if(event != NETDEV_DOWN) + if (event != NETDEV_DOWN) return NOTIFY_DONE; spin_lock_bh(&ipx_interfaces_lock); - for(i = ipx_interfaces; i != NULL;) - { + for (i = ipx_interfaces; i;) { tmp = i->if_next; - if(i->if_dev == dev) + if (i->if_dev == dev) __ipxitf_put(i); i = tmp; } spin_unlock_bh(&ipx_interfaces_lock); - - return (NOTIFY_DONE); + return NOTIFY_DONE; } -static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) +static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) { - int retval; - - if((retval = sock_queue_rcv_skb(sock, skb)) < 0) + if (sock_queue_rcv_skb(sock, skb) < 0) kfree_skb(skb); - - return (retval); } /* @@ -500,57 +483,50 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; - while(s != NULL) - { - if((s->protinfo.af_ipx.port == ipx->ipx_dest.sock) - && (is_broadcast - || (memcmp(ipx->ipx_dest.node, s->protinfo.af_ipx.node, - IPX_NODE_LEN) == 0))) - { + while (s) { + if (s->protinfo.af_ipx.port == ipx->ipx_dest.sock && + (is_broadcast || !memcmp(ipx->ipx_dest.node, + s->protinfo.af_ipx.node, + IPX_NODE_LEN))) { /* We found a socket to which to send */ struct sk_buff *skb1; - if(copy != 0) - { + if (copy) { skb1 = skb_clone(skb, GFP_ATOMIC); ret = -ENOMEM; - if (skb1 == NULL) + if (!skb1) goto out; - } - else - { + } else { skb1 = skb; copy = 1; /* skb may only be used once */ } ipxitf_def_skb_handler(s, skb1); /* On an external interface, one socket can listen */ - if(intrfc != ipx_internal_net) + if (intrfc != ipx_internal_net) break; } s = s->next; } /* skb was solely for us, and we did not make a copy, so free it. */ - if(copy == 0) + if (!copy) kfree_skb(skb); ret = 0; out: spin_unlock_bh(&intrfc->if_sklist_lock); return ret; } - #else - -static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) +static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, + int copy) { struct ipxhdr *ipx = skb->nh.ipxh; struct sock *sock1 = NULL, *sock2 = NULL; struct sk_buff *skb1 = NULL, *skb2 = NULL; int ret; - if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) - { + if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) { /* * The packet's target is a NCP connection handler. We want to * hand it to the correct socket directly within the kernel, @@ -562,48 +538,34 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * VERY fast as well. */ int connection = 0; - - if (*((char*)(ipx+1)) == 0x22 && *((char*)(ipx+1)+1) == 0x22) - { - /* - * The packet is a NCP request - */ - connection = ( ((int) *((char*)(ipx+1)+5)) << 8 ) - | (int) *((char*)(ipx+1)+3); - } - else if (*((char*)(ipx+1))== 0x77 && *((char*)(ipx+1)+1) == 0x77) - { - /* - * The packet is a BURST packet - */ - connection = ( ((int) *((char*)(ipx+1)+9)) << 8 ) - | (int) *((char*)(ipx+1)+8); - } - - if (connection) - { - /* - * Now we have to look for a special NCP connection handling - * socket. Only these sockets have ipx_ncp_conn != 0, set - * by SIOCIPXNCPCONN. - */ + u8 *ncphdr = (u8 *)(ipx + 1); + + if (*ncphdr == 0x22 && *(ncphdr + 1) == 0x22) + /* The packet is a NCP request */ + connection = (((int) *(ncphdr + 5)) << 8) | + (int) *(ncphdr+3); + else if (*ncphdr == 0x77 && *(ncphdr + 1) == 0x77) + /* The packet is a BURST packet */ + connection = (((int) *(ncphdr+9)) << 8) | + (int) *(ncphdr+8); + + if (connection) { + /* Now we have to look for a special NCP connection + * handling socket. Only these sockets have + * ipx_ncp_conn != 0, set by SIOCIPXNCPCONN. */ spin_lock_bh(&intrfc->if_sklist_lock); - for (sock1=intrfc->if_sklist; - (sock1 != NULL) && - (sock1->protinfo.af_ipx.ipx_ncp_conn != connection); - sock1=sock1->next); + for (sock1 = intrfc->if_sklist; + sock1 && + sock1->protinfo.af_ipx.ipx_ncp_conn != connection; + sock1 = sock1->next); if (sock1) sock_hold(sock1); spin_unlock_bh(&intrfc->if_sklist_lock); } } - if (sock1 == NULL) - { - /* No special socket found, forward the packet the - * normal way. - */ + if (!sock1) + /* No special socket found, forward the packet the normal way */ sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); - } /* * We need to check if there is a primary net and if @@ -613,10 +575,8 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * 0x456(Diagnostic). */ - if(ipx_primary_net && (intrfc != ipx_primary_net)) - { - switch(ntohs(ipx->ipx_dest.sock)) - { + if (ipx_primary_net && intrfc != ipx_primary_net) { + switch (ntohs(ipx->ipx_dest.sock)) { case 0x452: case 0x453: case 0x456: @@ -637,11 +597,10 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c /* * If there is nothing to do return. The kfree will cancel any charging. */ - if(sock1 == NULL && sock2 == NULL) - { - if(!copy) + if (!sock1 && !sock2) { + if (!copy) kfree_skb(skb); - return (0); + return 0; } /* @@ -652,30 +611,30 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * copies, we do as much as is possible. */ - if(copy) + if (copy) skb1 = skb_clone(skb, GFP_ATOMIC); else skb1 = skb; ret = -ENOMEM; - if(skb1 == NULL) + if (!skb1) goto out; /* Do we need 2 SKBs? */ - if(sock1 && sock2) + if (sock1 && sock2) skb2 = skb_clone(skb1, GFP_ATOMIC); else skb2 = skb1; - if(sock1) - (void) ipxitf_def_skb_handler(sock1, skb1); + if (sock1) + ipxitf_def_skb_handler(sock1, skb1); ret = -ENOMEM; - if(skb2 == NULL) + if (!skb2) goto out; - if(sock2) - (void) ipxitf_def_skb_handler(sock2, skb2); + if (sock2) + ipxitf_def_skb_handler(sock2, skb2); ret = 0; out: if (sock1) @@ -686,7 +645,8 @@ out: if (sock1) } #endif /* CONFIG_IPX_INTERN */ -static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb) +static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, + struct sk_buff *skb) { struct sk_buff *skb2; int in_offset = skb->h.raw - skb->head; @@ -694,21 +654,21 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buf int len; /* Hopefully, most cases */ - if(in_offset >= out_offset) - return (skb); + if (in_offset >= out_offset) + return skb; /* Need new SKB */ len = skb->len + out_offset; skb2 = alloc_skb(len, GFP_ATOMIC); - if(skb2 != NULL) - { + if (skb2) { skb_reserve(skb2, out_offset); skb2->nh.raw = skb2->h.raw = skb_put(skb2,skb->len); memcpy(skb2->h.raw, skb->h.raw, skb->len); + memcpy(skb2->cb, skb->cb, sizeof(skb->cb)); } kfree_skb(skb); - return (skb2); + return skb2; } /* caller must hold a reference to intrfc */ @@ -716,6 +676,7 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buf static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) { struct ipxhdr *ipx = skb->nh.ipxh; + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; struct net_device *dev = intrfc->if_dev; struct datalink_proto *dl = intrfc->if_dlink; char dest_node[IPX_NODE_LEN]; @@ -727,7 +688,7 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) * packet to avoid unnecessary copies. */ - if((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) + if (!dl || !dev || dev->flags & IFF_LOOPBACK) send_to_wire = 0; /* No non looped */ /* @@ -737,30 +698,27 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) * up clones. */ - if(ipx->ipx_dest.net == intrfc->if_netnum) - { + if (cb->ipx_dest_net == intrfc->if_netnum) { /* * To our own node, loop and free the original. * The internal net will receive on all node address. */ - if((intrfc == ipx_internal_net) - || memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) - { + if (intrfc == ipx_internal_net || + !memcmp(intrfc->if_node, node, IPX_NODE_LEN)) { /* Don't charge sender */ skb_orphan(skb); /* Will charge receiver */ - return (ipxitf_demux_socket(intrfc, skb, 0)); + return ipxitf_demux_socket(intrfc, skb, 0); } /* Broadcast, loop and possibly keep to send on. */ - if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) - { - if(!send_to_wire) + if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) { + if (!send_to_wire) skb_orphan(skb); ipxitf_demux_socket(intrfc, skb, send_to_wire); - if(!send_to_wire) - return (0); + if (!send_to_wire) + return 0; } } @@ -769,36 +727,45 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) * We are still charging the sender. Which is right - the driver * free will handle this fairly. */ - if(ipx->ipx_source.net != intrfc->if_netnum) - { + if (cb->ipx_source_net != intrfc->if_netnum) { /* * Unshare the buffer before modifying the count in * case its a flood or tcpdump */ skb = skb_unshare(skb, GFP_ATOMIC); - if(!skb) - return (0); - if(++(ipx->ipx_tctrl) > ipxcfg_max_hops) + if (!skb) + return 0; + if (++(cb->ipx_tctrl) > ipxcfg_max_hops) send_to_wire = 0; } - if(!send_to_wire) - { + if (!send_to_wire) { kfree_skb(skb); - return (0); + return 0; } /* Determine the appropriate hardware address */ addr_len = dev->addr_len; - if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) + if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) memcpy(dest_node, dev->broadcast, addr_len); else memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len); /* Make any compensation for differing physical/data link size */ skb = ipxitf_adjust_skbuff(intrfc, skb); - if(skb == NULL) - return (0); + if (!skb) + return 0; + + ipx->ipx_tctrl = cb->ipx_tctrl; + ipx->ipx_dest.net = cb->ipx_dest_net; + ipx->ipx_source.net = cb->ipx_source_net; + /* see if we need to include the netnum in the route list */ + if (cb->last_hop_index >= 0) { + u32 *last_hop = (u32 *)(((u8 *) skb->data) + + sizeof(struct ipxhdr) + cb->last_hop_index * + sizeof(u32)); + *last_hop = intrfc->if_netnum; + } /* set up data link and physical headers */ skb->dev = dev; @@ -807,15 +774,14 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) /* Send it out */ dev_queue_xmit(skb); - - return (0); + return 0; } static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *); static int ipxitf_add_local_route(ipx_interface *intrfc) { - return (ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL)); + return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL); } static const char * ipx_frame_name(unsigned short); @@ -824,29 +790,26 @@ static const char * ipx_device_name(ipx_interface *); static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) { struct ipxhdr *ipx = skb->nh.ipxh; - ipx_interface *i; + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; int ret = 0; ipxitf_hold(intrfc); /* See if we should update our network number */ - if(!intrfc->if_netnum /* net number of intrfc not known yet (== 0) */ - && (ipx->ipx_source.net == ipx->ipx_dest.net) /* intra packet */ - && ipx->ipx_source.net) /* source net number of packet != 0 */ - { + if (!intrfc->if_netnum && /* net number of intrfc not known yet */ + cb->ipx_source_net == cb->ipx_dest_net && /* intra packet */ + cb->ipx_source_net) { + ipx_interface *i = ipxitf_find_using_net(cb->ipx_source_net); /* NB: NetWare servers lie about their hop count so we * dropped the test based on it. This is the best way * to determine this is a 0 hop count packet. */ - if((i=ipxitf_find_using_net(ipx->ipx_source.net)) == NULL) - { - intrfc->if_netnum = ipx->ipx_source.net; - (void) ipxitf_add_local_route(intrfc); - } - else - { + if (!i) { + intrfc->if_netnum = cb->ipx_source_net; + ipxitf_add_local_route(intrfc); + } else { printk(KERN_WARNING "IPX: Network number collision %lx\n %s %s and %s %s\n", - (long unsigned int) htonl(ipx->ipx_source.net), + (long unsigned int) htonl(cb->ipx_source_net), ipx_device_name(i), ipx_frame_name(i->if_dlink_type), ipx_device_name(intrfc), @@ -854,75 +817,63 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) ipxitf_put(i); } } + + cb->last_hop_index = -1; - if(ipx->ipx_type == IPX_TYPE_PPROP - && ipx->ipx_tctrl < 8 - && skb->pkt_type != PACKET_OTHERHOST - /* header + 8 network numbers */ - && ntohs(ipx->ipx_pktsize) >= sizeof(struct ipxhdr) + 8 * 4) - { + if (ipx->ipx_type == IPX_TYPE_PPROP && cb->ipx_tctrl < 8 && + skb->pkt_type != PACKET_OTHERHOST && + /* header + 8 network numbers */ + ntohs(ipx->ipx_pktsize) >= sizeof(struct ipxhdr) + 8 * 4) { int i; ipx_interface *ifcs; struct sk_buff *skb2; - __u32 *l; - char *c; - - c = (char *) skb->data; - c += sizeof(struct ipxhdr); - l = (__u32 *) c; - - i = 0; + char *c = ((char *) skb->data) + sizeof(struct ipxhdr); + u32 *l = (u32 *) c; /* Dump packet if already seen this net */ - for( ; i < ipx->ipx_tctrl; i++) - if(*l++ == intrfc->if_netnum) + for (i = 0; i < cb->ipx_tctrl; i++) + if (*l++ == intrfc->if_netnum) break; - if(i == ipx->ipx_tctrl) - { + if (i == cb->ipx_tctrl) { /* < 8 hops && input itfc not in list */ - *l = intrfc->if_netnum; /* insert recvd netnum into list */ - ipx->ipx_tctrl++; + /* insert recvd netnum into list */ + cb->last_hop_index = i; + cb->ipx_tctrl++; /* xmit on all other interfaces... */ spin_lock_bh(&ipx_interfaces_lock); - for(ifcs = ipx_interfaces; ifcs != NULL; ifcs = ifcs->if_next) - { + for (ifcs = ipx_interfaces; ifcs; + ifcs = ifcs->if_next) { /* Except unconfigured interfaces */ - if(ifcs->if_netnum == 0) + if (!ifcs->if_netnum) continue; /* That aren't in the list */ l = (__u32 *) c; - for(i = 0; i <= ipx->ipx_tctrl; i++) - if(ifcs->if_netnum == *l++) + for (i = 0; i <= cb->ipx_tctrl; i++) + if (ifcs->if_netnum == *l++) break; - if(i - 1 == ipx->ipx_tctrl) - { - ipx->ipx_dest.net = ifcs->if_netnum; + if (i - 1 == cb->ipx_tctrl) { + cb->ipx_dest_net = ifcs->if_netnum; skb2=skb_clone(skb, GFP_ATOMIC); if (skb2) ipxrtr_route_skb(skb2); } } spin_unlock_bh(&ipx_interfaces_lock); - - /* Reset network number in packet */ - ipx->ipx_dest.net = intrfc->if_netnum; } } - if(!ipx->ipx_dest.net) - ipx->ipx_dest.net = intrfc->if_netnum; - if(!ipx->ipx_source.net) - ipx->ipx_source.net = intrfc->if_netnum; + if (!cb->ipx_dest_net) + cb->ipx_dest_net = intrfc->if_netnum; + if (!cb->ipx_source_net) + cb->ipx_source_net = intrfc->if_netnum; - if(intrfc->if_netnum != ipx->ipx_dest.net) - { + if (intrfc->if_netnum != cb->ipx_dest_net) { /* We only route point-to-point packets. */ - if(skb->pkt_type == PACKET_HOST) - { + if (skb->pkt_type == PACKET_HOST) { skb=skb_unshare(skb, GFP_ATOMIC); - if(skb) + if (skb) ret = ipxrtr_route_skb(skb); goto out_intrfc; } @@ -931,9 +882,8 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } /* see if we should keep it */ - if((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) - || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) - { + if (!memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) || + !memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN)) { ret = ipxitf_demux_socket(intrfc, skb, 0); goto out_intrfc; } @@ -952,20 +902,17 @@ static void ipxitf_insert(ipx_interface *intrfc) intrfc->if_next = NULL; spin_lock_bh(&ipx_interfaces_lock); - if(ipx_interfaces == NULL) + if (!ipx_interfaces) ipx_interfaces = intrfc; - else - { - for(i = ipx_interfaces; i->if_next != NULL; i = i->if_next) + else { + for (i = ipx_interfaces; i->if_next; i = i->if_next) ; i->if_next = intrfc; } spin_unlock_bh(&ipx_interfaces_lock); - if(ipxcfg_auto_select_primary && (ipx_primary_net == NULL)) + if (ipxcfg_auto_select_primary && !ipx_primary_net) ipx_primary_net = intrfc; - - return; } static int ipxitf_create_internal(ipx_interface_definition *idef) @@ -974,21 +921,21 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) int ret; /* Only one primary network allowed */ - if(ipx_primary_net != NULL) - return (-EEXIST); + if (ipx_primary_net) + return -EEXIST; /* Must have a valid network number */ - if(!idef->ipx_network) - return (-EADDRNOTAVAIL); + if (!idef->ipx_network) + return -EADDRNOTAVAIL; intrfc = ipxitf_find_using_net(idef->ipx_network); - if(intrfc != NULL) { + if (intrfc) { ipxitf_put(intrfc); - return (-EADDRINUSE); + return -EADDRINUSE; } - intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if(intrfc == NULL) - return (-EAGAIN); + intrfc = kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + if (!intrfc) + return -EAGAIN; intrfc->if_dev = NULL; intrfc->if_netnum = idef->ipx_network; intrfc->if_dlink_type = 0; @@ -998,8 +945,7 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) intrfc->if_ipx_offset = 0; intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN); - ipx_internal_net = intrfc; - ipx_primary_net = intrfc; + ipx_internal_net = ipx_primary_net = intrfc; spin_lock_init(&intrfc->if_sklist_lock); atomic_set(&intrfc->refcnt, 1); MOD_INC_USE_COUNT; @@ -1013,22 +959,21 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) static int ipx_map_frame_type(unsigned char type) { - switch(type) - { + switch (type) { case IPX_FRAME_ETHERII: - return (htons(ETH_P_IPX)); + return htons(ETH_P_IPX); case IPX_FRAME_8022: - return (htons(ETH_P_802_2)); + return htons(ETH_P_802_2); case IPX_FRAME_SNAP: - return (htons(ETH_P_SNAP)); + return htons(ETH_P_SNAP); case IPX_FRAME_8023: - return (htons(ETH_P_802_3)); + return htons(ETH_P_802_3); } - return (0); + return 0; } static int ipxitf_create(ipx_interface_definition *idef) @@ -1039,29 +984,29 @@ static int ipxitf_create(ipx_interface_definition *idef) ipx_interface *intrfc; int err; - if(idef->ipx_special == IPX_INTERNAL) - return (ipxitf_create_internal(idef)); + if (idef->ipx_special == IPX_INTERNAL) + return ipxitf_create_internal(idef); - if((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL)) - return (-EEXIST); + if (idef->ipx_special == IPX_PRIMARY && ipx_primary_net) + return -EEXIST; intrfc = ipxitf_find_using_net(idef->ipx_network); - if(idef->ipx_network && intrfc != NULL) { + if (idef->ipx_network && intrfc) { ipxitf_put(intrfc); - return (-EADDRINUSE); + return -EADDRINUSE; } if (intrfc) ipxitf_put(intrfc); dev = dev_get_by_name(idef->ipx_device); - if(dev == NULL) - return (-ENODEV); + if (!dev) + return -ENODEV; - switch(idef->ipx_dlink_type) - { + switch (idef->ipx_dlink_type) { case IPX_FRAME_TR_8022: - printk("IPX frame type 802.2TR is obsolete. Use 802.2 instead.\n"); + printk(KERN_WARNING "IPX frame type 802.2TR is " + "obsolete Use 802.2 instead.\n"); /* fall through */ case IPX_FRAME_8022: @@ -1070,14 +1015,14 @@ static int ipxitf_create(ipx_interface_definition *idef) break; case IPX_FRAME_ETHERII: - if (dev->type != ARPHRD_IEEE802) - { + if (dev->type != ARPHRD_IEEE802) { dlink_type = htons(ETH_P_IPX); datalink = pEII_datalink; break; - } - else - printk("IPX frame type EtherII over token-ring is obsolete. Use SNAP instead.\n"); + } else + printk(KERN_WARNING "IPX frame type EtherII " + "over token-ring is obsolete. Use SNAP " + "instead.\n"); /* fall through */ case IPX_FRAME_SNAP: @@ -1096,24 +1041,24 @@ static int ipxitf_create(ipx_interface_definition *idef) } err = -ENETDOWN; - if(!(dev->flags & IFF_UP)) + if (!(dev->flags & IFF_UP)) goto out_dev; /* Check addresses are suitable */ err = -EINVAL; - if(dev->addr_len > IPX_NODE_LEN) + if (dev->addr_len > IPX_NODE_LEN) goto out_dev; err = -EPROTONOSUPPORT; - if(datalink == NULL) + if (!datalink) goto out_dev; - if((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) - { + intrfc = ipxitf_find_using_phys(dev, dlink_type); + if (!intrfc) { /* Ok now create */ - intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + intrfc = kmalloc(sizeof(ipx_interface), GFP_ATOMIC); err = -EAGAIN; - if(intrfc == NULL) + if (!intrfc) goto out_dev; intrfc->if_dev = dev; intrfc->if_netnum = idef->ipx_network; @@ -1122,17 +1067,16 @@ static int ipxitf_create(ipx_interface_definition *idef) intrfc->if_sklist = NULL; intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; /* Setup primary if necessary */ - if((idef->ipx_special == IPX_PRIMARY)) + if ((idef->ipx_special == IPX_PRIMARY)) ipx_primary_net = intrfc; intrfc->if_internal = 0; intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length; - if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN) == 0) - { + if (!memcmp(idef->ipx_node, "\000\000\000\000\000\000", + IPX_NODE_LEN)) { memset(intrfc->if_node, 0, IPX_NODE_LEN); memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), dev->dev_addr, dev->addr_len); - } - else + } else memcpy(intrfc->if_node, idef->ipx_node, IPX_NODE_LEN); spin_lock_init(&intrfc->if_sklist_lock); atomic_set(&intrfc->refcnt, 1); @@ -1144,7 +1088,7 @@ static int ipxitf_create(ipx_interface_definition *idef) /* If the network number is known, add a route */ err = 0; - if(!intrfc->if_netnum) + if (!intrfc->if_netnum) goto out_intrfc; err = ipxitf_add_local_route(intrfc); @@ -1164,10 +1108,8 @@ static int ipxitf_delete(ipx_interface_definition *idef) int ret = 0; spin_lock_bh(&ipx_interfaces_lock); - if(idef->ipx_special == IPX_INTERNAL) - { - if(ipx_internal_net != NULL) - { + if (idef->ipx_special == IPX_INTERNAL) { + if (ipx_internal_net) { __ipxitf_put(ipx_internal_net); goto out; } @@ -1176,19 +1118,19 @@ static int ipxitf_delete(ipx_interface_definition *idef) } dlink_type = ipx_map_frame_type(idef->ipx_dlink_type); - if(dlink_type == 0) { + if (!dlink_type) { ret = -EPROTONOSUPPORT; goto out; } dev = __dev_get_by_name(idef->ipx_device); - if(dev == NULL) { + if (!dev) { ret = -ENODEV; goto out; } intrfc = __ipxitf_find_using_phys(dev, dlink_type); - if(intrfc != NULL) + if (intrfc) __ipxitf_put(intrfc); else ret = -EINVAL; @@ -1198,13 +1140,12 @@ out: spin_unlock_bh(&ipx_interfaces_lock); } static ipx_interface *ipxitf_auto_create(struct net_device *dev, - unsigned short dlink_type) + unsigned short dlink_type) { struct datalink_proto *datalink = NULL; ipx_interface *intrfc; - switch(htons(dlink_type)) - { + switch (htons(dlink_type)) { case ETH_P_IPX: datalink = pEII_datalink; break; @@ -1222,19 +1163,18 @@ static ipx_interface *ipxitf_auto_create(struct net_device *dev, break; default: - return (NULL); + return NULL; } - if(dev == NULL) - return (NULL); + if (!dev) + return NULL; /* Check addresses are suitable */ - if(dev->addr_len>IPX_NODE_LEN) - return (NULL); + if (dev->addr_len > IPX_NODE_LEN) + return NULL; - intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if(intrfc != NULL) - { + intrfc = kmalloc(sizeof(ipx_interface), GFP_ATOMIC); + if (intrfc) { intrfc->if_dev = dev; intrfc->if_netnum = 0; intrfc->if_dlink_type = dlink_type; @@ -1253,27 +1193,25 @@ static ipx_interface *ipxitf_auto_create(struct net_device *dev, ipxitf_insert(intrfc); } - return (intrfc); + return intrfc; } static int ipxitf_ioctl(unsigned int cmd, void *arg) { struct ifreq ifr; - int err, val; + int err = 0, val; - switch(cmd) - { - case SIOCSIFADDR: - { + switch (cmd) { + case SIOCSIFADDR: { struct sockaddr_ipx *sipx; ipx_interface_definition f; - if(copy_from_user(&ifr, arg, sizeof(ifr))) - return (-EFAULT); + if (copy_from_user(&ifr, arg, sizeof(ifr))) + return -EFAULT; sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; - if(sipx->sipx_family != AF_IPX) - return (-EINVAL); + if (sipx->sipx_family != AF_IPX) + return -EINVAL; f.ipx_network = sipx->sipx_network; memcpy(f.ipx_device,ifr.ifr_name,sizeof(f.ipx_device)); @@ -1281,10 +1219,10 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) f.ipx_dlink_type = sipx->sipx_type; f.ipx_special = sipx->sipx_special; - if(sipx->sipx_action == IPX_DLTITF) - return (ipxitf_delete(&f)); + if (sipx->sipx_action == IPX_DLTITF) + return ipxitf_delete(&f); else - return (ipxitf_create(&f)); + return ipxitf_create(&f); } case SIOCGIFADDR: @@ -1293,50 +1231,46 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) ipx_interface *ipxif; struct net_device *dev; - if(copy_from_user(&ifr, arg, sizeof(ifr))) - return (-EFAULT); + if (copy_from_user(&ifr, arg, sizeof(ifr))) + return -EFAULT; sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; dev = __dev_get_by_name(ifr.ifr_name); - if(!dev) - return (-ENODEV); + if (!dev) + return -ENODEV; ipxif = ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type)); - if(ipxif == NULL) - return (-EADDRNOTAVAIL); + if (!ipxif) + return -EADDRNOTAVAIL; sipx->sipx_family = AF_IPX; sipx->sipx_network = ipxif->if_netnum; - memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node)); - err = -EFAULT; - if(!copy_to_user(arg, &ifr, sizeof(ifr))) - err = 0; + memcpy(sipx->sipx_node, ipxif->if_node, + sizeof(sipx->sipx_node)); + if (copy_to_user(arg, &ifr, sizeof(ifr))) + err = -EFAULT; ipxitf_put(ipxif); - return (err); + return err; } case SIOCAIPXITFCRT: - { - err = get_user(val, (unsigned char *) arg); - if(err) - return (err); - - return (ipxcfg_set_auto_create(val)); - } + if (get_user(val, (unsigned char *) arg)) + return -EFAULT; + ipxcfg_set_auto_create(val); + break; case SIOCAIPXPRISLT: - { - err = get_user(val, (unsigned char *) arg); - if(err) - return (err); - - return (ipxcfg_set_auto_select(val)); - } + if (get_user(val, (unsigned char *) arg)) + return -EFAULT; + ipxcfg_set_auto_select(val); + break; default: - return (-EINVAL); + return -EINVAL; } + + return 0; } /**************************************************************************\ @@ -1350,11 +1284,11 @@ static ipx_route *ipxrtr_lookup(__u32 net) ipx_route *r; read_lock_bh(&ipx_routes_lock); - for(r = ipx_routes; (r != NULL) && (r->ir_net != net); r = r->ir_next) + for (r = ipx_routes; r && r->ir_net != net; r = r->ir_next) ; read_unlock_bh(&ipx_routes_lock); - return (r); + return r; } /* caller must hold a reference to intrfc */ @@ -1365,34 +1299,30 @@ static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char /* Get a route structure; either existing or create */ rt = ipxrtr_lookup(network); - if(rt == NULL) - { - rt = (ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC); - if(rt == NULL) - return (-EAGAIN); + if (!rt) { + rt = kmalloc(sizeof(ipx_route),GFP_ATOMIC); + if (!rt) + return -EAGAIN; write_lock_bh(&ipx_routes_lock); rt->ir_next = ipx_routes; ipx_routes = rt; write_unlock_bh(&ipx_routes_lock); } - else if(intrfc == ipx_internal_net) - return (-EEXIST); + else if (intrfc == ipx_internal_net) + return -EEXIST; rt->ir_net = network; rt->ir_intrfc = intrfc; - if(node == NULL) - { + if (!node) { memset(rt->ir_router_node, '\0', IPX_NODE_LEN); rt->ir_routed = 0; - } - else - { + } else { memcpy(rt->ir_router_node, node, IPX_NODE_LEN); rt->ir_routed = 1; } - return (0); + return 0; } static void ipxrtr_del_routes(ipx_interface *intrfc) @@ -1400,14 +1330,11 @@ static void ipxrtr_del_routes(ipx_interface *intrfc) ipx_route **r, *tmp; write_lock_bh(&ipx_routes_lock); - for(r = &ipx_routes; (tmp = *r) != NULL;) - { - if(tmp->ir_intrfc == intrfc) - { + for (r = &ipx_routes; (tmp = *r) != NULL;) { + if (tmp->ir_intrfc == intrfc) { *r = tmp->ir_next; kfree(tmp); - } - else + } else r = &(tmp->ir_next); } write_unlock_bh(&ipx_routes_lock); @@ -1420,8 +1347,8 @@ static int ipxrtr_create(ipx_route_definition *rd) /* Find the appropriate interface */ intrfc = ipxitf_find_using_net(rd->ipx_router_network); - if(intrfc == NULL) - return (-ENETUNREACH); + if (!intrfc) + return -ENETUNREACH; ret = ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node); ipxitf_put(intrfc); return ret; @@ -1434,13 +1361,11 @@ static int ipxrtr_delete(long net) int err; write_lock_bh(&ipx_routes_lock); - for(r = &ipx_routes; (tmp = *r) != NULL;) - { - if(tmp->ir_net == net) - { + for (r = &ipx_routes; (tmp = *r) != NULL;) { + if (tmp->ir_net == net) { /* Directly connected; can't lose route */ err = -EPERM; - if(!(tmp->ir_routed)) + if (!tmp->ir_routed) goto out; *r = tmp->ir_next; @@ -1461,45 +1386,38 @@ out: write_unlock_bh(&ipx_routes_lock); */ /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ +/* This functions should *not* mess with packet contents */ -static __u16 ipx_set_checksum(struct ipxhdr *packet,int length) +static __u16 ipx_cksum(struct ipxhdr *packet,int length) { /* * NOTE: sum is a net byte order quantity, which optimizes the * loop. This only works on big and little endian machines. (I * don't know of a machine that isn't.) */ - - __u32 sum = 0; - - /* Pointer to second word - We skip the checksum field */ - __u16 *p = (__u16 *)&packet->ipx_pktsize; - - /* Number of complete words */ - __u32 i = length >> 1; - char hops = packet->ipx_tctrl; - - /* Hop count excluded from checksum calc */ - packet->ipx_tctrl = 0; - - /* Loop through all complete words except the checksum field */ - while(--i) + /* start at ipx_dest - We skip the checksum field and start with + * ipx_type before the loop, not considering ipx_tctrl in the calc */ + __u16 *p = (__u16 *)&packet->ipx_dest; + __u32 i = (length >> 1) - 1; /* Number of complete words */ + __u32 sum = packet->ipx_type << sizeof(packet->ipx_tctrl); + + /* Loop through all complete words except the checksum field, + * ipx_type (accounted above) and ipx_tctrl (not used in the cksum) */ + while (--i) sum += *p++; /* Add on the last part word if it exists */ - if(packet->ipx_pktsize & htons(1)) + if (packet->ipx_pktsize & htons(1)) sum += ntohs(0xff00) & *p; - packet->ipx_tctrl = hops; - /* Do final fixup */ sum = (sum & 0xffff) + (sum >> 16); /* It's a pity there's no concept of carry in C */ - if(sum >= 0x10000) + if (sum >= 0x10000) sum++; - return (~sum); + return ~sum; } /* @@ -1510,80 +1428,76 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru struct sk_buff *skb; ipx_interface *intrfc; struct ipxhdr *ipx; + struct ipx_cb *cb; int size; int ipx_offset; ipx_route *rt = NULL; int err; /* Find the appropriate interface on which to send packet */ - if(!usipx->sipx_network && (ipx_primary_net != NULL)) - { + if (!usipx->sipx_network && ipx_primary_net) { usipx->sipx_network = ipx_primary_net->if_netnum; intrfc = ipx_primary_net; - } - else - { + } else { rt = ipxrtr_lookup(usipx->sipx_network); - if(rt == NULL) - return (-ENETUNREACH); + if (!rt) + return -ENETUNREACH; intrfc = rt->ir_intrfc; } ipxitf_hold(intrfc); ipx_offset = intrfc->if_ipx_offset; - size = sizeof(struct ipxhdr) + len; - size += ipx_offset; + size = sizeof(struct ipxhdr) + len + ipx_offset; skb = sock_alloc_send_skb(sk, size, 0, noblock, &err); - if(skb == NULL) + if (!skb) goto out; skb_reserve(skb,ipx_offset); skb->sk = sk; + cb = (struct ipx_cb *) skb->cb; /* Fill in IPX header */ ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr)); ipx->ipx_pktsize= htons(len + sizeof(struct ipxhdr)); - ipx->ipx_tctrl = 0; + cb->ipx_tctrl = 0; ipx->ipx_type = usipx->sipx_type; skb->h.raw = (void *)skb->nh.ipxh = ipx; - ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum; + cb->last_hop_index = -1; #ifdef CONFIG_IPX_INTERN + cb->ipx_source_net = sk->protinfo.af_ipx.intrfc->if_netnum; memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); #else - if((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452) - { + err = ntohs(sk->protinfo.af_ipx.port); + if (err == 0x453 || err == 0x452) { /* RIP/SAP special handling for mars_nwe */ - ipx->ipx_source.net = intrfc->if_netnum; + cb->ipx_source_net = intrfc->if_netnum; memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN); - } - else - { - ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum; + } else { + cb->ipx_source_net = sk->protinfo.af_ipx.intrfc->if_netnum; memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); } #endif /* CONFIG_IPX_INTERN */ ipx->ipx_source.sock = sk->protinfo.af_ipx.port; - ipx->ipx_dest.net = usipx->sipx_network; + cb->ipx_dest_net = usipx->sipx_network; memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN); ipx->ipx_dest.sock = usipx->sipx_port; err = memcpy_fromiovec(skb_put(skb,len),iov,len); - if(err) - { + if (err) { kfree_skb(skb); goto out; } /* Apply checksum. Not allowed on 802.3 links. */ - if(sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023) + if (sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023) ipx->ipx_checksum=0xFFFF; else - ipx->ipx_checksum = ipx_set_checksum(ipx, len + sizeof(struct ipxhdr)); + ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); err = ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? rt->ir_router_node : ipx->ipx_dest.node); @@ -1594,21 +1508,20 @@ out: ipxitf_put(intrfc); int ipxrtr_route_skb(struct sk_buff *skb) { struct ipxhdr *ipx = skb->nh.ipxh; - ipx_route *r; + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; + ipx_route *r = ipxrtr_lookup(cb->ipx_dest_net); - r = ipxrtr_lookup(ipx->ipx_dest.net); - if(r == NULL) /* no known route */ - { + if (!r) { /* no known route */ kfree_skb(skb); - return (0); + return 0; } ipxitf_hold(r->ir_intrfc); - (void)ipxitf_send(r->ir_intrfc, skb, (r->ir_routed) ? + ipxitf_send(r->ir_intrfc, skb, (r->ir_routed) ? r->ir_router_node : ipx->ipx_dest.node); ipxitf_put(r->ir_intrfc); - return (0); + return 0; } /* @@ -1621,23 +1534,22 @@ static int ipxrtr_ioctl(unsigned int cmd, void *arg) int err; err = copy_from_user(&rt,arg,sizeof(rt)); - if(err) - return (-EFAULT); + if (err) + return -EFAULT; sg = (struct sockaddr_ipx *)&rt.rt_gateway; st = (struct sockaddr_ipx *)&rt.rt_dst; - if(!(rt.rt_flags & RTF_GATEWAY)) - return (-EINVAL); /* Direct routes are fixed */ - if(sg->sipx_family != AF_IPX) - return (-EINVAL); - if(st->sipx_family != AF_IPX) - return (-EINVAL); + if (!(rt.rt_flags & RTF_GATEWAY)) + return -EINVAL; /* Direct routes are fixed */ + if (sg->sipx_family != AF_IPX) + return -EINVAL; + if (st->sipx_family != AF_IPX) + return -EINVAL; - switch(cmd) - { + switch (cmd) { case SIOCDELRT: - return (ipxrtr_delete(st->sipx_network)); + return ipxrtr_delete(st->sipx_network); case SIOCADDRT: { @@ -1645,42 +1557,40 @@ static int ipxrtr_ioctl(unsigned int cmd, void *arg) f.ipx_network=st->sipx_network; f.ipx_router_network=sg->sipx_network; memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN); - return (ipxrtr_create(&f)); + return ipxrtr_create(&f); } - - default: - return (-EINVAL); } + + return -EINVAL; } static const char *ipx_frame_name(unsigned short frame) { - switch(ntohs(frame)) - { + switch (ntohs(frame)) { case ETH_P_IPX: - return ("EtherII"); + return "EtherII"; case ETH_P_802_2: - return ("802.2"); + return "802.2"; case ETH_P_SNAP: - return ("SNAP"); + return "SNAP"; case ETH_P_802_3: - return ("802.3"); + return "802.3"; case ETH_P_TR_802_2: - return ("802.2TR"); + return "802.2TR"; default: - return ("None"); + return "None"; } } static const char *ipx_device_name(ipx_interface *intrfc) { - return (intrfc->if_internal ? "Internal" : - (intrfc->if_dev ? intrfc->if_dev->name : "Unknown")); + return intrfc->if_internal ? "Internal" : + intrfc->if_dev ? intrfc->if_dev->name : "Unknown"; } /* Called from proc fs */ @@ -1700,13 +1610,12 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, #endif strcat(buffer+len++, "\n"); spin_lock_bh(&ipx_interfaces_lock); - for(i = ipx_interfaces; i != NULL; i = i->if_next) - { + for (i = ipx_interfaces; i; i = i->if_next) { len += sprintf(buffer+len, "%08lX ", (long unsigned int)ntohl(i->if_netnum)); len += sprintf(buffer+len,"%02X%02X%02X%02X%02X%02X ", i->if_node[0], i->if_node[1], i->if_node[2], i->if_node[3], i->if_node[4], i->if_node[5]); - len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ? + len += sprintf(buffer+len, "%-9s", i == ipx_primary_net ? "Yes" : "No"); len += sprintf(buffer+len, "%-11s", ipx_device_name(i)); len += sprintf(buffer+len, "%-9s", @@ -1718,12 +1627,11 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, /* Are we still dumping unwanted data then discard the record */ pos = begin + len; - if(pos < offset) - { + if (pos < offset) { len = 0; /* Keep dumping into the buffer start */ begin = pos; } - if(pos > offset + length) /* We have dumped enough */ + if (pos > offset + length) /* We have dumped enough */ break; } spin_unlock_bh(&ipx_interfaces_lock); @@ -1731,10 +1639,10 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, /* The data in question runs from begin to begin+len */ *start = buffer + (offset - begin); /* Start of wanted data */ len -= (offset - begin); /* Remove unwanted header data from length */ - if(len > length) + if (len > length) len = length; /* Remove unwanted tail data from length */ - return (len); + return len; } static int ipx_get_info(char *buffer, char **start, off_t offset, int length) @@ -1755,12 +1663,10 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) "State", "Uid"); spin_lock_bh(&ipx_interfaces_lock); - for(i = ipx_interfaces; i != NULL; i = i->if_next) - { + for (i = ipx_interfaces; i; i = i->if_next) { ipxitf_hold(i); spin_lock_bh(&i->if_sklist_lock); - for(s = i->if_sklist; s != NULL; s = s->next) - { + for (s = i->if_sklist; s; s = s->next) { #ifdef CONFIG_IPX_INTERN len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", @@ -1778,10 +1684,9 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) htons(s->protinfo.af_ipx.port)); #endif /* CONFIG_IPX_INTERN */ - if(s->state != TCP_ESTABLISHED) + if (s->state != TCP_ESTABLISHED) len += sprintf(buffer+len, "%-28s", "Not_Connected"); - else - { + else { len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", (unsigned long) htonl(s->protinfo.af_ipx.dest_addr.net), @@ -1801,13 +1706,12 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) s->state, SOCK_INODE(s->socket)->i_uid); pos = begin + len; - if(pos < offset) - { + if (pos < offset) { len = 0; begin = pos; } - if(pos > offset + length) /* We have dumped enough */ + if (pos > offset + length) /* We have dumped enough */ break; } spin_unlock_bh(&i->if_sklist_lock); @@ -1818,10 +1722,10 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) /* The data in question runs from begin to begin+len */ *start = buffer + (offset-begin); len -= (offset - begin); - if(len > length) + if (len > length) len = length; - return (len); + return len; } static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) @@ -1833,41 +1737,36 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) len += sprintf(buffer,"%-11s%-13s%s\n", "Network", "Router_Net", "Router_Node"); read_lock_bh(&ipx_routes_lock); - for(rt = ipx_routes; rt != NULL; rt = rt->ir_next) - { + for (rt = ipx_routes; rt; rt = rt->ir_next) { len += sprintf(buffer+len,"%08lX ", (long unsigned int) ntohl(rt->ir_net)); - if(rt->ir_routed) - { + if (rt->ir_routed) { len += sprintf(buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n", (long unsigned int) ntohl(rt->ir_intrfc->if_netnum), rt->ir_router_node[0], rt->ir_router_node[1], rt->ir_router_node[2], rt->ir_router_node[3], rt->ir_router_node[4], rt->ir_router_node[5]); - } - else - { + } else { len += sprintf(buffer+len, "%-13s%s\n", "Directly", "Connected"); } pos = begin + len; - if(pos < offset) - { - len = 0; + if (pos < offset) { + len = 0; begin = pos; } - if(pos > offset + length) + if (pos > offset + length) break; } read_unlock_bh(&ipx_routes_lock); *start = buffer + (offset - begin); len -= (offset - begin); - if(len > length) + if (len > length) len = length; - return (len); + return len; } /**************************************************************************\ @@ -1877,89 +1776,80 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) * * \**************************************************************************/ -static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) +static int ipx_setsockopt(struct socket *sock, int level, int optname, + char *optval, int optlen) { - struct sock *sk; - int err, opt; - - sk = sock->sk; + struct sock *sk = sock->sk; + int opt; - if(optlen != sizeof(int)) - return (-EINVAL); + if (optlen != sizeof(int)) + return -EINVAL; - err = get_user(opt, (unsigned int *)optval); - if(err) - return (err); + if (get_user(opt, (unsigned int *)optval)) + return -EFAULT; - switch(level) - { + switch (level) { case SOL_IPX: - switch(optname) - { + switch (optname) { case IPX_TYPE: sk->protinfo.af_ipx.type = opt; - return (0); + return 0; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } break; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } } static int ipx_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { - struct sock *sk; - int val=0; + struct sock *sk = sock->sk; + int val = 0; int len; - sk = sock->sk; - - switch(level) - { + switch (level) { case SOL_IPX: - switch(optname) - { + switch (optname) { case IPX_TYPE: val = sk->protinfo.af_ipx.type; break; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } break; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } - if(get_user(len, optlen)) - return (-EFAULT); + if (get_user(len, optlen)) + return -EFAULT; len = min(len, sizeof(int)); - if(put_user(len, optlen)) - return (-EFAULT); + if (put_user(len, optlen)) + return -EFAULT; - if(copy_to_user(optval, &val, len)) - return (-EFAULT); + if (copy_to_user(optval, &val, len)) + return -EFAULT; - return (0); + return 0; } static int ipx_create(struct socket *sock, int protocol) { struct sock *sk; - switch(sock->type) - { + switch (sock->type) { case SOCK_DGRAM: sk = sk_alloc(PF_IPX, GFP_KERNEL, 1); - if(sk == NULL) - return (-ENOMEM); + if (!sk) + return -ENOMEM; sock->ops = &ipx_dgram_ops; break; @@ -1968,12 +1858,12 @@ static int ipx_create(struct socket *sock, int protocol) * From this point on SPX sockets are handled * by af_spx.c and the methods replaced. */ - if(spx_family_ops) - return (spx_family_ops->create(sock,protocol)); + if (spx_family_ops) + return spx_family_ops->create(sock,protocol); /* Fall through if SPX is not loaded */ case SOCK_STREAM: /* Allow higher levels to piggyback */ default: - return (-ESOCKTNOSUPPORT); + return -ESOCKTNOSUPPORT; } #ifdef IPX_REFCNT_DEBUG atomic_inc(&ipx_sock_nr); @@ -1985,31 +1875,30 @@ static int ipx_create(struct socket *sock, int protocol) sk->no_check = 1; /* Checksum off by default */ MOD_INC_USE_COUNT; - - return (0); + return 0; } static int ipx_release(struct socket *sock) { struct sock *sk = sock->sk; - if(sk == NULL) - return (0); + if (!sk) + return 0; - if(!sk->dead) + if (!sk->dead) sk->state_change(sk); sk->dead = 1; sock->sk = NULL; ipx_destroy_socket(sk); - if(sock->type == SOCK_DGRAM) + if (sock->type == SOCK_DGRAM) MOD_DEC_USE_COUNT; - return (0); + return 0; } -/* caller must hold a referente to intrfc */ +/* caller must hold a reference to intrfc */ static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc) { @@ -2017,91 +1906,80 @@ static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc) spin_lock_bh(&intrfc->if_sklist_lock); - if(socketNum < IPX_MIN_EPHEMERAL_SOCKET) + if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; - while(__ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL) - { - if(socketNum > IPX_MAX_EPHEMERAL_SOCKET) + while (__ipxitf_find_socket(intrfc, ntohs(socketNum))) + if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; else socketNum++; - } spin_unlock_bh(&intrfc->if_sklist_lock); intrfc->if_sknum = socketNum; - return (ntohs(socketNum)); + return ntohs(socketNum); } static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { - struct sock *sk; + struct sock *sk = sock->sk; ipx_interface *intrfc; struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; int ret; - sk = sock->sk; - - if(sk->zapped == 0) - return (-EINVAL); + if (!sk->zapped) + return -EINVAL; - if(addr_len != sizeof(struct sockaddr_ipx)) - return (-EINVAL); + if (addr_len != sizeof(struct sockaddr_ipx)) + return -EINVAL; intrfc = ipxitf_find_using_net(addr->sipx_network); - if(intrfc == NULL) - return (-EADDRNOTAVAIL); + if (!intrfc) + return -EADDRNOTAVAIL; - if(addr->sipx_port == 0) - { + if (!addr->sipx_port) { addr->sipx_port = ipx_first_free_socketnum(intrfc); ret = -EINVAL; - if(addr->sipx_port == 0) + if (!addr->sipx_port) goto out; } /* protect IPX system stuff like routing/sap */ ret = -EACCES; - if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN)) + if (ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && + !capable(CAP_NET_ADMIN)) goto out; sk->protinfo.af_ipx.port = addr->sipx_port; #ifdef CONFIG_IPX_INTERN - if(intrfc == ipx_internal_net) - { + if (intrfc == ipx_internal_net) { /* The source address is to be set explicitly if the * socket is to be bound on the internal network. If a * node number 0 was specified, the default is used. */ ret = -EINVAL; - if(memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN) == 0) + if (!memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN)) goto out; - if(memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0) - { + if (!memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN)) memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, IPX_NODE_LEN); - } else - { - memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN); - } + memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, + IPX_NODE_LEN); ret = -EADDRINUSE; - if(ipxitf_find_internal_socket(intrfc, - sk->protinfo.af_ipx.node, - sk->protinfo.af_ipx.port) != NULL) - { + if (ipxitf_find_internal_socket(intrfc, + sk->protinfo.af_ipx.node, + sk->protinfo.af_ipx.port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); goto out; } - } - else - { + } else { /* Source addresses are easy. It must be our * network:node pair for an interface routed to IPX * with the ipx routing ioctl() @@ -2111,8 +1989,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) IPX_NODE_LEN); ret = -EADDRINUSE; - if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL) - { + if (ipxitf_find_socket(intrfc, addr->sipx_port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); @@ -2126,8 +2003,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) an interface routed to IPX with the ipx routing ioctl() */ ret = -EADDRINUSE; - if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL) - { + if (ipxitf_find_socket(intrfc, addr->sipx_port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); goto out; @@ -2153,13 +2029,12 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, sk->state = TCP_CLOSE; sock->state = SS_UNCONNECTED; - if(addr_len != sizeof(*addr)) - return (-EINVAL); + if (addr_len != sizeof(*addr)) + return -EINVAL; addr = (struct sockaddr_ipx *)uaddr; /* put the autobinding in */ - if(sk->protinfo.af_ipx.port == 0) - { + if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; int ret; @@ -2167,7 +2042,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if(sk->protinfo.af_ipx.intrfc) + if (sk->protinfo.af_ipx.intrfc) memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,IPX_NODE_LEN); else return -ENETDOWN; /* Someone zonked the iface */ @@ -2175,13 +2050,15 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if(ret != 0) - return (ret); + if (ret) + return ret; } - /* We can either connect to primary network or somewhere we can route to */ - if( !(addr->sipx_network == 0 && ipx_primary_net != NULL) && ipxrtr_lookup(addr->sipx_network) == NULL) - return (-ENETUNREACH); + /* We can either connect to primary network or somewhere + * we can route to */ + if (!(!addr->sipx_network && ipx_primary_net) && + !ipxrtr_lookup(addr->sipx_network)) + return -ENETUNREACH; sk->protinfo.af_ipx.dest_addr.net = addr->sipx_network; sk->protinfo.af_ipx.dest_addr.sock = addr->sipx_port; @@ -2189,41 +2066,34 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, addr->sipx_node,IPX_NODE_LEN); sk->protinfo.af_ipx.type = addr->sipx_type; - if(sock->type == SOCK_DGRAM ) - { + if (sock->type == SOCK_DGRAM) { sock->state = SS_CONNECTED; sk->state = TCP_ESTABLISHED; } - return (0); + return 0; } static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) + int *uaddr_len, int peer) { ipx_address *addr; struct sockaddr_ipx sipx; - struct sock *sk; - - sk = sock->sk; + struct sock *sk = sock->sk; *uaddr_len = sizeof(struct sockaddr_ipx); - if(peer) - { - if(sk->state != TCP_ESTABLISHED) - return (-ENOTCONN); + if (peer) { + if (sk->state != TCP_ESTABLISHED) + return -ENOTCONN; addr = &sk->protinfo.af_ipx.dest_addr; sipx.sipx_network = addr->net; memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN); sipx.sipx_port = addr->sock; - } - else - { - if(sk->protinfo.af_ipx.intrfc != NULL) - { + } else { + if (sk->protinfo.af_ipx.intrfc) { sipx.sipx_network=sk->protinfo.af_ipx.intrfc->if_netnum; #ifdef CONFIG_IPX_INTERN memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); @@ -2231,9 +2101,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, memcpy(sipx.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); #endif /* CONFIG_IPX_INTERN */ - } - else - { + } else { sipx.sipx_network = 0; memset(sipx.sipx_node, '\0', IPX_NODE_LEN); } @@ -2242,10 +2110,10 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, } sipx.sipx_family = AF_IPX; - sipx.sipx_type = sk->protinfo.af_ipx.type; + sipx.sipx_type = sk->protinfo.af_ipx.type; memcpy(uaddr,&sipx,sizeof(sipx)); - return (0); + return 0; } int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) @@ -2253,97 +2121,96 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) /* NULL here for pt means the packet was looped back */ ipx_interface *intrfc; struct ipxhdr *ipx; + struct ipx_cb *cb; + u16 ipx_pktsize; int ret; - - ipx = skb->nh.ipxh; - - /* Too small? */ - if(ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr)) - goto drop; - - /* Invalid header */ - if(ntohs(ipx->ipx_pktsize) > skb->len) - goto drop; /* Not ours */ if (skb->pkt_type == PACKET_OTHERHOST) goto drop; + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + goto out; + + ipx = skb->nh.ipxh; + ipx_pktsize = ntohs(ipx->ipx_pktsize); + + /* Too small or invalid header? */ + if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len) + goto drop; - if(ipx->ipx_checksum != IPX_NO_CHECKSUM) - { - if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize)) != ipx->ipx_checksum) - goto drop; - } + if (ipx->ipx_checksum != IPX_NO_CHECKSUM && + ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize)) + goto drop; + + cb = (struct ipx_cb *) skb->cb; + cb->ipx_tctrl = ipx->ipx_tctrl; + cb->ipx_dest_net = ipx->ipx_dest.net; + cb->ipx_source_net = ipx->ipx_source.net; /* Determine what local ipx endpoint this is */ intrfc = ipxitf_find_using_phys(dev, pt->type); - if(intrfc == NULL) - { - if(ipxcfg_auto_create_interfaces - && ntohl(ipx->ipx_dest.net) != 0L) - { + if (!intrfc) { + if (ipxcfg_auto_create_interfaces && + ntohl(cb->ipx_dest_net)) { intrfc = ipxitf_auto_create(dev, pt->type); ipxitf_hold(intrfc); } - if(intrfc == NULL) /* Not one of ours */ + if (!intrfc) /* Not one of ours */ goto drop; } ret = ipxitf_rcv(intrfc, skb); ipxitf_put(intrfc); return ret; -drop: - kfree_skb(skb); - return (0); +drop: kfree_skb(skb); +out: return 0; } static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) { struct sock *sk = sock->sk; - struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name; + struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name; struct sockaddr_ipx local_sipx; int retval; int flags = msg->msg_flags; /* Socket gets bound below anyway */ -/* if(sk->zapped) - return (-EIO); */ /* Socket not bound */ - if(flags & ~MSG_DONTWAIT) - return (-EINVAL); - - if(usipx) - { - if(sk->protinfo.af_ipx.port == 0) - { +/* if (sk->zapped) + return -EIO; */ /* Socket not bound */ + if (flags & ~MSG_DONTWAIT) + return -EINVAL; + + if (usipx) { + if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; int ret; uaddr.sipx_port = 0; uaddr.sipx_network = 0L; #ifdef CONFIG_IPX_INTERN - if(sk->protinfo.af_ipx.intrfc) - memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc - ->if_node,IPX_NODE_LEN); + if (sk->protinfo.af_ipx.intrfc) + memcpy(uaddr.sipx_node, + sk->protinfo.af_ipx.intrfc->if_node, + IPX_NODE_LEN); else return -ENETDOWN; /* Someone zonked the iface */ #endif ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if(ret != 0) - return (ret); + if (ret) + return ret; } - if(msg->msg_namelen < sizeof(*usipx)) - return (-EINVAL); - if(usipx->sipx_family != AF_IPX) - return (-EINVAL); - } - else - { - if(sk->state != TCP_ESTABLISHED) - return (-ENOTCONN); + if (msg->msg_namelen < sizeof(*usipx)) + return -EINVAL; + if (usipx->sipx_family != AF_IPX) + return -EINVAL; + } else { + if (sk->state != TCP_ESTABLISHED) + return -ENOTCONN; usipx=&local_sipx; usipx->sipx_family = AF_IPX; @@ -2353,11 +2220,12 @@ static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN); } - retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, flags&MSG_DONTWAIT); - if(retval < 0) - return (retval); + retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, + flags & MSG_DONTWAIT); + if (retval < 0) + return retval; - return (len); + return len; } @@ -2371,8 +2239,7 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, int copied, err; /* put the autobinding in */ - if(sk->protinfo.af_ipx.port == 0) - { + if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; int ret; @@ -2380,7 +2247,7 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if(sk->protinfo.af_ipx.intrfc) + if (sk->protinfo.af_ipx.intrfc) memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,IPX_NODE_LEN); else return -ENETDOWN; /* Someone zonked the iface */ @@ -2388,47 +2255,45 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if(ret != 0) - return (ret); + if (ret) + return ret; } - if(sk->zapped) - return (-ENOTCONN); + if (sk->zapped) + return -ENOTCONN; skb = skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); - if(!skb) + if (!skb) goto out; ipx = skb->nh.ipxh; copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); - if(copied > size) - { + if (copied > size) { copied=size; msg->msg_flags |= MSG_TRUNC; } err = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov, copied); - if(err) + if (err) goto out_free; sk->stamp = skb->stamp; msg->msg_namelen = sizeof(*sipx); - if(sipx) - { + if (sipx) { + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; sipx->sipx_family = AF_IPX; sipx->sipx_port = ipx->ipx_source.sock; memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN); - sipx->sipx_network = ipx->ipx_source.net; + sipx->sipx_network = cb->ipx_source_net; sipx->sipx_type = ipx->ipx_type; } err = copied; out_free: skb_free_datagram(sk, skb); -out: - return (err); +out: return err; } @@ -2437,40 +2302,39 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) long amount = 0; struct sock *sk = sock->sk; - switch(cmd) - { + switch (cmd) { case TIOCOUTQ: amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); - if(amount < 0) + if (amount < 0) amount = 0; - return (put_user(amount, (int *)arg)); + return put_user(amount, (int *)arg); case TIOCINQ: { - struct sk_buff *skb; + struct sk_buff *skb = skb_peek(&sk->receive_queue); /* These two are safe on a single CPU system as only user tasks fiddle here */ - if((skb = skb_peek(&sk->receive_queue)) != NULL) + if (skb) amount = skb->len - sizeof(struct ipxhdr); - return (put_user(amount, (int *)arg)); + return put_user(amount, (int *)arg); } case SIOCADDRT: case SIOCDELRT: - if(!capable(CAP_NET_ADMIN)) - return (-EPERM); - return (ipxrtr_ioctl(cmd,(void *)arg)); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + return ipxrtr_ioctl(cmd,(void *)arg); case SIOCSIFADDR: case SIOCAIPXITFCRT: case SIOCAIPXPRISLT: - if(!capable(CAP_NET_ADMIN)) - return (-EPERM); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; case SIOCGIFADDR: - return (ipxitf_ioctl(cmd,(void *)arg)); + return ipxitf_ioctl(cmd,(void *)arg); case SIOCIPXCFGDATA: - return (ipxcfg_get_config_data((void *)arg)); + return ipxcfg_get_config_data((void *)arg); case SIOCIPXNCPCONN: { @@ -2479,24 +2343,24 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) * handed to us in arg. */ if (!capable(CAP_NET_ADMIN)) - return(-EPERM); - return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, (const unsigned short *)(arg)); + return -EPERM; + return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, + (const unsigned short *)(arg)); } case SIOCGSTAMP: { int ret = -EINVAL; - if(sk) - { - if(sk->stamp.tv_sec == 0) - return (-ENOENT); + if (sk) { + if (!sk->stamp.tv_sec) + return -ENOENT; ret = -EFAULT; - if(!copy_to_user((void *)arg, &sk->stamp, + if (!copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval))) ret = 0; } - return (ret); + return ret; } case SIOCGIFDSTADDR: @@ -2505,14 +2369,14 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCSIFBRDADDR: case SIOCGIFNETMASK: case SIOCSIFNETMASK: - return (-EINVAL); + return -EINVAL; default: - return (dev_ioctl(cmd,(void *) arg)); + return dev_ioctl(cmd,(void *) arg); } /*NOT REACHED*/ - return (0); + return 0; } /* @@ -2521,19 +2385,19 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) int ipx_register_spx(struct proto_ops **p, struct net_proto_family *spx) { - if(spx_family_ops!=NULL) + if (spx_family_ops) return -EBUSY; cli(); MOD_INC_USE_COUNT; - *p=&ipx_dgram_ops; - spx_family_ops=spx; + *p = &ipx_dgram_ops; + spx_family_ops = spx; sti(); return 0; } int ipx_unregister_spx(void) { - spx_family_ops=NULL; + spx_family_ops = NULL; MOD_DEC_USE_COUNT; return 0; } @@ -2576,7 +2440,7 @@ static struct packet_type ipx_8023_packet_type = __constant_htons(ETH_P_802_3), NULL, /* All devices */ ipx_rcv, - NULL, + (void *) 1, /* yap, I understand shared skbs :-) */ NULL, }; @@ -2585,7 +2449,7 @@ static struct packet_type ipx_dix_packet_type = __constant_htons(ETH_P_IPX), NULL, /* All devices */ ipx_rcv, - NULL, + (void *) 1, /* yap, I understand shared skbs :-) */ NULL, }; @@ -2604,12 +2468,9 @@ extern void destroy_8023_client(struct datalink_proto *); static unsigned char ipx_8022_type = 0xE0; static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; - - - static int __init ipx_init(void) { - (void) sock_register(&ipx_family_ops); + sock_register(&ipx_family_ops); pEII_datalink = make_EII_client(); dev_add_pack(&ipx_dix_packet_type); @@ -2617,35 +2478,34 @@ static int __init ipx_init(void) p8023_datalink = make_8023_client(); dev_add_pack(&ipx_8023_packet_type); - if((p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv)) == NULL) + p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv); + if (!p8022_datalink) printk(KERN_CRIT "IPX: Unable to register with 802.2\n"); - if((pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv)) == NULL) + pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv); + if (!pSNAP_datalink) printk(KERN_CRIT "IPX: Unable to register with SNAP\n"); register_netdevice_notifier(&ipx_dev_notifier); - #ifdef CONFIG_PROC_FS proc_net_create("ipx", 0, ipx_get_info); proc_net_create("ipx_interface", 0, ipx_interface_get_info); proc_net_create("ipx_route", 0, ipx_rt_get_info); #endif - - printk(KERN_INFO "NET4: Linux IPX 0.42v4 for NET4.0\n"); + printk(KERN_INFO "NET4: Linux IPX 0.43 for NET4.0\n"); printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n"); printk(KERN_INFO "IPX Portions Copyright (c) 2000 Conectiva, Inc.\n"); return 0; } + module_init(ipx_init); /* Higher layers need this info to prep tx pkts */ int ipx_if_offset(unsigned long ipx_net_number) { - ipx_route *rt = NULL; - - rt = ipxrtr_lookup(ipx_net_number); + ipx_route *rt = ipxrtr_lookup(ipx_net_number); - return (rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH); + return rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH; } /* Export symbols for higher layers */ @@ -2683,24 +2543,22 @@ static void ipx_proto_finito(void) unregister_netdevice_notifier(&ipx_dev_notifier); unregister_snap_client(ipx_snap_id); - pSNAP_datalink = NULL; + pSNAP_datalink = NULL; unregister_8022_client(ipx_8022_type); - p8022_datalink = NULL; + p8022_datalink = NULL; dev_remove_pack(&ipx_8023_packet_type); destroy_8023_client(p8023_datalink); - p8023_datalink = NULL; + p8023_datalink = NULL; dev_remove_pack(&ipx_dix_packet_type); destroy_EII_client(pEII_datalink); - pEII_datalink = NULL; - - (void) sock_unregister(ipx_family_ops.family); + pEII_datalink = NULL; - return; + sock_unregister(ipx_family_ops.family); } + module_exit(ipx_proto_finito); #endif /* MODULE */ - #endif /* CONFIG_IPX || CONFIG_IPX_MODULE */ |