summaryrefslogtreecommitdiffstats
path: root/net/ipx/af_ipx.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2001-01-31 22:22:27 +0000
committerRalf Baechle <ralf@linux-mips.org>2001-01-31 22:22:27 +0000
commit825423e4c4f18289df2393951cfd2a7a31fc0464 (patch)
tree4ad80e981c3d9effa910d2247d118d254f9a5d09 /net/ipx/af_ipx.c
parentc4693dc4856ab907a5c02187a8d398861bebfc7e (diff)
Merge with Linux 2.4.1.
Diffstat (limited to 'net/ipx/af_ipx.c')
-rw-r--r--net/ipx/af_ipx.c1296
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 */