summaryrefslogtreecommitdiffstats
path: root/net
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
parentc4693dc4856ab907a5c02187a8d398861bebfc7e (diff)
Merge with Linux 2.4.1.
Diffstat (limited to 'net')
-rw-r--r--net/appletalk/aarp.c599
-rw-r--r--net/appletalk/ddp.c923
-rw-r--r--net/atm/lec.c10
-rw-r--r--net/atm/lec.h4
-rw-r--r--net/bridge/br_private.h6
-rw-r--r--net/core/netfilter.c5
-rw-r--r--net/decnet/Makefile2
-rw-r--r--net/decnet/TODO12
-rw-r--r--net/decnet/af_decnet.c567
-rw-r--r--net/decnet/dn_dev.c4
-rw-r--r--net/decnet/dn_fib.c6
-rw-r--r--net/decnet/dn_neigh.c168
-rw-r--r--net/decnet/dn_nsp_in.c174
-rw-r--r--net/decnet/dn_nsp_out.c304
-rw-r--r--net/decnet/dn_route.c190
-rw-r--r--net/decnet/dn_rules.c11
-rw-r--r--net/decnet/dn_table.c2
-rw-r--r--net/decnet/dn_timer.c8
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/netfilter/Config.in11
-rw-r--r--net/ipv4/netfilter/Makefile2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c21
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c14
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c24
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c6
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_input.c2
-rw-r--r--net/ipv6/netfilter/Makefile1
-rw-r--r--net/ipv6/netfilter/ip6_tables.c22
-rw-r--r--net/ipv6/netfilter/ip6t_MARK.c21
-rw-r--r--net/ipv6/netfilter/ip6t_mark.c6
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c189
-rw-r--r--net/ipx/af_ipx.c1296
-rw-r--r--net/irda/af_irda.c3
-rw-r--r--net/sched/cls_u32.c2
-rw-r--r--net/sched/sch_dsmark.c22
-rw-r--r--net/sched/sch_gred.c12
-rw-r--r--net/sunrpc/auth.c20
-rw-r--r--net/sunrpc/sunrpc_syms.c1
-rw-r--r--net/sysctl_net.c7
-rw-r--r--net/unix/Makefile2
-rw-r--r--net/unix/af_unix.c52
-rw-r--r--net/unix/sysctl_net_unix.c22
-rw-r--r--net/x25/Makefile2
-rw-r--r--net/x25/af_x25.c21
-rw-r--r--net/x25/x25_dev.c6
-rw-r--r--net/x25/x25_facilities.c6
-rw-r--r--net/x25/x25_in.c4
-rw-r--r--net/x25/x25_link.c12
-rw-r--r--net/x25/x25_out.c4
-rw-r--r--net/x25/x25_route.c12
-rw-r--r--net/x25/x25_subr.c18
-rw-r--r--net/x25/x25_timer.c42
54 files changed, 2376 insertions, 2517 deletions
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index c67e3fdd0..ce5fc6d0d 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -25,6 +25,7 @@
* Jaume Grau - flush caches on AARP_PROBE
* Rob Newberry - Added proxy AARP and AARP proc fs,
* moved probing from DDP module.
+ * Arnaldo C. Melo - don't mangle rx packets
*
*/
@@ -58,16 +59,12 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
-
int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
int sysctl_aarp_tick_time = AARP_TICK_TIME;
int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT;
int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
-/*
- * Lists of aarp entries
- */
-
+/* Lists of aarp entries */
struct aarp_entry {
/* These first two are only used for unresolved entries */
unsigned long last_sent; /* Last time we xmitted the aarp request */
@@ -81,22 +78,16 @@ struct aarp_entry {
struct aarp_entry *next; /* Next entry in chain */
};
-/*
- * Hashed list of resolved, unresolved and proxy entries
- */
-
+/* Hashed list of resolved, unresolved and proxy entries */
static struct aarp_entry *resolved[AARP_HASH_SIZE];
static struct aarp_entry *unresolved[AARP_HASH_SIZE];
static struct aarp_entry *proxies[AARP_HASH_SIZE];
-static int unresolved_count = 0;
+static int unresolved_count;
/* One lock protects it all. */
static spinlock_t aarp_lock = SPIN_LOCK_UNLOCKED;
-/*
- * Used to walk the list and purge/kick entries.
- */
-
+/* Used to walk the list and purge/kick entries. */
static struct timer_list aarp_timer;
/*
@@ -108,7 +99,7 @@ static void __aarp_expire(struct aarp_entry *a)
{
struct sk_buff *skb;
- while ((skb=skb_dequeue(&a->packet_queue)) != NULL)
+ while ((skb = skb_dequeue(&a->packet_queue)) != NULL)
kfree_skb(skb);
kfree(a);
@@ -125,33 +116,29 @@ static void __aarp_send_query(struct aarp_entry *a)
static char aarp_eth_multicast[ETH_ALEN] =
{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
struct net_device *dev = a->dev;
- int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length;
+ int len = dev->hard_header_len + sizeof(struct elapaarp) +
+ aarp_dl->header_length;
struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
- struct elapaarp *eah;
struct at_addr *sat = atalk_find_dev_addr(dev);
+ struct elapaarp *eah;
- if (skb == NULL)
+ if (!skb)
return;
- if (sat == NULL) {
+ if (!sat) {
kfree_skb(skb);
return;
}
- /*
- * Set up the buffer.
- */
-
+ /* Set up the buffer */
skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
- eah = (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp));
+ eah = (struct elapaarp *)skb_put(skb,
+ sizeof(struct elapaarp));
skb->protocol = htons(ETH_P_ATALK);
skb->nh.raw = skb->h.raw = (void *) eah;
skb->dev = dev;
- /*
- * Set up the ARP.
- */
-
+ /* Set up the ARP */
eah->hw_type = htons(AARP_HW_TYPE_ETHERNET);
eah->pa_type = htons(ETH_P_ATALK);
eah->hw_len = ETH_ALEN;
@@ -170,52 +157,37 @@ static void __aarp_send_query(struct aarp_entry *a)
eah->pa_dst_net = a->target_addr.s_net;
eah->pa_dst_node= a->target_addr.s_node;
- /*
- * Add ELAP headers and set target to the AARP multicast.
- */
-
+ /* Add ELAP headers and set target to the AARP multicast */
aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
- /*
- * Send it.
- */
-
+ /* Send it */
dev_queue_xmit(skb);
-
- /*
- * Update the sending count
- */
-
+ /* Update the sending count */
a->xmit_count++;
}
-/* This runs under aarp_lock and in softint context, so only
- * atomic memory allocations can be used.
- */
+/* This runs under aarp_lock and in softint context, so only atomic memory
+ * allocations can be used. */
static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
struct at_addr *them, unsigned char *sha)
{
- int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length;
+ int len = dev->hard_header_len + sizeof(struct elapaarp) +
+ aarp_dl->header_length;
struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
struct elapaarp *eah;
- if (skb == NULL)
+ if (!skb)
return;
- /*
- * Set up the buffer.
- */
-
+ /* Set up the buffer */
skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
- eah = (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp));
+ eah = (struct elapaarp *)skb_put(skb,
+ sizeof(struct elapaarp));
skb->protocol = htons(ETH_P_ATALK);
skb->nh.raw = skb->h.raw = (void *) eah;
skb->dev = dev;
- /*
- * Set up the ARP.
- */
-
+ /* Set up the ARP */
eah->hw_type = htons(AARP_HW_TYPE_ETHERNET);
eah->pa_type = htons(ETH_P_ATALK);
eah->hw_len = ETH_ALEN;
@@ -228,7 +200,7 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
eah->pa_src_net = us->s_net;
eah->pa_src_node= us->s_node;
- if (sha == NULL)
+ if (!sha)
memset(eah->hw_dst, '\0', ETH_ALEN);
else
memcpy(eah->hw_dst, sha, ETH_ALEN);
@@ -237,47 +209,38 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
eah->pa_dst_net = them->s_net;
eah->pa_dst_node= them->s_node;
- /*
- * Add ELAP headers and set target to the AARP multicast.
- */
-
+ /* Add ELAP headers and set target to the AARP multicast */
aarp_dl->datalink_header(aarp_dl, skb, sha);
-
- /*
- * Send it.
- */
+ /* Send it */
dev_queue_xmit(skb);
}
/*
- * Send probe frames. Called from aarp_probe_network and aarp_proxy_probe_network.
+ * Send probe frames. Called from aarp_probe_network and
+ * aarp_proxy_probe_network.
*/
void aarp_send_probe(struct net_device *dev, struct at_addr *us)
{
- int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length;
+ int len = dev->hard_header_len + sizeof(struct elapaarp) +
+ aarp_dl->header_length;
struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
- struct elapaarp *eah;
static char aarp_eth_multicast[ETH_ALEN] =
{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
+ struct elapaarp *eah;
- if (skb == NULL)
+ if (!skb)
return;
- /*
- * Set up the buffer.
- */
-
+ /* Set up the buffer */
skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
- eah = (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp));
+ eah = (struct elapaarp *)skb_put(skb,
+ sizeof(struct elapaarp));
skb->protocol = htons(ETH_P_ATALK);
skb->nh.raw = skb->h.raw = (void *) eah;
skb->dev = dev;
- /*
- * Set up the ARP.
- */
-
+ /* Set up the ARP */
eah->hw_type = htons(AARP_HW_TYPE_ETHERNET);
eah->pa_type = htons(ETH_P_ATALK);
eah->hw_len = ETH_ALEN;
@@ -296,15 +259,9 @@ void aarp_send_probe(struct net_device *dev, struct at_addr *us)
eah->pa_dst_net = us->s_net;
eah->pa_dst_node= us->s_node;
- /*
- * Add ELAP headers and set target to the AARP multicast.
- */
-
+ /* Add ELAP headers and set target to the AARP multicast */
aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
-
- /*
- * Send it.
- */
+ /* Send it */
dev_queue_xmit(skb);
}
@@ -318,16 +275,14 @@ static void __aarp_expire_timer(struct aarp_entry **n)
{
struct aarp_entry *t;
- while ((*n) != NULL) {
+ while (*n)
/* Expired ? */
- if(time_after(jiffies, (*n)->expires_at)) {
+ if (time_after(jiffies, (*n)->expires_at)) {
t = *n;
*n = (*n)->next;
__aarp_expire(t);
- } else {
+ } else
n = &((*n)->next);
- }
- }
}
/*
@@ -340,10 +295,8 @@ static void __aarp_kick(struct aarp_entry **n)
{
struct aarp_entry *t;
- while ((*n) != NULL) {
- /* Expired - if this will be the 11th transmit, we delete
- * instead.
- */
+ while (*n)
+ /* Expired: if this will be the 11th tx, we delete instead. */
if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) {
t = *n;
*n = (*n)->next;
@@ -352,7 +305,6 @@ static void __aarp_kick(struct aarp_entry **n)
__aarp_send_query(*n);
n = &((*n)->next);
}
- }
}
/*
@@ -366,21 +318,16 @@ static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev)
{
struct aarp_entry *t;
- while ((*n) != NULL) {
+ while (*n)
if ((*n)->dev == dev) {
t = *n;
*n = (*n)->next;
__aarp_expire(t);
- } else {
+ } else
n = &((*n)->next);
- }
- }
}
-/*
- * Handle the timer event
- */
-
+/* Handle the timer event */
static void aarp_expire_timeout(unsigned long unused)
{
int ct;
@@ -395,17 +342,14 @@ static void aarp_expire_timeout(unsigned long unused)
}
spin_unlock_bh(&aarp_lock);
-
mod_timer(&aarp_timer, jiffies +
- (unresolved_count ? sysctl_aarp_tick_time:
+ (unresolved_count ? sysctl_aarp_tick_time :
sysctl_aarp_expiry_time));
}
-/*
- * Network device notifier chain handler.
- */
-
-static int aarp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
+/* Network device notifier chain handler. */
+static int aarp_device_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
{
int ct;
@@ -432,11 +376,8 @@ static struct aarp_entry *aarp_alloc(void)
{
struct aarp_entry *a = kmalloc(sizeof(struct aarp_entry), GFP_ATOMIC);
- if (a == NULL)
- return NULL;
-
- skb_queue_head_init(&a->packet_queue);
-
+ if (a)
+ skb_queue_head_init(&a->packet_queue);
return a;
}
@@ -464,10 +405,8 @@ static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list,
/* Called from the DDP code, and thus must be exported. */
void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
{
+ int hash = sa->s_node % (AARP_HASH_SIZE - 1);
struct aarp_entry *a;
- int hash;
-
- hash = sa->s_node % (AARP_HASH_SIZE-1);
spin_lock_bh(&aarp_lock);
@@ -479,23 +418,15 @@ void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
}
/* This must run under aarp_lock. */
-static struct at_addr *__aarp_proxy_find(struct net_device *dev, struct at_addr *sa)
+static struct at_addr *__aarp_proxy_find(struct net_device *dev,
+ struct at_addr *sa)
{
- struct at_addr *retval;
- struct aarp_entry *a;
- int hash;
+ int hash = sa->s_node % (AARP_HASH_SIZE - 1);
+ struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa);
- hash = sa->s_node % (AARP_HASH_SIZE-1);
-
- retval = NULL;
- a = __aarp_find_entry(proxies[hash], dev, sa);
- if (a != NULL)
- retval = sa;
-
- return retval;
+ return a ? sa : NULL;
}
-
/*
* Probe a Phase 1 device or a device that requires its Net:Node to
* be set via an ioctl.
@@ -506,13 +437,13 @@ void aarp_send_probe_phase1(struct atalk_iface *iface)
struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
sa->sat_addr.s_node = iface->address.s_node;
- sa->sat_addr.s_net = ntohs(iface->address.s_net);
+ sa->sat_addr.s_net = ntohs(iface->address.s_net);
/* We pass the Net:Node to the drivers/cards by a Device ioctl. */
if (!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) {
(void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR);
- if ((iface->address.s_net != htons(sa->sat_addr.s_net)) ||
- (iface->address.s_node != sa->sat_addr.s_node))
+ if (iface->address.s_net != htons(sa->sat_addr.s_net) ||
+ iface->address.s_node != sa->sat_addr.s_node)
iface->status |= ATIF_PROBE_FAIL;
iface->address.s_net = htons(sa->sat_addr.s_net);
@@ -523,17 +454,16 @@ void aarp_send_probe_phase1(struct atalk_iface *iface)
void aarp_probe_network(struct atalk_iface *atif)
{
- if(atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) {
+ if (atif->dev->type == ARPHRD_LOCALTLK ||
+ atif->dev->type == ARPHRD_PPP)
aarp_send_probe_phase1(atif);
- } else {
+ else {
unsigned int count;
for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) {
aarp_send_probe(atif->dev, &atif->address);
- /*
- * Defer 1/10th
- */
+ /* Defer 1/10th */
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ/10);
@@ -545,9 +475,9 @@ void aarp_probe_network(struct atalk_iface *atif)
int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
{
- struct aarp_entry *entry;
+ int hash, retval = 1;
+ struct aarp_entry *entry;
unsigned int count;
- int hash, retval;
/*
* we don't currently support LocalTalk or PPP for proxy AARP;
@@ -564,7 +494,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
* we need this one to hang around even if it's in use
*/
entry = aarp_alloc();
- if (entry == NULL)
+ if (!entry)
return -ENOMEM;
entry->expires_at = -1;
@@ -582,56 +512,38 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) {
aarp_send_probe(atif->dev, sa);
- /*
- * Defer 1/10th
- */
+ /* Defer 1/10th */
current->state = TASK_INTERRUPTIBLE;
-
spin_unlock_bh(&aarp_lock);
-
schedule_timeout(HZ/10);
-
spin_lock_bh(&aarp_lock);
if (entry->status & ATIF_PROBE_FAIL)
break;
}
- retval = 1;
-
if (entry->status & ATIF_PROBE_FAIL) {
- /* free the entry */
- entry->expires_at = jiffies - 1;
-
- /* return network full */
- retval = -EADDRINUSE;
- } else {
- /* clear the probing flag */
+ entry->expires_at = jiffies - 1; /* free the entry */
+ retval = -EADDRINUSE; /* return network full */
+ } else /* clear the probing flag */
entry->status &= ~ATIF_PROBE;
- }
spin_unlock_bh(&aarp_lock);
-
return retval;
}
-
-/*
- * Send a DDP frame
- */
-int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr)
+/* Send a DDP frame */
+int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
+ struct at_addr *sa, void *hwaddr)
{
- static char ddp_eth_multicast[ETH_ALEN] = { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
+ static char ddp_eth_multicast[ETH_ALEN] =
+ { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
int hash;
struct aarp_entry *a;
skb->nh.raw = skb->data;
- /*
- * Check for LocalTalk first
- */
-
-
+ /* Check for LocalTalk first */
if (dev->type == ARPHRD_LOCALTLK) {
struct at_addr *at = atalk_find_dev_addr(dev);
struct ddpehdr *ddp = (struct ddpehdr *)skb->data;
@@ -644,8 +556,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa
* (zero matches anything)
*/
- if( ( ddp->deh_snet==0 || at->s_net==ddp->deh_snet) &&
- ( ddp->deh_dnet==0 || at->s_net==ddp->deh_dnet) ) {
+ if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) &&
+ (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) {
skb_pull(skb, sizeof(struct ddpehdr) - 4);
/*
@@ -665,104 +577,58 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa
skb->data[0] = sa->s_node;
skb->data[1] = at->s_node;
skb->data[2] = ft;
-
- if (skb->sk)
- skb->priority = skb->sk->priority;
skb->dev = dev;
- dev_queue_xmit(skb);
- return 1;
+ goto sendit;
}
- /*
- * On a PPP link we neither compress nor aarp.
- */
+ /* On a PPP link we neither compress nor aarp. */
if (dev->type == ARPHRD_PPP) {
skb->protocol = htons(ETH_P_PPPTALK);
- if (skb->sk)
- skb->priority = skb->sk->priority;
skb->dev = dev;
- dev_queue_xmit(skb);
- return 1;
+ goto sendit;
}
- /*
- * Non ELAP we cannot do.
- */
-
+ /* Non ELAP we cannot do. */
if (dev->type != ARPHRD_ETHER)
return -1;
skb->dev = dev;
skb->protocol = htons(ETH_P_ATALK);
-
hash = sa->s_node % (AARP_HASH_SIZE - 1);
- /*
- * Do we have a resolved entry ?
- */
-
+ /* Do we have a resolved entry? */
if (sa->s_node == ATADDR_BCAST) {
ddp_dl->datalink_header(ddp_dl, skb, ddp_eth_multicast);
-
- if (skb->sk)
- skb->priority = skb->sk->priority;
- dev_queue_xmit(skb);
- return 1;
+ goto sendit;
}
spin_lock_bh(&aarp_lock);
-
a = __aarp_find_entry(resolved[hash], dev, sa);
- if (a != NULL) {
- /*
- * Return 1 and fill in the address
- */
-
+ if (a) { /* Return 1 and fill in the address */
a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10);
ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr);
- if(skb->sk)
- skb->priority = skb->sk->priority;
- dev_queue_xmit(skb);
-
spin_unlock_bh(&aarp_lock);
- return 1;
+ goto sendit;
}
- /*
- * Do we have an unresolved entry: This is the less common path
- */
-
+ /* Do we have an unresolved entry: This is the less common path */
a = __aarp_find_entry(unresolved[hash], dev, sa);
- if (a != NULL) {
- /*
- * Queue onto the unresolved queue
- */
-
+ if (a) { /* Queue onto the unresolved queue */
skb_queue_tail(&a->packet_queue, skb);
-
spin_unlock_bh(&aarp_lock);
return 0;
}
- /*
- * Allocate a new entry
- */
-
+ /* Allocate a new entry */
a = aarp_alloc();
- if (a == NULL) {
- /*
- * Whoops slipped... good job it's an unreliable
- * protocol 8)
- */
+ if (!a) {
+ /* Whoops slipped... good job it's an unreliable protocol 8) */
spin_unlock_bh(&aarp_lock);
return -1;
}
- /*
- * Set up the queue
- */
-
+ /* Set up the queue */
skb_queue_tail(&a->packet_queue, skb);
a->expires_at = jiffies + sysctl_aarp_resolve_time;
a->dev = dev;
@@ -772,10 +638,7 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa
unresolved[hash] = a;
unresolved_count++;
- /*
- * Send an initial request for the address
- */
-
+ /* Send an initial request for the address */
__aarp_send_query(a);
/*
@@ -786,18 +649,16 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa
if (unresolved_count == 1)
mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
-
- /*
- * Now finally, it is safe to drop the lock.
- */
-
+ /* Now finally, it is safe to drop the lock. */
spin_unlock_bh(&aarp_lock);
- /*
- * Tell the ddp layer we have taken over for this frame.
- */
-
+ /* Tell the ddp layer we have taken over for this frame. */
return 0;
+
+sendit: if (skb->sk)
+ skb->priority = skb->sk->priority;
+ dev_queue_xmit(skb);
+ return 1;
}
/*
@@ -806,170 +667,112 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa
*
* Must run under aarp_lock.
*/
-static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash)
+static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a,
+ int hash)
{
struct sk_buff *skb;
- while (*list != NULL) {
+ while (*list)
if (*list == a) {
unresolved_count--;
-
*list = a->next;
- /*
- * Move into the resolved list
- */
-
+ /* Move into the resolved list */
a->next = resolved[hash];
resolved[hash] = a;
- /*
- * Kick frames off
- */
-
+ /* Kick frames off */
while ((skb = skb_dequeue(&a->packet_queue)) != NULL) {
- a->expires_at = jiffies + (sysctl_aarp_expiry_time*10);
+ a->expires_at = jiffies +
+ sysctl_aarp_expiry_time * 10;
ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr);
if (skb->sk)
skb->priority = skb->sk->priority;
dev_queue_xmit(skb);
}
- } else {
+ } else
list = &((*list)->next);
- }
- }
}
/*
* This is called by the SNAP driver whenever we see an AARP SNAP
* frame. We currently only support Ethernet.
*/
-static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt)
{
- struct elapaarp *ea=(struct elapaarp *)skb->h.raw;
+ struct elapaarp *ea = (struct elapaarp *)skb->h.raw;
+ int hash, ret = 0;
+ __u16 function;
struct aarp_entry *a;
struct at_addr sa, *ma, da;
- int hash;
struct atalk_iface *ifa;
- /*
- * We only do Ethernet SNAP AARP.
- */
-
- if (dev->type != ARPHRD_ETHER) {
- kfree_skb(skb);
- return 0;
- }
-
- /*
- * Frame size ok ?
- */
-
- if (!skb_pull(skb, sizeof(*ea))) {
- kfree_skb(skb);
- return 0;
- }
-
- ea->function = ntohs(ea->function);
+ /* We only do Ethernet SNAP AARP. */
+ if (dev->type != ARPHRD_ETHER)
+ goto out0;
- /*
- * Sanity check fields.
- */
+ /* Frame size ok? */
+ if (!skb_pull(skb, sizeof(*ea)))
+ goto out0;
- if (ea->function < AARP_REQUEST ||
- ea->function > AARP_PROBE ||
- ea->hw_len != ETH_ALEN ||
- ea->pa_len != AARP_PA_ALEN ||
- ea->pa_src_zero != 0 ||
- ea->pa_dst_zero != 0) {
- kfree_skb(skb);
- return 0;
- }
+ function = ntohs(ea->function);
- /*
- * Looks good.
- */
+ /* Sanity check fields. */
+ if (function < AARP_REQUEST || function > AARP_PROBE ||
+ ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN ||
+ ea->pa_src_zero || ea->pa_dst_zero)
+ goto out0;
+ /* Looks good. */
hash = ea->pa_src_node % (AARP_HASH_SIZE - 1);
- /*
- * Build an address.
- */
-
+ /* Build an address. */
sa.s_node = ea->pa_src_node;
sa.s_net = ea->pa_src_net;
- /*
- * Process the packet.
- * Check for replies of me.
- */
-
+ /* Process the packet. Check for replies of me. */
ifa = atalk_find_dev(dev);
- if (ifa == NULL) {
- kfree_skb(skb);
- return 1;
- }
-
- if (ifa->status & ATIF_PROBE) {
- if (ifa->address.s_node == ea->pa_dst_node &&
- ifa->address.s_net == ea->pa_dst_net) {
- /*
- * Fail the probe (in use)
- */
-
- ifa->status |= ATIF_PROBE_FAIL;
- kfree_skb(skb);
- return 1;
- }
+ if (!ifa)
+ goto out1;
+
+ if (ifa->status & ATIF_PROBE &&
+ ifa->address.s_node == ea->pa_dst_node &&
+ ifa->address.s_net == ea->pa_dst_net) {
+ ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */
+ goto out1;
}
- /*
- * Check for replies of proxy AARP entries
- */
-
+ /* Check for replies of proxy AARP entries */
da.s_node = ea->pa_dst_node;
da.s_net = ea->pa_dst_net;
spin_lock_bh(&aarp_lock);
-
a = __aarp_find_entry(proxies[hash], dev, &da);
- if (a != NULL) {
- if (a->status & ATIF_PROBE) {
- a->status |= ATIF_PROBE_FAIL;
-
- spin_unlock_bh(&aarp_lock);
-
- /*
- * we do not respond to probe or request packets for
- * this address while we are probing this address
- */
- kfree_skb(skb);
-
- return 1;
- }
+ if (a && a->status & ATIF_PROBE) {
+ a->status |= ATIF_PROBE_FAIL;
+ /*
+ * we do not respond to probe or request packets for
+ * this address while we are probing this address
+ */
+ goto unlock;
}
- switch (ea->function) {
+ switch (function) {
case AARP_REPLY:
- if (unresolved_count == 0) /* Speed up */
+ if (!unresolved_count) /* Speed up */
break;
- /*
- * Find the entry.
- */
-
- if ((a = __aarp_find_entry(unresolved[hash],dev,&sa)) == NULL ||
- (dev != a->dev))
+ /* Find the entry. */
+ a = __aarp_find_entry(unresolved[hash],dev,&sa);
+ if (!a || dev != a->dev)
break;
- /*
- * We can fill one in - this is good.
- */
-
+ /* We can fill one in - this is good. */
memcpy(a->hwaddr,ea->hw_src,ETH_ALEN);
__aarp_resolved(&unresolved[hash],a,hash);
- if (unresolved_count == 0)
+ if (!unresolved_count)
mod_timer(&aarp_timer,
jiffies + sysctl_aarp_expiry_time);
break;
@@ -977,49 +780,45 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t
case AARP_REQUEST:
case AARP_PROBE:
/*
- * If it is my address set ma to my address and reply. We can treat probe and
- * request the same. Probe simply means we shouldn't cache the querying host,
- * as in a probe they are proposing an address not using one.
+ * If it is my address set ma to my address and
+ * reply. We can treat probe and request the
+ * same. Probe simply means we shouldn't cache
+ * the querying host, as in a probe they are
+ * proposing an address not using one.
*
- * Support for proxy-AARP added. We check if the address is one
- * of our proxies before we toss the packet out.
+ * Support for proxy-AARP added. We check if the
+ * address is one of our proxies before we toss
+ * the packet out.
*/
sa.s_node = ea->pa_dst_node;
sa.s_net = ea->pa_dst_net;
- /*
- * See if we have a matching proxy.
- */
+ /* See if we have a matching proxy. */
ma = __aarp_proxy_find(dev, &sa);
- if (!ma) {
+ if (!ma)
ma = &ifa->address;
- } else {
- /*
- * We need to make a copy of the entry.
- */
+ else { /* We need to make a copy of the entry. */
da.s_node = sa.s_node;
da.s_net = da.s_net;
ma = &da;
}
- if (ea->function == AARP_PROBE) {
+ if (function == AARP_PROBE) {
/* A probe implies someone trying to get an
* address. So as a precaution flush any
- * entries we have for this address.
- */
+ * entries we have for this address. */
struct aarp_entry *a = __aarp_find_entry(
- resolved[sa.s_node%(AARP_HASH_SIZE-1)],
- skb->dev,
- &sa);
+ resolved[sa.s_node%(AARP_HASH_SIZE-1)],
+ skb->dev, &sa);
/* Make it expire next tick - that avoids us
- * getting into a probe/flush/learn/probe/flush/learn
- * cycle during probing of a slow to respond host addr.
- */
- if (a != NULL)
- {
+ * getting into a probe/flush/learn/probe/
+ * flush/learn cycle during probing of a slow
+ * to respond host addr. */
+ if (a) {
a->expires_at = jiffies - 1;
- mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
+ mod_timer(&aarp_timer, jiffies +
+ sysctl_aarp_tick_time);
}
}
@@ -1032,18 +831,16 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t
sa.s_node = ea->pa_src_node;
sa.s_net = ea->pa_src_net;
- /*
- * aarp_my_address has found the address to use for us.
- */
-
+ /* aarp_my_address has found the address to use for us.
+ */
aarp_send_reply(dev, ma, &sa, ea->hw_src);
break;
- };
-
- spin_unlock_bh(&aarp_lock);
+ }
- kfree_skb(skb);
- return 1;
+unlock: spin_unlock_bh(&aarp_lock);
+out1: ret = 1;
+out0: kfree_skb(skb);
+ return ret;
}
static struct notifier_block aarp_notifier = {
@@ -1054,10 +851,10 @@ static struct notifier_block aarp_notifier = {
static char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 };
-
void __init aarp_proto_init(void)
{
- if ((aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv)) == NULL)
+ aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv);
+ if (!aarp_dl)
printk(KERN_CRIT "Unable to register AARP with SNAP.\n");
init_timer(&aarp_timer);
aarp_timer.function = aarp_expire_timeout;
@@ -1067,9 +864,7 @@ void __init aarp_proto_init(void)
register_netdevice_notifier(&aarp_notifier);
}
-/*
- * Remove the AARP entries associated with a device.
- */
+/* Remove the AARP entries associated with a device. */
void aarp_device_down(struct net_device *dev)
{
int ct;
@@ -1085,14 +880,12 @@ void aarp_device_down(struct net_device *dev)
spin_unlock_bh(&aarp_lock);
}
-/*
- * Called from proc fs
- */
+/* Called from proc fs */
static int aarp_get_info(char *buffer, char **start, off_t offset, int length)
{
/* we should dump all our AARP entries */
- struct aarp_entry *entry;
- int len, ct;
+ struct aarp_entry *entry;
+ int len, ct;
len = sprintf(buffer,
"%-10.10s ""%-10.10s""%-18.18s""%12.12s""%12.12s"" xmit_count status\n",
@@ -1171,25 +964,19 @@ static int aarp_get_info(char *buffer, char **start, off_t offset, int length)
}
spin_unlock_bh(&aarp_lock);
-
return len;
}
#ifdef MODULE
-/*
- * General module cleanup. Called from cleanup_module() in ddp.c.
- */
+/* General module cleanup. Called from cleanup_module() in ddp.c. */
void aarp_cleanup_module(void)
{
del_timer(&aarp_timer);
unregister_netdevice_notifier(&aarp_notifier);
unregister_snap_client(aarp_snap_id);
}
-
#endif /* MODULE */
-
#ifdef CONFIG_PROC_FS
-
void aarp_register_proc_fs(void)
{
proc_net_create("aarp", 0, aarp_get_info);
@@ -1199,7 +986,5 @@ void aarp_unregister_proc_fs(void)
{
proc_net_remove("aarp");
}
-
#endif
-
#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index e7784dabd..0e514faae 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -29,15 +29,17 @@
* driver file. (ipddp.c & ipddp.h)
* Jay Schulist : Made work as module with
* AppleTalk drivers, cleaned it.
- * Rob Newberry : Added proxy AARP and AARP proc fs,
- * moved probing to AARP module.
+ * Rob Newberry : Added proxy AARP and AARP
+ * procfs, moved probing to AARP
+ * module.
* Adrian Sun/
* Michael Zuelsdorff : fix for net.0 packets. don't
* allow illegal ether/tokentalk
* port assignment. we lose a
* valid localtalk port as a
* result.
- *
+ * Arnaldo C. de Melo : Cleanup, in preparation for
+ * shared skb support 8)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -84,19 +86,19 @@
#include <linux/stat.h>
#include <linux/init.h>
-
#ifdef CONFIG_PROC_FS
extern void aarp_register_proc_fs(void);
extern void aarp_unregister_proc_fs(void);
#endif
+extern void aarp_cleanup_module(void);
+
extern void aarp_probe_network(struct atalk_iface *atif);
-extern int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa);
+extern int aarp_proxy_probe_network(struct atalk_iface *atif,
+ struct at_addr *sa);
extern void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa);
-
#undef APPLETALK_DEBUG
-
#ifdef APPLETALK_DEBUG
#define DPRINT(x) print(x)
#else
@@ -119,13 +121,14 @@ static struct proto_ops atalk_dgram_ops;
* *
\**************************************************************************/
-static struct sock *atalk_sockets = NULL;
+static struct sock *atalk_sockets;
static spinlock_t atalk_sockets_lock = SPIN_LOCK_UNLOCKED;
extern inline void atalk_insert_socket(struct sock *sk)
{
spin_lock_bh(&atalk_sockets_lock);
- if ((sk->next = atalk_sockets) != NULL)
+ sk->next = atalk_sockets;
+ if (sk->next)
atalk_sockets->pprev = &sk->next;
atalk_sockets = sk;
sk->pprev = &atalk_sockets;
@@ -135,7 +138,7 @@ extern inline void atalk_insert_socket(struct sock *sk)
extern inline void atalk_remove_socket(struct sock *sk)
{
spin_lock_bh(&atalk_sockets_lock);
- if (sk->pprev != NULL) {
+ if (sk->pprev) {
if (sk->next)
sk->next->pprev = sk->pprev;
*sk->pprev = sk->next;
@@ -144,12 +147,13 @@ extern inline void atalk_remove_socket(struct sock *sk)
spin_unlock_bh(&atalk_sockets_lock);
}
-static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_iface *atif)
+static struct sock *atalk_search_socket(struct sockaddr_at *to,
+ struct atalk_iface *atif)
{
struct sock *s;
spin_lock_bh(&atalk_sockets_lock);
- for (s = atalk_sockets; s != NULL; s = s->next) {
+ for (s = atalk_sockets; s; s = s->next) {
if (to->sat_port != s->protinfo.af_at.src_port)
continue;
@@ -174,7 +178,6 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_ifa
}
}
spin_unlock_bh(&atalk_sockets_lock);
-
return s;
}
@@ -185,29 +188,28 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_ifa
*
* This entire operation must execute atomically.
*/
-static struct sock *atalk_find_or_insert_socket(struct sock *sk, struct sockaddr_at *sat)
+static struct sock *atalk_find_or_insert_socket(struct sock *sk,
+ struct sockaddr_at *sat)
{
struct sock *s;
spin_lock_bh(&atalk_sockets_lock);
-
- for (s = atalk_sockets; s != NULL; s = s->next) {
+ for (s = atalk_sockets; s; s = s->next)
if (s->protinfo.af_at.src_net == sat->sat_addr.s_net &&
s->protinfo.af_at.src_node == sat->sat_addr.s_node &&
s->protinfo.af_at.src_port == sat->sat_port)
break;
- }
if (!s) {
/* Wheee, it's free, assign and insert. */
- if ((sk->next = atalk_sockets) != NULL)
+ sk->next = atalk_sockets;
+ if (sk->next)
atalk_sockets->pprev = &sk->next;
atalk_sockets = sk;
sk->pprev = &atalk_sockets;
}
spin_unlock_bh(&atalk_sockets_lock);
-
return s;
}
@@ -215,9 +217,8 @@ static void atalk_destroy_timer(unsigned long data)
{
struct sock *sk = (struct sock *) data;
- if (atomic_read(&sk->wmem_alloc) == 0 &&
- atomic_read(&sk->rmem_alloc) == 0 &&
- sk->dead) {
+ if (!atomic_read(&sk->wmem_alloc) &&
+ !atomic_read(&sk->rmem_alloc) && sk->dead) {
sock_put(sk);
MOD_DEC_USE_COUNT;
} else {
@@ -228,16 +229,11 @@ static void atalk_destroy_timer(unsigned long data)
extern inline void atalk_destroy_socket(struct sock *sk)
{
- struct sk_buff *skb;
-
atalk_remove_socket(sk);
+ skb_queue_purge(&sk->receive_queue);
- while ((skb = skb_dequeue(&sk->receive_queue)) != NULL)
- kfree_skb(skb);
-
- if (atomic_read(&sk->wmem_alloc) == 0 &&
- atomic_read(&sk->rmem_alloc) == 0 &&
- sk->dead) {
+ if (!atomic_read(&sk->wmem_alloc) &&
+ !atomic_read(&sk->rmem_alloc) && sk->dead) {
sock_put(sk);
MOD_DEC_USE_COUNT;
} else {
@@ -249,37 +245,31 @@ extern inline void atalk_destroy_socket(struct sock *sk)
}
}
-/*
- * Called from proc fs
- */
+/* Called from proc fs */
static int atalk_get_info(char *buffer, char **start, off_t offset, int length)
{
- struct sock *s;
- int len = 0;
off_t pos = 0;
off_t begin = 0;
-
- /*
- * Output the AppleTalk data for the /proc filesystem.
- */
-
- len += sprintf(buffer,"Type local_addr remote_addr tx_queue rx_queue st uid\n");
+ int len = sprintf(buffer, "Type local_addr remote_addr tx_queue "
+ "rx_queue st uid\n");
+ struct sock *s;
+ /* Output the AppleTalk data for the /proc filesystem */
spin_lock_bh(&atalk_sockets_lock);
- for (s = atalk_sockets; s != NULL; s = s->next) {
- len += sprintf(buffer+len,"%02X ", s->type);
- len += sprintf(buffer+len,"%04X:%02X:%02X ",
+ for (s = atalk_sockets; s; s = s->next) {
+ len += sprintf(buffer + len,"%02X ", s->type);
+ len += sprintf(buffer + len,"%04X:%02X:%02X ",
ntohs(s->protinfo.af_at.src_net),
s->protinfo.af_at.src_node,
s->protinfo.af_at.src_port);
- len += sprintf(buffer+len,"%04X:%02X:%02X ",
+ len += sprintf(buffer + len,"%04X:%02X:%02X ",
ntohs(s->protinfo.af_at.dest_net),
s->protinfo.af_at.dest_node,
s->protinfo.af_at.dest_port);
- len += sprintf(buffer+len,"%08X:%08X ",
+ len += sprintf(buffer + len,"%08X:%08X ",
atomic_read(&s->wmem_alloc),
atomic_read(&s->rmem_alloc));
- len += sprintf(buffer+len,"%02X %d\n", s->state,
+ len += sprintf(buffer + len,"%02X %d\n", s->state,
SOCK_INODE(s->socket)->i_uid);
/* Are we still dumping unwanted data then discard the record */
@@ -295,8 +285,8 @@ static int atalk_get_info(char *buffer, char **start, off_t offset, int length)
spin_unlock_bh(&atalk_sockets_lock);
/* 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 */
+ *start = buffer + offset - begin; /* Start of wanted data */
+ len -= offset - begin; /* Remove unwanted header data from length */
if (len > length)
len = length; /* Remove unwanted tail data from length */
@@ -310,18 +300,16 @@ static int atalk_get_info(char *buffer, char **start, off_t offset, int length)
\**************************************************************************/
/* Anti-deadlock ordering is router_lock --> iface_lock -DaveM */
-static struct atalk_route *atalk_router_list = NULL;
+static struct atalk_route *atalk_router_list;
static rwlock_t atalk_router_lock = RW_LOCK_UNLOCKED;
-static struct atalk_iface *atalk_iface_list = NULL;
+static struct atalk_iface *atalk_iface_list;
static spinlock_t atalk_iface_lock = SPIN_LOCK_UNLOCKED;
-static struct atalk_route atrtr_default; /* For probing devices or in a routerless network */
-
-/*
- * AppleTalk interface control
- */
+/* For probing devices or in a routerless network */
+static struct atalk_route atrtr_default;
+/* AppleTalk interface control */
/*
* Drop a device. Doesn't drop any of its routes - that is the caller's
* problem. Called when we down the interface or delete the address.
@@ -344,12 +332,12 @@ static void atif_drop_device(struct net_device *dev)
spin_unlock_bh(&atalk_iface_lock);
}
-static struct atalk_iface *atif_add_device(struct net_device *dev, struct at_addr *sa)
+static struct atalk_iface *atif_add_device(struct net_device *dev,
+ struct at_addr *sa)
{
- struct atalk_iface *iface = (struct atalk_iface *)
- kmalloc(sizeof(*iface), GFP_KERNEL);
+ struct atalk_iface *iface = kmalloc(sizeof(*iface), GFP_KERNEL);
- if (iface == NULL)
+ if (!iface)
return NULL;
iface->dev = dev;
@@ -363,51 +351,37 @@ static struct atalk_iface *atif_add_device(struct net_device *dev, struct at_add
spin_unlock_bh(&atalk_iface_lock);
MOD_INC_USE_COUNT;
-
return iface;
}
-
-/*
- * Perform phase 2 AARP probing on our tentative address.
- */
+/* Perform phase 2 AARP probing on our tentative address */
static int atif_probe_device(struct atalk_iface *atif)
{
- int netrange = ntohs(atif->nets.nr_lastnet) - ntohs(atif->nets.nr_firstnet) + 1;
+ int netrange = ntohs(atif->nets.nr_lastnet) -
+ ntohs(atif->nets.nr_firstnet) + 1;
int probe_net = ntohs(atif->address.s_net);
int probe_node = atif->address.s_node;
int netct, nodect;
- /*
- * Offset the network we start probing with.
- */
-
+ /* Offset the network we start probing with */
if (probe_net == ATADDR_ANYNET) {
- if (!netrange)
- probe_net = ntohs(atif->nets.nr_firstnet);
- else
- probe_net = ntohs(atif->nets.nr_firstnet) + (jiffies % netrange);
+ probe_net = ntohs(atif->nets.nr_firstnet);
+ if (netrange)
+ probe_net += jiffies % netrange;
}
-
if (probe_node == ATADDR_ANYNODE)
probe_node = jiffies & 0xFF;
- /*
- * Scan the networks.
- */
+ /* Scan the networks */
atif->status |= ATIF_PROBE;
for (netct = 0; netct <= netrange; netct++) {
- /*
- * Sweep the available nodes from a given start.
- */
-
+ /* Sweep the available nodes from a given start */
atif->address.s_net = htons(probe_net);
for (nodect = 0; nodect < 256; nodect++) {
atif->address.s_node = ((nodect+probe_node) & 0xFF);
- if (atif->address.s_node > 0 && atif->address.s_node < 254) {
- /*
- * Probe a proposed address.
- */
+ if (atif->address.s_node > 0 &&
+ atif->address.s_node < 254) {
+ /* Probe a proposed address */
aarp_probe_network(atif);
if (!(atif->status & ATIF_PROBE_FAIL)) {
@@ -427,58 +401,45 @@ static int atif_probe_device(struct atalk_iface *atif)
}
-/*
- * Perform AARP probing for a proxy address
- */
-static int atif_proxy_probe_device(struct atalk_iface *atif, struct at_addr* proxy_addr)
+/* Perform AARP probing for a proxy address */
+static int atif_proxy_probe_device(struct atalk_iface *atif,
+ struct at_addr* proxy_addr)
{
- int netrange = ntohs(atif->nets.nr_lastnet) - ntohs(atif->nets.nr_firstnet) + 1;
- int probe_net = ntohs(atif->address.s_net); /* we probe the interface's network */
+ int netrange = ntohs(atif->nets.nr_lastnet) -
+ ntohs(atif->nets.nr_firstnet) + 1;
+ /* we probe the interface's network */
+ int probe_net = ntohs(atif->address.s_net);
int probe_node = ATADDR_ANYNODE; /* we'll take anything */
int netct, nodect;
- /*
- * Offset the network we start probing with.
- */
-
+ /* Offset the network we start probing with */
if (probe_net == ATADDR_ANYNET) {
- if (!netrange)
- probe_net = ntohs(atif->nets.nr_firstnet);
- else
- probe_net = ntohs(atif->nets.nr_firstnet) + (jiffies % netrange);
+ probe_net = ntohs(atif->nets.nr_firstnet);
+ if (netrange)
+ probe_net += jiffies % netrange;
}
if (probe_node == ATADDR_ANYNODE)
probe_node = jiffies & 0xFF;
- /*
- * Scan the networks.
- */
-
+ /* Scan the networks */
for (netct = 0; netct <= netrange; netct++) {
- /*
- * Sweep the available nodes from a given start.
- */
-
+ /* Sweep the available nodes from a given start */
proxy_addr->s_net = htons(probe_net);
for (nodect = 0; nodect < 256; nodect++) {
proxy_addr->s_node = ((nodect + probe_node) & 0xFF);
- if ((proxy_addr->s_node > 0) && (proxy_addr->s_node < 254)) {
- /*
- * Tell AARP to probe a proposed address.
- */
- int probe_result = aarp_proxy_probe_network(atif,
- proxy_addr);
-
- if (probe_result == 0)
- return 0;
-
- if (probe_result != -EADDRINUSE)
- return probe_result;
+ if (proxy_addr->s_node > 0 &&
+ proxy_addr->s_node < 254) {
+ /* Tell AARP to probe a proposed address */
+ int ret = aarp_proxy_probe_network(atif,
+ proxy_addr);
+
+ if (ret != -EADDRINUSE)
+ return ret;
}
}
probe_net++;
- if(probe_net > ntohs(atif->nets.nr_lastnet))
+ if (probe_net > ntohs(atif->nets.nr_lastnet))
probe_net = ntohs(atif->nets.nr_firstnet);
}
@@ -489,25 +450,21 @@ static int atif_proxy_probe_device(struct atalk_iface *atif, struct at_addr* pro
struct at_addr *atalk_find_dev_addr(struct net_device *dev)
{
struct atalk_iface *iface = dev->atalk_ptr;
-
- if(iface)
- return &iface->address;
-
- return NULL;
+ return iface ? &iface->address : NULL;
}
static struct at_addr *atalk_find_primary(void)
{
+ struct atalk_iface *fiface = NULL;
struct at_addr *retval;
struct atalk_iface *iface;
- struct atalk_iface *fiface = NULL;
/*
* Return a point-to-point interface only if
* there is no non-ptp interface available.
*/
spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface != NULL; iface = iface->next) {
+ for (iface = atalk_iface_list; iface; iface = iface->next) {
if (!fiface && !(iface->dev->flags & IFF_LOOPBACK))
fiface = iface;
if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
@@ -516,16 +473,13 @@ static struct at_addr *atalk_find_primary(void)
}
}
- if (fiface) {
+ if (fiface)
retval = &fiface->address;
- } else if (atalk_iface_list != NULL) {
+ else if (atalk_iface_list)
retval = &atalk_iface_list->address;
- } else {
+ else
retval = NULL;
- }
-out:
- spin_unlock_bh(&atalk_iface_lock);
-
+out: spin_unlock_bh(&atalk_iface_lock);
return retval;
}
@@ -535,9 +489,9 @@ out:
*/
static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
{
- struct atalk_iface *iface=dev->atalk_ptr;
+ struct atalk_iface *iface = dev->atalk_ptr;
- if (iface==NULL || (iface->status & ATIF_PROBE))
+ if (!iface || iface->status & ATIF_PROBE)
return NULL;
if (node == ATADDR_BCAST ||
@@ -548,15 +502,13 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
return NULL;
}
-/*
- * Find a match for a specific network:node pair
- */
+/* Find a match for a specific network:node pair */
static struct atalk_iface *atalk_find_interface(int net, int node)
{
struct atalk_iface *iface;
spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface != NULL; iface = iface->next) {
+ for (iface = atalk_iface_list; iface; iface = iface->next) {
if ((node == ATADDR_BCAST ||
node == ATADDR_ANYNODE ||
iface->address.s_node == node) &&
@@ -565,13 +517,12 @@ static struct atalk_iface *atalk_find_interface(int net, int node)
break;
/* XXXX.0 -- net.0 returns the iface associated with net */
- if ((node == ATADDR_ANYNODE) && (net != ATADDR_ANYNET) &&
- (ntohs(iface->nets.nr_firstnet) <= ntohs(net)) &&
- (ntohs(net) <= ntohs(iface->nets.nr_lastnet)))
+ if (node == ATADDR_ANYNODE && net != ATADDR_ANYNET &&
+ ntohs(iface->nets.nr_firstnet) <= ntohs(net) &&
+ ntohs(net) <= ntohs(iface->nets.nr_lastnet))
break;
}
spin_unlock_bh(&atalk_iface_lock);
-
return iface;
}
@@ -588,11 +539,11 @@ static struct atalk_route *atrtr_find(struct at_addr *target)
* host route, because some host routes might overlap
* network routes
*/
- struct atalk_route *r;
struct atalk_route *net_route = NULL;
+ struct atalk_route *r;
read_lock_bh(&atalk_router_lock);
- for (r = atalk_router_list; r != NULL; r = r->next) {
+ for (r = atalk_router_list; r; r = r->next) {
if (!(r->flags & RTF_UP))
continue;
@@ -604,13 +555,12 @@ static struct atalk_route *atrtr_find(struct at_addr *target)
*/
if (r->target.s_node == target->s_node)
goto out;
- } else {
+ } else
/*
* this route will work if there isn't a
* direct host route, so cache it
*/
net_route = r;
- }
}
}
@@ -618,19 +568,13 @@ static struct atalk_route *atrtr_find(struct at_addr *target)
* if we found a network route but not a direct host
* route, then return it
*/
- if (net_route != NULL) {
+ if (net_route)
r = net_route;
- } else if (atrtr_default.dev) {
+ else if (atrtr_default.dev)
r = &atrtr_default;
- } else {
- /*
- * No route can be found.
- */
+ else /* No route can be found */
r = NULL;
- }
-
-out:
- read_unlock_bh(&atalk_router_lock);
+out: read_unlock_bh(&atalk_router_lock);
return r;
}
@@ -642,16 +586,10 @@ out:
struct net_device *atrtr_get_dev(struct at_addr *sa)
{
struct atalk_route *atr = atrtr_find(sa);
-
- if (atr == NULL)
- return NULL;
- else
- return atr->dev;
+ return atr ? atr->dev : NULL;
}
-/*
- * Set up a default router.
- */
+/* Set up a default router */
static void atrtr_set_default(struct net_device *dev)
{
atrtr_default.dev = dev;
@@ -678,20 +616,16 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
* operations.
*/
- /*
- * Validate the request
- */
+ /* Validate the request */
if (ta->sat_family != AF_APPLETALK)
return -EINVAL;
- if (devhint == NULL && ga->sat_family != AF_APPLETALK)
+ if (!devhint && ga->sat_family != AF_APPLETALK)
return -EINVAL;
- /*
- * Now walk the routing table and make our decisions.
- */
+ /* Now walk the routing table and make our decisions */
write_lock_bh(&atalk_router_lock);
- for (rt = atalk_router_list; rt != NULL; rt = rt->next) {
+ for (rt = atalk_router_list; rt; rt = rt->next) {
if (r->rt_flags != rt->flags)
continue;
@@ -703,65 +637,59 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
}
}
- if(devhint == NULL) {
+ if (!devhint) {
riface = NULL;
spin_lock_bh(&atalk_iface_lock);
for (iface = atalk_iface_list; iface; iface = iface->next) {
- if (riface == NULL &&
- ntohs(ga->sat_addr.s_net) >= ntohs(iface->nets.nr_firstnet) &&
- ntohs(ga->sat_addr.s_net) <= ntohs(iface->nets.nr_lastnet))
+ if (!riface &&
+ ntohs(ga->sat_addr.s_net) >=
+ ntohs(iface->nets.nr_firstnet) &&
+ ntohs(ga->sat_addr.s_net) <=
+ ntohs(iface->nets.nr_lastnet))
riface = iface;
- if (ga->sat_addr.s_net == iface->address.s_net &&
+ if (ga->sat_addr.s_net == iface->address.s_net &&
ga->sat_addr.s_node == iface->address.s_node)
riface = iface;
}
spin_unlock_bh(&atalk_iface_lock);
retval = -ENETUNREACH;
- if (riface == NULL)
+ if (!riface)
goto out;
devhint = riface->dev;
}
- if (rt == NULL) {
- rt = (struct atalk_route *)
- kmalloc(sizeof(struct atalk_route), GFP_ATOMIC);
+ if (!rt) {
+ rt = kmalloc(sizeof(struct atalk_route), GFP_ATOMIC);
retval = -ENOBUFS;
- if (rt == NULL)
+ if (!rt)
goto out;
rt->next = atalk_router_list;
atalk_router_list = rt;
}
- /*
- * Fill in the routing entry.
- */
+ /* Fill in the routing entry */
rt->target = ta->sat_addr;
rt->dev = devhint;
rt->flags = r->rt_flags;
rt->gateway = ga->sat_addr;
retval = 0;
-
-out:
- write_unlock_bh(&atalk_router_lock);
-
+out: write_unlock_bh(&atalk_router_lock);
return retval;
}
-/*
- * Delete a route. Find it and discard it.
- */
+/* Delete a route. Find it and discard it */
static int atrtr_delete(struct at_addr * addr)
{
struct atalk_route **r = &atalk_router_list;
- struct atalk_route *tmp;
int retval = 0;
+ struct atalk_route *tmp;
write_lock_bh(&atalk_router_lock);
while ((tmp = *r) != NULL) {
@@ -775,8 +703,7 @@ static int atrtr_delete(struct at_addr * addr)
r = &tmp->next;
}
retval = -ENOENT;
-out:
- write_unlock_bh(&atalk_router_lock);
+out: write_unlock_bh(&atalk_router_lock);
return retval;
}
@@ -794,9 +721,8 @@ void atrtr_device_down(struct net_device *dev)
if (tmp->dev == dev) {
*r = tmp->next;
kfree(tmp);
- } else {
+ } else
r = &tmp->next;
- }
}
write_unlock_bh(&atalk_router_lock);
@@ -804,9 +730,7 @@ void atrtr_device_down(struct net_device *dev)
atrtr_set_default(NULL);
}
-/*
- * Actually down the interface.
- */
+/* Actually down the interface */
static inline void atalk_dev_down(struct net_device *dev)
{
atrtr_device_down(dev); /* Remove all routes for the device */
@@ -818,27 +742,22 @@ static inline void atalk_dev_down(struct net_device *dev)
* A device event has occurred. Watch for devices going down and
* delete our use of them (iface and route).
*/
-static int ddp_device_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int ddp_device_event(struct notifier_block *this, unsigned long event,
+ void *ptr)
{
- if (event == NETDEV_DOWN) {
+ if (event == NETDEV_DOWN)
/* Discard any use of this */
atalk_dev_down((struct net_device *) ptr);
- }
return NOTIFY_DONE;
}
-/*
- * ioctl calls. Shouldn't even need touching.
- */
-
-/*
- * Device configuration ioctl calls.
- */
+/* ioctl calls. Shouldn't even need touching */
+/* Device configuration ioctl calls */
int atif_ioctl(int cmd, void *arg)
{
- struct ifreq atreq;
static char aarp_mcast[6] = {0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF};
+ struct ifreq atreq;
struct netrange *nr;
struct sockaddr_at *sa;
struct net_device *dev;
@@ -846,12 +765,13 @@ int atif_ioctl(int cmd, void *arg)
int ct;
int limit;
struct rtentry rtdef;
- int add_route;
+ int add_route;
if (copy_from_user(&atreq, arg, sizeof(atreq)))
return -EFAULT;
- if ((dev = __dev_get_by_name(atreq.ifr_name)) == NULL)
+ dev = __dev_get_by_name(atreq.ifr_name);
+ if (!dev)
return -ENODEV;
sa = (struct sockaddr_at*) &atreq.ifr_addr;
@@ -870,16 +790,19 @@ int atif_ioctl(int cmd, void *arg)
return -EPROTONOSUPPORT;
nr = (struct netrange *) &sa->sat_zero[0];
-
add_route = 1;
/*
- * if this is a point-to-point iface, and we already have an
- * iface for this AppleTalk address, then we should not add a route
+ * if this is a point-to-point iface, and we already
+ * have an iface for this AppleTalk address, then we
+ * should not add a route
*/
if ((dev->flags & IFF_POINTOPOINT) &&
- atalk_find_interface(sa->sat_addr.s_net, sa->sat_addr.s_node)) {
- printk(KERN_DEBUG "AppleTalk: point-to-point interface added with existing address\n");
+ atalk_find_interface(sa->sat_addr.s_net,
+ sa->sat_addr.s_node)) {
+ printk(KERN_DEBUG "AppleTalk: point-to-point "
+ "interface added with "
+ "existing address\n");
add_route = 0;
}
@@ -889,13 +812,11 @@ int atif_ioctl(int cmd, void *arg)
*/
if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2)
return -EPROTONOSUPPORT;
- if (sa->sat_addr.s_node == ATADDR_BCAST ||
+ if (sa->sat_addr.s_node == ATADDR_BCAST ||
sa->sat_addr.s_node == 254)
return -EINVAL;
if (atif) {
- /*
- * Already setting address.
- */
+ /* Already setting address */
if (atif->status & ATIF_PROBE)
return -EBUSY;
@@ -904,7 +825,7 @@ int atif_ioctl(int cmd, void *arg)
atrtr_device_down(dev); /* Flush old routes */
} else {
atif = atif_add_device(dev, &sa->sat_addr);
- if (atif == NULL)
+ if (!atif)
return -ENOMEM;
}
atif->nets = *nr;
@@ -921,10 +842,7 @@ int atif_ioctl(int cmd, void *arg)
return -EADDRINUSE;
}
- /*
- * Hey it worked - add the direct routes.
- */
-
+ /* Hey it worked - add the direct routes */
sa = (struct sockaddr_at *) &rtdef.rt_gateway;
sa->sat_family = AF_APPLETALK;
sa->sat_addr.s_net = atif->address.s_net;
@@ -933,13 +851,11 @@ int atif_ioctl(int cmd, void *arg)
rtdef.rt_flags = RTF_UP;
sa->sat_family = AF_APPLETALK;
sa->sat_addr.s_node = ATADDR_ANYNODE;
- if ((dev->flags & IFF_LOOPBACK) ||
- (dev->flags & IFF_POINTOPOINT))
+ if (dev->flags & IFF_LOOPBACK ||
+ dev->flags & IFF_POINTOPOINT)
rtdef.rt_flags |= RTF_HOST;
- /*
- * Routerless initial state.
- */
+ /* Routerless initial state */
if (nr->nr_firstnet == htons(0) &&
nr->nr_lastnet == htons(0xFFFE)) {
sa->sat_addr.s_net = atif->address.s_net;
@@ -948,37 +864,35 @@ int atif_ioctl(int cmd, void *arg)
} else {
limit = ntohs(nr->nr_lastnet);
if (limit - ntohs(nr->nr_firstnet) > 4096) {
- printk(KERN_WARNING "Too many routes/iface.\n");
+ printk(KERN_WARNING "Too many routes/"
+ "iface.\n");
return -EINVAL;
}
- if (add_route) {
- for(ct = ntohs(nr->nr_firstnet);ct <= limit; ct++) {
+ if (add_route)
+ for (ct = ntohs(nr->nr_firstnet);
+ ct <= limit; ct++) {
sa->sat_addr.s_net = htons(ct);
atrtr_create(&rtdef, dev);
}
- }
}
dev_mc_add(dev, aarp_mcast, 6, 1);
return 0;
case SIOCGIFADDR:
- if (atif == NULL)
+ if (!atif)
return -EADDRNOTAVAIL;
- ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_family =
- AF_APPLETALK;
- ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr =
- atif->address;
+
+ sa->sat_family = AF_APPLETALK;
+ sa->sat_addr = atif->address;
break;
case SIOCGIFBRDADDR:
- if (atif == NULL)
+ if (!atif)
return -EADDRNOTAVAIL;
- ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_family =
- AF_APPLETALK;
- ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_net =
- atif->address.s_net;
- ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_node =
- ATADDR_BCAST;
+
+ sa->sat_family = AF_APPLETALK;
+ sa->sat_addr.s_net = atif->address.s_net;
+ sa->sat_addr.s_node = ATADDR_BCAST;
break;
case SIOCATALKDIFADDR:
@@ -995,7 +909,7 @@ int atif_ioctl(int cmd, void *arg)
return -EPERM;
if (sa->sat_family != AF_APPLETALK)
return -EINVAL;
- if (atif == NULL)
+ if (!atif)
return -EADDRNOTAVAIL;
/*
@@ -1007,9 +921,10 @@ int atif_ioctl(int cmd, void *arg)
/*
* atif points to the current interface on this network;
- * we aren't concerned about its current status (at least for now),
- * but it has all the settings about the network we're going
- * to probe. consequently, it must exist.
+ * we aren't concerned about its current status (at
+ * least for now), but it has all the settings about
+ * the network we're going to probe. Consequently, it
+ * must exist.
*/
if (!atif)
return -EADDRNOTAVAIL;
@@ -1034,10 +949,10 @@ int atif_ioctl(int cmd, void *arg)
return -EADDRINUSE;
/*
- * We now have an address on the local network, and the AARP
- * code will defend it for us until we take it down.
- * We don't set up any routes right now, because ATCP will
- * install them manually via SIOCADDRT.
+ * We now have an address on the local network, and
+ * the AARP code will defend it for us until we take it
+ * down. We don't set up any routes right now, because
+ * ATCP will install them manually via SIOCADDRT.
*/
break;
@@ -1046,30 +961,22 @@ int atif_ioctl(int cmd, void *arg)
return -EPERM;
if (sa->sat_family != AF_APPLETALK)
return -EINVAL;
- if (atif == NULL)
+ if (!atif)
return -EADDRNOTAVAIL;
- /*
- * give to aarp module to remove proxy entry
- */
+ /* give to aarp module to remove proxy entry */
aarp_proxy_remove(atif->dev, &(sa->sat_addr));
-
return 0;
- };
-
- if (copy_to_user(arg, &atreq, sizeof(atreq)))
- return -EFAULT;
+ }
- return 0;
+ return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0;
}
-/*
- * Routing ioctl() calls
- */
+/* Routing ioctl() calls */
static int atrtr_ioctl(unsigned int cmd, void *arg)
{
- struct rtentry rt;
struct net_device *dev = NULL;
+ struct rtentry rt;
if (copy_from_user(&rt, arg, sizeof(rt)))
return -EFAULT;
@@ -1078,37 +985,38 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
case SIOCDELRT:
if (rt.rt_dst.sa_family != AF_APPLETALK)
return -EINVAL;
- return atrtr_delete(&((struct sockaddr_at *)&rt.rt_dst)->sat_addr);
+ return atrtr_delete(&((struct sockaddr_at *)
+ &rt.rt_dst)->sat_addr);
case SIOCADDRT:
- /* FIX ME: the name of the device is still in user space, isn't it? */
- if (rt.rt_dev != NULL) {
- if ((dev = __dev_get_by_name(rt.rt_dev)) == NULL)
+ /* FIXME: the name of the device is still in user
+ * space, isn't it? */
+ if (rt.rt_dev) {
+ dev = __dev_get_by_name(rt.rt_dev);
+ if (!dev)
return -ENODEV;
}
return atrtr_create(&rt, dev);
-
- default:
- return -EINVAL;
- };
+ }
+ return -EINVAL;
}
/* Called from proc fs - just make it print the ifaces neatly */
-
-static int atalk_if_get_info(char *buffer, char **start, off_t offset, int length)
+static int atalk_if_get_info(char *buffer, char **start, off_t offset,
+ int length)
{
- struct atalk_iface *iface;
- int len = 0;
off_t pos = 0;
off_t begin = 0;
-
- len += sprintf(buffer,"Interface Address Networks Status\n");
+ struct atalk_iface *iface;
+ int len = sprintf(buffer, "Interface Address "
+ "Networks Status\n");
spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface != NULL; iface = iface->next) {
+ for (iface = atalk_iface_list; iface; iface = iface->next) {
len += sprintf(buffer+len,"%-16s %04X:%02X %04X-%04X %d\n",
iface->dev->name, ntohs(iface->address.s_net),
- iface->address.s_node, ntohs(iface->nets.nr_firstnet),
+ iface->address.s_node,
+ ntohs(iface->nets.nr_firstnet),
ntohs(iface->nets.nr_lastnet), iface->status);
pos = begin + len;
if (pos < offset) {
@@ -1124,33 +1032,32 @@ static int atalk_if_get_info(char *buffer, char **start, off_t offset, int lengt
len -= (offset - begin);
if (len > length)
len = length;
-
- return (len);
+ return len;
}
/* Called from proc fs - just make it print the routes neatly */
-
-static int atalk_rt_get_info(char *buffer, char **start, off_t offset, int length)
+static int atalk_rt_get_info(char *buffer, char **start, off_t offset,
+ int length)
{
- struct atalk_route *rt;
- int len = 0;
off_t pos = 0;
off_t begin = 0;
+ int len = sprintf(buffer, "Target Router Flags Dev\n");
+ struct atalk_route *rt;
- len += sprintf(buffer,"Target Router Flags Dev\n");
if (atrtr_default.dev) {
rt = &atrtr_default;
- len += sprintf(buffer+len,"Default %04X:%02X %-4d %s\n",
+ len += sprintf(buffer + len,"Default %04X:%02X %-4d %s\n",
ntohs(rt->gateway.s_net), rt->gateway.s_node,
rt->flags, rt->dev->name);
}
read_lock_bh(&atalk_router_lock);
- for (rt = atalk_router_list; rt != NULL; rt = rt->next) {
- len += sprintf(buffer+len,"%04X:%02X %04X:%02X %-4d %s\n",
+ for (rt = atalk_router_list; rt; rt = rt->next) {
+ len += sprintf(buffer + len,
+ "%04X:%02X %04X:%02X %-4d %s\n",
ntohs(rt->target.s_net), rt->target.s_node,
- ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags,
- rt->dev->name);
+ ntohs(rt->gateway.s_net), rt->gateway.s_node,
+ rt->flags, rt->dev->name);
pos = begin + len;
if (pos < offset) {
len = 0;
@@ -1165,7 +1072,6 @@ static int atalk_rt_get_info(char *buffer, char **start, off_t offset, int lengt
len -= (offset - begin);
if (len > length)
len = length;
-
return len;
}
@@ -1198,11 +1104,8 @@ unsigned short atalk_checksum(struct ddpehdr *ddp, int len)
}
data++;
}
-
- if (sum)
- return htons((unsigned short) sum);
-
- return 0xFFFF; /* Use 0xFFFF for 0. 0 itself means none */
+ /* Use 0xFFFF for 0. 0 itself means none */
+ return sum ? htons((unsigned short) sum) : 0xFFFF;
}
/*
@@ -1211,10 +1114,9 @@ unsigned short atalk_checksum(struct ddpehdr *ddp, int len)
*/
static int atalk_create(struct socket *sock, int protocol)
{
- struct sock *sk;
+ struct sock *sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, 1);
- sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, 1);
- if (sk == NULL)
+ if (!sk)
return -ENOMEM;
switch (sock->type) {
@@ -1230,36 +1132,32 @@ static int atalk_create(struct socket *sock, int protocol)
case SOCK_STREAM:
/*
- * TO DO: if you want to implement ADSP, here's the place to start
+ * TODO: if you want to implement ADSP, here's the
+ * place to start
*/
/*
sock->ops = &atalk_stream_ops;
break;
*/
default:
- sk_free((void *) sk);
+ sk_free(sk);
return -ESOCKTNOSUPPORT;
- };
+ }
MOD_INC_USE_COUNT;
-
sock_init_data(sock, sk);
-
sk->destruct = NULL;
/* Checksums on by default */
sk->zapped = 1;
-
return 0;
}
-/*
- * Free a socket. No work needed
- */
+/* Free a socket. No work needed */
static int atalk_release(struct socket *sock)
{
- struct sock *sk=sock->sk;
+ struct sock *sk = sock->sk;
- if (sk == NULL)
+ if (!sk)
return 0;
if (!sk->dead)
@@ -1268,7 +1166,6 @@ static int atalk_release(struct socket *sock)
sk->dead = 1;
sock->sk = NULL;
atalk_destroy_socket(sk);
-
return 0;
}
@@ -1289,21 +1186,21 @@ static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat)
for (sat->sat_port = ATPORT_RESERVED;
sat->sat_port < ATPORT_LAST;
sat->sat_port++) {
- for (s = atalk_sockets; s != NULL; s = s->next) {
+ for (s = atalk_sockets; s; s = s->next) {
if (s->protinfo.af_at.src_net == sat->sat_addr.s_net &&
- s->protinfo.af_at.src_node == sat->sat_addr.s_node &&
+ s->protinfo.af_at.src_node ==
+ sat->sat_addr.s_node &&
s->protinfo.af_at.src_port == sat->sat_port)
goto try_next_port;
}
/* Wheee, it's free, assign and insert. */
- if ((sk->next = atalk_sockets) != NULL)
+ sk->next = atalk_sockets;
+ if (sk->next)
atalk_sockets->pprev = &sk->next;
atalk_sockets = sk;
sk->pprev = &atalk_sockets;
-
sk->protinfo.af_at.src_port = sat->sat_port;
-
retval = 0;
goto out;
@@ -1312,61 +1209,53 @@ static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat)
}
retval = -EBUSY;
-out:
- spin_unlock_bh(&atalk_sockets_lock);
-
+out: spin_unlock_bh(&atalk_sockets_lock);
return retval;
}
static int atalk_autobind(struct sock *sk)
{
- struct at_addr *ap = atalk_find_primary();
struct sockaddr_at sat;
int n;
+ struct at_addr *ap = atalk_find_primary();
- if (ap == NULL || ap->s_net == htons(ATADDR_ANYNET))
+ if (!ap || ap->s_net == htons(ATADDR_ANYNET))
return -EADDRNOTAVAIL;
sk->protinfo.af_at.src_net = sat.sat_addr.s_net = ap->s_net;
sk->protinfo.af_at.src_node = sat.sat_addr.s_node = ap->s_node;
- if ((n = atalk_pick_and_bind_port(sk, &sat)) < 0)
+ n = atalk_pick_and_bind_port(sk, &sat);
+ if (n < 0)
return n;
sk->zapped = 0;
-
return 0;
}
-/*
- * Set the address 'our end' of the connection.
- */
+/* Set the address 'our end' of the connection */
static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
- struct sock *sk;
struct sockaddr_at *addr = (struct sockaddr_at *)uaddr;
+ struct sock *sk = sock->sk;
- sk = sock->sk;
-
- if(sk->zapped == 0)
- return -EINVAL;
-
- if(addr_len != sizeof(struct sockaddr_at))
+ if (!sk->zapped || addr_len != sizeof(struct sockaddr_at))
return -EINVAL;
- if(addr->sat_family != AF_APPLETALK)
+ if (addr->sat_family != AF_APPLETALK)
return -EAFNOSUPPORT;
- if(addr->sat_addr.s_net == htons(ATADDR_ANYNET)) {
+ if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) {
struct at_addr *ap = atalk_find_primary();
- if(ap == NULL)
+ if (!ap)
return -EADDRNOTAVAIL;
sk->protinfo.af_at.src_net = addr->sat_addr.s_net = ap->s_net;
sk->protinfo.af_at.src_node = addr->sat_addr.s_node= ap->s_node;
} else {
- if (atalk_find_interface(addr->sat_addr.s_net, addr->sat_addr.s_node) == NULL)
+ if (!atalk_find_interface(addr->sat_addr.s_net,
+ addr->sat_addr.s_node))
return -EADDRNOTAVAIL;
sk->protinfo.af_at.src_net = addr->sat_addr.s_net;
@@ -1381,18 +1270,15 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
} else {
sk->protinfo.af_at.src_port = addr->sat_port;
- if (atalk_find_or_insert_socket(sk, addr) != NULL)
+ if (atalk_find_or_insert_socket(sk, addr))
return -EADDRINUSE;
}
sk->zapped = 0;
-
return 0;
}
-/*
- * Set the address we talk to.
- */
+/* Set the address we talk to */
static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
@@ -1412,19 +1298,20 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
if (addr->sat_addr.s_node == ATADDR_BCAST && !sk->broadcast) {
#if 1
- printk(KERN_WARNING "%s is broken and did not set SO_BROADCAST. It will break when 2.2 is released.\n",
+ printk(KERN_WARNING "%s is broken and did not set "
+ "SO_BROADCAST. It will break when 2.2 is "
+ "released.\n",
current->comm);
#else
return -EACCES;
#endif
}
- if (sk->zapped) {
+ if (sk->zapped)
if (atalk_autobind(sk) < 0)
return -EBUSY;
- }
- if (atrtr_get_dev(&addr->sat_addr) == NULL)
+ if (!atrtr_get_dev(&addr->sat_addr))
return -ENETUNREACH;
sk->protinfo.af_at.dest_port = addr->sat_port;
@@ -1433,7 +1320,6 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
sock->state = SS_CONNECTED;
sk->state = TCP_ESTABLISHED;
-
return 0;
}
@@ -1446,13 +1332,11 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
int *uaddr_len, int peer)
{
struct sockaddr_at sat;
- struct sock *sk;
+ struct sock *sk = sock->sk;
- sk = sock->sk;
- if (sk->zapped) {
+ if (sk->zapped)
if (atalk_autobind(sk) < 0)
return -ENOBUFS;
- }
*uaddr_len = sizeof(struct sockaddr_at);
@@ -1471,7 +1355,6 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
sat.sat_family = AF_APPLETALK;
memcpy(uaddr, &sat, sizeof(sat));
-
return 0;
}
@@ -1482,20 +1365,19 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
* extracted. PPP should probably pass frames marked as for this layer.
* [ie ARPHRD_ETHERTALK]
*/
-static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt)
{
- struct sock *sock;
struct ddpehdr *ddp = (void *) skb->h.raw;
+ struct sock *sock;
struct atalk_iface *atif;
struct sockaddr_at tosat;
int origlen;
struct ddpebits ddphv;
/* Size check */
- if (skb->len < sizeof(*ddp)) {
- kfree_skb(skb);
- return 0;
- }
+ if (skb->len < sizeof(*ddp))
+ goto freeit;
/*
* Fix up the length field [Ok this is horrible but otherwise
@@ -1506,15 +1388,10 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
* happens to be safe BUT.. (Its safe as user space will not
* run until we put it back)
*/
-
*((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp));
- /*
- * Trim buffer in case of stray trailing data
- */
-
+ /* Trim buffer in case of stray trailing data */
origlen = skb->len;
-
skb_trim(skb, min(skb->len, ddphv.deh_len));
/*
@@ -1522,32 +1399,26 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
* (Otherwise we'll detonate most spectacularly
* in the middle of recvmsg()).
*/
- if (skb->len < sizeof(*ddp)) {
- kfree_skb(skb);
- return 0;
- }
+ if (skb->len < sizeof(*ddp))
+ goto freeit;
/*
* Any checksums. Note we don't do htons() on this == is assumed to be
* valid for net byte orders all over the networking code...
*/
- if (ddp->deh_sum && atalk_checksum(ddp, ddphv.deh_len) != ddp->deh_sum) {
+ if (ddp->deh_sum &&
+ atalk_checksum(ddp, ddphv.deh_len) != ddp->deh_sum)
/* Not a valid AppleTalk frame - dustbin time */
- kfree_skb(skb);
- return 0;
- }
+ goto freeit;
/* Check the packet is aimed at us */
-
- if (ddp->deh_dnet == 0) /* Net 0 is 'this network' */
+ if (!ddp->deh_dnet) /* Net 0 is 'this network' */
atif = atalk_find_anynet(ddp->deh_dnode, dev);
else
atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode);
- /*
- * Not ours, so we route the packet via the correct AppleTalk interface.
- */
- if (atif == NULL) {
+ /* Not ours, so we route the packet via the correct AppleTalk iface */
+ if (!atif) {
struct atalk_route *rt;
struct at_addr ta;
@@ -1555,16 +1426,16 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
* Don't route multicast, etc., packets, or packets
* sent to "this network"
*/
- if (skb->pkt_type != PACKET_HOST || ddp->deh_dnet == 0) {
- /*
- * FIX ME:
- * Can it ever happen that a packet is from a PPP iface and needs to be broadcast onto the default network?
- */
+ if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) {
+ /* FIXME:
+ * Can it ever happen that a packet is from a PPP
+ * iface and needs to be broadcast onto the default
+ * network? */
if (dev->type == ARPHRD_PPP)
- printk(KERN_DEBUG "AppleTalk: didn't forward broadcast packet received from PPP iface\n");
-
- kfree_skb(skb);
- return 0;
+ printk(KERN_DEBUG "AppleTalk: didn't forward "
+ "broadcast packet received "
+ "from PPP iface\n");
+ goto freeit;
}
ta.s_net = ddp->deh_dnet;
@@ -1572,10 +1443,8 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
/* Route the packet */
rt = atrtr_find(&ta);
- if (rt == NULL || ddphv.deh_hops == DDP_MAXHOPS) {
- kfree_skb(skb);
- return 0;
- }
+ if (!rt || ddphv.deh_hops == DDP_MAXHOPS)
+ goto freeit;
ddphv.deh_hops++;
/*
@@ -1606,40 +1475,33 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
*
* Note. ddp-> becomes invalid at the realloc.
*/
- if (skb_headroom(skb) < 22)
- {
- struct sk_buff *newskb;
+ if (skb_headroom(skb) < 22) {
/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
- newskb = skb_realloc_headroom(skb, 32);
+ struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
kfree_skb(skb);
- if (!newskb)
- return 0;
- skb = newskb;
- }
- else
+ if (!nskb)
+ goto out;
+ skb = nskb;
+ } else
skb = skb_unshare(skb, GFP_ATOMIC);
/*
* If the buffer didn't vanish into the lack of
* space bitbucket we can send it.
*/
- if (skb) {
- if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1)
- kfree_skb(skb);
- }
-
- return 0;
+ if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1)
+ goto freeit;
+ goto out;
}
#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
- /*
- * Check if IP-over-DDP
- */
+ /* Check if IP-over-DDP */
if (skb->data[12] == 22) {
- struct net_device *dev;
+ struct net_device *dev = __dev_get_by_name("ipddp0");
+ struct net_device_stats *stats;
/* This needs to be able to handle ipddp"N" devices */
- if ((dev = __dev_get_by_name("ipddp0")) == NULL)
+ if (!dev)
return -ENODEV;
skb->protocol = htons(ETH_P_IP);
@@ -1647,14 +1509,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
skb->dev = dev;
skb->h.raw = skb->data;
- ((struct net_device_stats *)dev->priv)->rx_packets++;
- ((struct net_device_stats *)dev->priv)->rx_bytes += skb->len + 13;
+ stats = dev->priv;
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len + 13;
netif_rx(skb); /* Send the SKB up to a higher place. */
-
- return 0;
+ goto out;
}
#endif
-
/*
* Which socket - atalk_search_socket() looks for a *full match*
* of the <net,node,port> tuple.
@@ -1664,23 +1525,17 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
tosat.sat_port = ddp->deh_dport;
sock = atalk_search_socket(&tosat, atif);
-
- if (sock == NULL) {
- /* But not one of our sockets */
- kfree_skb(skb);
- return 0;
- }
+ if (!sock) /* But not one of our sockets */
+ goto freeit;
- /*
- * Queue packet (standard)
- */
-
+ /* Queue packet (standard) */
skb->sk = sock;
if (sock_queue_rcv_skb(sock, skb) < 0)
- kfree_skb(skb);
-
- return 0;
+ goto freeit;
+ goto out;
+freeit: kfree_skb(skb);
+out: return 0;
}
/*
@@ -1688,21 +1543,18 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
* Caller must provide enough headroom on the packet to pull the short
* header and append a long one.
*/
-static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pt)
{
struct ddpehdr *ddp;
struct at_addr *ap;
- /*
- * Expand any short form frames.
- */
+ /* Expand any short form frames */
if (skb->mac.raw[2] == 1) {
- /*
- * Find our address.
- */
+ /* Find our address */
ap = atalk_find_dev_addr(dev);
- if (ap == NULL || skb->len < sizeof(struct ddpshdr)) {
+ if (!ap || skb->len < sizeof(struct ddpshdr)) {
kfree_skb(skb);
return 0;
}
@@ -1715,9 +1567,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
skb_push(skb, sizeof(*ddp) - 4);
ddp = (struct ddpehdr *)skb->data;
- /*
- * Now fill in the long header.
- */
+ /* Now fill in the long header */
/*
* These two first. The mac overlays the new source/dest
@@ -1737,7 +1587,6 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
ddp->deh_len = skb->len;
ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop
if we slip up later */
-
/* Mend the byte order */
*((__u16 *)ddp) = htons(*((__u16 *)ddp));
}
@@ -1746,19 +1595,20 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_
return atalk_rcv(skb, dev, pt);
}
-static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
+static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
+ struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name;
+ int flags = msg->msg_flags;
+ int loopback = 0;
struct sockaddr_at local_satalk, gsat;
struct sk_buff *skb;
struct net_device *dev;
struct ddpehdr *ddp;
int size;
struct atalk_route *rt;
- int loopback = 0;
int err;
- int flags = msg->msg_flags;
if (flags & ~MSG_DONTWAIT)
return -EINVAL;
@@ -1767,19 +1617,18 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc
return -EMSGSIZE;
if (usat) {
- if(sk->zapped) {
+ if (sk->zapped)
if (atalk_autobind(sk) < 0)
return -EBUSY;
- }
- if (msg->msg_namelen < sizeof(*usat))
- return -EINVAL;
- if (usat->sat_family != AF_APPLETALK)
+ if (msg->msg_namelen < sizeof(*usat) ||
+ usat->sat_family != AF_APPLETALK)
return -EINVAL;
/* netatalk doesn't implement this check */
if (usat->sat_addr.s_node == ATADDR_BCAST && !sk->broadcast) {
- printk(KERN_INFO "SO_BROADCAST: Fix your netatalk as it will break before 2.2\n");
+ printk(KERN_INFO "SO_BROADCAST: Fix your netatalk as "
+ "it will break before 2.2\n");
#if 0
return -EPERM;
#endif
@@ -1795,15 +1644,14 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc
}
/* Build a packet */
-
SOCK_DEBUG(sk, "SK %p: Got address.\n", sk);
/* For headers */
size = sizeof(struct ddpehdr) + len + ddp_dl->header_length;
- if (usat->sat_addr.s_net != 0 || usat->sat_addr.s_node == ATADDR_ANYNODE) {
+ if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) {
rt = atrtr_find(&usat->sat_addr);
- if (rt == NULL)
+ if (!rt)
return -ENETUNREACH;
dev = rt->dev;
@@ -1814,24 +1662,23 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc
at_hint.s_net = sk->protinfo.af_at.src_net;
rt = atrtr_find(&at_hint);
- if (rt == NULL)
+ if (!rt)
return -ENETUNREACH;
dev = rt->dev;
}
- SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name);
+ SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n",
+ sk, size, dev->name);
size += dev->hard_header_len;
-
skb = sock_alloc_send_skb(sk, size, 0, (flags & MSG_DONTWAIT), &err);
- if (skb == NULL)
+ if (!skb)
return err;
skb->sk = sk;
skb_reserve(skb, ddp_dl->header_length);
skb_reserve(skb, dev->hard_header_len);
-
skb->dev = dev;
SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk);
@@ -1871,28 +1718,30 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc
* Loopback broadcast packets to non gateway targets (ie routes
* to group we are in)
*/
- if (ddp->deh_dnode == ATADDR_BCAST) {
- if ((!(rt->flags&RTF_GATEWAY)) && (!(dev->flags&IFF_LOOPBACK))) {
- struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL);
- if (skb2) {
- loopback = 1;
- SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
- if (aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL) == -1)
- kfree_skb(skb2);
+ if (ddp->deh_dnode == ATADDR_BCAST &&
+ !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) {
+ struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL);
+
+ if (skb2) {
+ loopback = 1;
+ SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
+ if (aarp_send_ddp(dev, skb2,
+ &usat->sat_addr, NULL) == -1)
+ kfree_skb(skb2);
/* else queued/sent above in the aarp queue */
- }
}
}
- if ((dev->flags & IFF_LOOPBACK) || loopback) {
+ if (dev->flags & IFF_LOOPBACK || loopback) {
SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk);
/* loop back */
skb_orphan(skb);
ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr);
skb->mac.raw = skb->data;
- skb->h.raw = skb->data + ddp_dl->header_length + dev->hard_header_len;
- skb_pull(skb,dev->hard_header_len);
- skb_pull(skb,ddp_dl->header_length);
+ skb->h.raw = skb->data + ddp_dl->header_length +
+ dev->hard_header_len;
+ skb_pull(skb, dev->hard_header_len);
+ skb_pull(skb, ddp_dl->header_length);
atalk_rcv(skb, dev, NULL);
} else {
SOCK_DEBUG(sk, "SK %p: send out.\n", sk);
@@ -1915,15 +1764,15 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
{
struct sock *sk = sock->sk;
struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
- struct ddpehdr *ddp = NULL;
- struct ddpebits ddphv;
+ struct ddpehdr *ddp = NULL;
int copied = 0;
- struct sk_buff *skb;
int err = 0;
+ struct ddpebits ddphv;
+ struct sk_buff *skb;
- skb = skb_recv_datagram(sk, (flags & ~MSG_DONTWAIT),
- (flags & MSG_DONTWAIT), &err);
- if (skb == NULL)
+ skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+ flags & MSG_DONTWAIT, &err);
+ if (!skb)
return err;
ddp = (struct ddpehdr *)(skb->h.raw);
@@ -1943,7 +1792,8 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
copied = size;
msg->msg_flags |= MSG_TRUNC;
}
- err = skb_copy_datagram_iovec(skb, sizeof(*ddp), msg->msg_iov, copied);
+ err = skb_copy_datagram_iovec(skb, sizeof(*ddp),
+ msg->msg_iov, copied);
}
if (!err) {
@@ -1957,7 +1807,6 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
}
skb_free_datagram(sk, skb); /* Free the datagram. */
-
return err ? err : copied;
}
@@ -1967,50 +1816,40 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size,
*/
static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
{
- long amount=0;
- struct sock *sk=sock->sk;
+ long amount = 0;
+ struct sock *sk = sock->sk;
- switch(cmd)
- {
- /*
- * Protocol layer
- */
+ switch (cmd) {
+ /* Protocol layer */
case TIOCOUTQ:
amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
- if(amount < 0)
+ if (amount < 0)
amount = 0;
break;
-
case TIOCINQ:
{
- struct sk_buff *skb;
- /* These two are safe on a single CPU system as only user tasks fiddle here */
- if((skb = skb_peek(&sk->receive_queue)) != NULL)
+ /* These two are safe on a single CPU system as only
+ * user tasks fiddle here */
+ struct sk_buff *skb = skb_peek(&sk->receive_queue);
+
+ if (skb)
amount = skb->len-sizeof(struct ddpehdr);
break;
}
-
case SIOCGSTAMP:
- if(sk)
- {
- if(sk->stamp.tv_sec == 0)
- return -ENOENT;
- return (copy_to_user((void *)arg,&sk->stamp,sizeof(struct timeval)) ? -EFAULT : 0);
- }
- return (-EINVAL);
-
- /*
- * Routing
- */
+ if (!sk)
+ return -EINVAL;
+ if (!sk->stamp.tv_sec)
+ return -ENOENT;
+ return copy_to_user((void *)arg, &sk->stamp,
+ sizeof(struct timeval)) ? -EFAULT : 0;
+ /* Routing */
case SIOCADDRT:
case SIOCDELRT:
- if(!capable(CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
- return (atrtr_ioctl(cmd,(void *)arg));
-
- /*
- * Interface
- */
+ return atrtr_ioctl(cmd, (void *)arg);
+ /* Interface */
case SIOCGIFADDR:
case SIOCSIFADDR:
case SIOCGIFBRDADDR:
@@ -2018,11 +1857,8 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
case SIOCDIFADDR:
case SIOCSARP: /* proxy AARP */
case SIOCDARP: /* proxy AARP */
- return (atif_ioctl(cmd,(void *)arg));
-
- /*
- * Physical layer ioctl calls
- */
+ return atif_ioctl(cmd, (void *)arg);
+ /* Physical layer ioctl calls */
case SIOCSIFLINK:
case SIOCGIFHWADDR:
case SIOCSIFHWADDR:
@@ -2035,8 +1871,7 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
case SIOCGIFCOUNT:
case SIOCGIFINDEX:
case SIOCGIFNAME:
- return ((dev_ioctl(cmd,(void *) arg)));
-
+ return dev_ioctl(cmd,(void *) arg);
case SIOCSIFMETRIC:
case SIOCSIFBRDADDR:
case SIOCGIFNETMASK:
@@ -2045,16 +1880,15 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
case SIOCSIFMEM:
case SIOCGIFDSTADDR:
case SIOCSIFDSTADDR:
- return (-EINVAL);
-
+ return -EINVAL;
default:
- return (-EINVAL);
+ return -EINVAL;
}
- return (put_user(amount, (int *)arg));
+ return put_user(amount, (int *)arg);
}
-static struct net_proto_family atalk_family_ops=
+static struct net_proto_family atalk_family_ops =
{
PF_APPLETALK,
atalk_create
@@ -2111,19 +1945,17 @@ struct packet_type ppptalk_packet_type=
static char ddp_snap_id[] = {0x08, 0x00, 0x07, 0x80, 0x9B};
-/*
- * Export symbols for use by drivers when AppleTalk is a module.
- */
+/* Export symbols for use by drivers when AppleTalk is a module */
EXPORT_SYMBOL(aarp_send_ddp);
EXPORT_SYMBOL(atrtr_get_dev);
EXPORT_SYMBOL(atalk_find_dev_addr);
/* Called by proto.c on kernel start up */
-
static int __init atalk_init(void)
{
(void) sock_register(&atalk_family_ops);
- if((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
+ ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv);
+ if (!ddp_dl)
printk(KERN_CRIT "Unable to register DDP with SNAP.\n");
ltalk_packet_type.type = htons(ETH_P_LOCALTALK);
@@ -2135,19 +1967,16 @@ static int __init atalk_init(void)
register_netdevice_notifier(&ddp_notifier);
aarp_proto_init();
-#ifdef CONFIG_PROC_FS
proc_net_create("appletalk", 0, atalk_get_info);
proc_net_create("atalk_route", 0, atalk_rt_get_info);
proc_net_create("atalk_iface", 0, atalk_if_get_info);
-
+#ifdef CONFIG_PROC_FS
aarp_register_proc_fs();
#endif /* CONFIG_PROC_FS */
-
#ifdef CONFIG_SYSCTL
atalk_register_sysctl();
#endif /* CONFIG_SYSCTL */
-
- printk(KERN_INFO "NET4: AppleTalk 0.18 for Linux NET4.0\n");
+ printk(KERN_INFO "NET4: AppleTalk 0.18a for Linux NET4.0\n");
return 0;
}
module_init(atalk_init);
@@ -2165,32 +1994,24 @@ module_init(atalk_init);
* Ergo, before the AppleTalk module can be removed, all AppleTalk
* sockets be closed from user space.
*/
-
static void __exit atalk_exit(void)
{
#ifdef CONFIG_SYSCTL
atalk_unregister_sysctl();
#endif /* CONFIG_SYSCTL */
-
-#ifdef CONFIG_PROC_FS
proc_net_remove("appletalk");
proc_net_remove("atalk_route");
proc_net_remove("atalk_iface");
-
+#ifdef CONFIG_PROC_FS
aarp_unregister_proc_fs();
#endif /* CONFIG_PROC_FS */
-
aarp_cleanup_module(); /* General aarp clean-up. */
-
unregister_netdevice_notifier(&ddp_notifier);
dev_remove_pack(&ltalk_packet_type);
dev_remove_pack(&ppptalk_packet_type);
unregister_snap_client(ddp_snap_id);
sock_unregister(PF_APPLETALK);
-
- return;
}
module_exit(atalk_exit);
#endif /* MODULE */
-
#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 51be9f077..ec0dc2671 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -51,6 +51,11 @@ static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00};
#define DPRINTK(format,args...)
#endif
+struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
+ unsigned char *addr);
+void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
+
+
#define DUMP_PACKETS 0 /* 0 = None,
* 1 = 30 first bytes
* 2 = Whole packet
@@ -853,8 +858,11 @@ static void __exit lane_module_cleanup(void)
if (dev_lec[i] != NULL) {
priv = (struct lec_priv *)dev_lec[i]->priv;
#if defined(CONFIG_TR)
- unregister_trdev(dev_lec[i]);
+ if (priv->is_trdev)
+ unregister_trdev(dev_lec[i]);
+ else
#endif
+ unregister_netdev(dev_lec[i]);
kfree(dev_lec[i]);
dev_lec[i] = NULL;
}
diff --git a/net/atm/lec.h b/net/atm/lec.h
index f40a37fa3..5dd0494e9 100644
--- a/net/atm/lec.h
+++ b/net/atm/lec.h
@@ -16,9 +16,9 @@
#if defined (CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#include <linux/if_bridge.h>
-struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
+extern struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
unsigned char *addr);
-void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
+extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
#endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
#define LEC_HEADER_LEN 16
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 940d69be0..8fcfe3fe4 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -4,7 +4,7 @@
* Authors:
* Lennert Buytenhek <buytenh@gnu.org>
*
- * $Id: br_private.h,v 1.3 2000/05/05 02:17:17 davem Exp $
+ * $Id: br_private.h,v 1.4 2001/01/19 04:51:48 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -112,8 +112,8 @@ struct net_bridge
int gc_interval;
};
-struct notifier_block br_device_notifier;
-unsigned char bridge_ula[6];
+extern struct notifier_block br_device_notifier;
+extern unsigned char bridge_ula[6];
/* br.c */
void br_dec_use_count(void);
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index f4bb62818..b12e1d5ec 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -442,7 +442,6 @@ static void nf_queue(struct sk_buff *skb,
}
}
-/* We have BR_NETPROTO_LOCK here */
int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
struct net_device *indev,
struct net_device *outdev,
@@ -452,6 +451,9 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
unsigned int verdict;
int ret = 0;
+ /* We may already have this, but read-locks nest anyway */
+ br_read_lock_bh(BR_NETPROTO_LOCK);
+
#ifdef CONFIG_NETFILTER_DEBUG
if (skb->nf_debug & (1 << hook)) {
printk("nf_hook: hook %i already set.\n", hook);
@@ -479,6 +481,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
break;
}
+ br_read_unlock_bh(BR_NETPROTO_LOCK);
return ret;
}
diff --git a/net/decnet/Makefile b/net/decnet/Makefile
index ac7a1a462..11f7c8b08 100644
--- a/net/decnet/Makefile
+++ b/net/decnet/Makefile
@@ -11,5 +11,3 @@ obj-y += sysctl_net_decnet.o
include $(TOPDIR)/Rules.make
-tar:
- tar -cvf /dev/f1 .
diff --git a/net/decnet/TODO b/net/decnet/TODO
index 1607d6d1b..c8ea8178d 100644
--- a/net/decnet/TODO
+++ b/net/decnet/TODO
@@ -43,15 +43,15 @@ Steve's quick list of things that need finishing off:
o Hello messages should be generated for each primary address on each
interface.
- o Add more information into /proc/net/decnet and finalise the format to
- allow DECnet support in netstat.
-
- o Make sure that returned connect messages are generated when they should
- be, and that the correct error messages are sent too.
-
o Add the routing message grabbing netfilter module [written, tested,
awaiting merge]
o Add perfect socket hashing - an idea suggested by Paul Koning [part written,
awaiting debugging and merge]
+ o Add session control message flow control
+
+ o Add NSP message flow control
+
+ o DECnet sendpages() function
+
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index bc51b636d..b930878c2 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -35,6 +35,7 @@
* Arnaldo C. Melo: use capable, not suser
* Steve Whitehouse: Removed unused code. Fix to use sk->allocation
* when required.
+ * Patrick Caulfield: /proc/net/decnet now has object name/number
*/
@@ -128,8 +129,6 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat
#include <net/dn_fib.h>
#include <net/dn_neigh.h>
-#define MAX(a,b) ((a)>(b)?(a):(b))
-
static void dn_keepalive(struct sock *sk);
/*
@@ -141,15 +140,15 @@ unsigned char decnet_ether_address[ETH_ALEN] = { 0xAA, 0x00, 0x04, 0x00, 0x00, 0
static struct proto_ops dn_proto_ops;
rwlock_t dn_hash_lock = RW_LOCK_UNLOCKED;
-static struct sock *dn_sklist = NULL;
-static struct sock *dn_wild_sk = NULL;
+static struct sock *dn_sklist;
+static struct sock *dn_wild_sk;
static int __dn_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen, int flags);
static int __dn_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen, int flags);
static struct sock **dn_find_list(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->addr.sdn_flags & SDF_WILD)
return dn_wild_sk ? NULL : &dn_wild_sk;
@@ -159,7 +158,7 @@ static struct sock **dn_find_list(struct sock *sk)
static unsigned short port_alloc(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
static unsigned short port = 0x2000;
if (port == 0)
@@ -177,12 +176,17 @@ static unsigned short port = 0x2000;
*/
static int dn_hash_sock(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct sock **skp;
int rv = -EUSERS;
- write_lock_bh(&dn_hash_lock);
+ if (sk->next)
+ BUG();
+ if (sk->pprev)
+ BUG();
+ write_lock_bh(&dn_hash_lock);
+
if (!scp->addrloc && !port_alloc(sk))
goto out;
@@ -327,7 +331,7 @@ struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr)
read_lock(&dn_hash_lock);
for(sk = dn_sklist; sk != NULL; sk = sk->next) {
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (sk->state != TCP_LISTEN)
continue;
if (scp->addr.sdn_objnum) {
@@ -355,13 +359,13 @@ struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr)
struct sock *dn_find_by_skb(struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct sock *sk;
struct dn_scp *scp;
read_lock(&dn_hash_lock);
for(sk = dn_sklist; sk != NULL; sk = sk->next) {
- scp = &sk->protinfo.dn;
+ scp = DN_SK(sk);
if (cb->src != dn_saddr2dn(&scp->peer))
continue;
if (cb->dst_port != scp->addrloc)
@@ -383,7 +387,7 @@ struct sock *dn_find_by_skb(struct sk_buff *skb)
static void dn_destruct(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
skb_queue_purge(&scp->data_xmit_queue);
skb_queue_purge(&scp->other_xmit_queue);
@@ -394,25 +398,26 @@ static void dn_destruct(struct sock *sk)
MOD_DEC_USE_COUNT;
}
-struct sock *dn_alloc_sock(struct socket *sock, int flags)
+struct sock *dn_alloc_sock(struct socket *sock, int gfp)
{
struct sock *sk;
struct dn_scp *scp;
- if ((sk = sk_alloc(PF_DECnet, flags, 1)) == NULL)
+ if ((sk = sk_alloc(PF_DECnet, gfp, 1)) == NULL)
goto no_sock;
if (sock) {
sock->ops = &dn_proto_ops;
}
sock_init_data(sock,sk);
- scp = &sk->protinfo.dn;
+ scp = DN_SK(sk);
sk->backlog_rcv = dn_nsp_backlog_rcv;
sk->destruct = dn_destruct;
sk->no_check = 1;
sk->family = PF_DECnet;
sk->protocol = 0;
+ sk->allocation = gfp;
/* Initialization of DECnet Session Control Port */
scp->state = DN_O; /* Open */
@@ -424,13 +429,25 @@ struct sock *dn_alloc_sock(struct socket *sock, int flags)
scp->ackrcv_oth = 0; /* Last oth data ack rec*/
scp->flowrem_sw = DN_SEND;
scp->flowloc_sw = DN_SEND;
+ scp->flowrem_dat = 0;
+ scp->flowrem_oth = 1;
+ scp->flowloc_dat = 0;
+ scp->flowloc_oth = 1;
+ scp->services_rem = 0;
+ scp->services_loc = 1 | NSP_FC_NONE;
+ scp->info_rem = 0;
+ scp->info_loc = 0x03; /* NSP version 4.1 */
+ scp->segsize_rem = 230; /* Default: Updated by remote segsize */
+ scp->segsize_loc = 1450; /* Best guess for ethernet */
+ scp->nonagle = 0;
+ scp->multi_ireq = 1;
scp->accept_mode = ACC_IMMED;
scp->addr.sdn_family = AF_DECnet;
scp->peer.sdn_family = AF_DECnet;
scp->accessdata.acc_accl = 5;
memcpy(scp->accessdata.acc_acc, "LINUX", 5);
- scp->mss = 1460;
+ scp->max_window = NSP_MAX_WINDOW;
scp->snd_window = NSP_MIN_WINDOW;
scp->nsp_srtt = NSP_INITIAL_SRTT;
scp->nsp_rttvar = NSP_INITIAL_RTTVAR;
@@ -464,7 +481,7 @@ no_sock:
*/
static void dn_keepalive(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
/*
* By checking the other_data transmit queue is empty
@@ -472,7 +489,7 @@ static void dn_keepalive(struct sock *sk)
* many of these keepalive frames.
*/
if (skb_queue_len(&scp->other_xmit_queue) == 0)
- dn_nsp_send_lnk(sk, DN_NOCHANGE);
+ dn_nsp_send_link(sk, DN_NOCHANGE, 0);
}
@@ -485,7 +502,7 @@ static void dn_keepalive(struct sock *sk)
*/
int dn_destroy_timer(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
scp->persist = dn_nsp_persist(sk);
@@ -527,7 +544,7 @@ int dn_destroy_timer(struct sock *sk)
static void dn_destroy_sock(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
scp->nsp_rxtshift = 0; /* reset back off */
@@ -674,7 +691,7 @@ dn_release(struct socket *sock)
static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr;
struct net_device *dev;
int rv;
@@ -722,11 +739,8 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
memcpy(&scp->addr, saddr, addr_len);
sk->zapped = 0;
- if ((rv = dn_hash_sock(sk)) == 0)
- goto out;
-
- sk->zapped = 1;
-out:
+ if ((rv = dn_hash_sock(sk)) != 0)
+ sk->zapped = 1;
return rv;
}
@@ -735,7 +749,7 @@ out:
static int dn_auto_bind(struct socket *sock)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
sk->zapped = 0;
@@ -769,7 +783,7 @@ static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len,
{
struct sockaddr_dn *addr = (struct sockaddr_dn *)uaddr;
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int err = -EISCONN;
lock_sock(sk);
@@ -788,7 +802,7 @@ static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len,
}
err = -EINVAL;
- if (sk->protinfo.dn.state != DN_O)
+ if (DN_SK(sk)->state != DN_O)
goto out;
if (addr_len != sizeof(struct sockaddr_dn))
@@ -812,7 +826,7 @@ static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len,
sk->state = TCP_SYN_SENT;
sock->state = SS_CONNECTING;
- sk->protinfo.dn.state = DN_CI;
+ DN_SK(sk)->state = DN_CI;
dn_nsp_send_conninit(sk, NSP_CI);
@@ -853,7 +867,7 @@ out:
return err;
}
-static int dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc)
+static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc)
{
unsigned char *ptr = skb->data;
@@ -870,10 +884,9 @@ static int dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc)
skb_pull(skb, acc->acc_accl + acc->acc_passl + acc->acc_userl + 3);
- return 0;
}
-static int dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
+static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
{
unsigned char *ptr = skb->data;
@@ -882,7 +895,6 @@ static int dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt)
memcpy(opt->opt_data, ptr, opt->opt_optl);
skb_pull(skb, opt->opt_optl + 1);
- return 0;
}
@@ -910,7 +922,7 @@ static int dn_wait_accept(struct socket *sock, int flags)
return -ERESTARTSYS; /* But of course you don't! */
}
- if ((sk->protinfo.dn.state != DN_RUN) && (sk->protinfo.dn.state != DN_DRC)) {
+ if ((DN_SK(sk)->state != DN_RUN) && (DN_SK(sk)->state != DN_DRC)) {
sock->state = SS_UNCONNECTED;
return sock_error(sk);
}
@@ -937,7 +949,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
return -EINVAL;
}
- if (sk->protinfo.dn.state != DN_O) {
+ if (DN_SK(sk)->state != DN_O) {
release_sock(sk);
return -EINVAL;
}
@@ -967,7 +979,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
}
} while (skb == NULL);
- cb = (struct dn_skb_cb *)skb->cb;
+ cb = DN_SKB_CB(skb);
if ((newsk = dn_alloc_sock(newsock, sk->allocation)) == NULL) {
release_sock(sk);
@@ -980,50 +992,52 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
dst_release(xchg(&newsk->dst_cache, skb->dst));
skb->dst = NULL;
- newsk->protinfo.dn.state = DN_CR;
- newsk->protinfo.dn.addrrem = cb->src_port;
- newsk->protinfo.dn.mss = cb->segsize;
- newsk->protinfo.dn.accept_mode = sk->protinfo.dn.accept_mode;
+ DN_SK(newsk)->state = DN_CR;
+ DN_SK(newsk)->addrrem = cb->src_port;
+ DN_SK(newsk)->services_rem = cb->services;
+ DN_SK(newsk)->info_rem = cb->info;
+ DN_SK(newsk)->segsize_rem = cb->segsize;
+ DN_SK(newsk)->accept_mode = DN_SK(sk)->accept_mode;
- if (newsk->protinfo.dn.mss < 230)
- newsk->protinfo.dn.mss = 230;
+ if (DN_SK(newsk)->segsize_rem < 230)
+ DN_SK(newsk)->segsize_rem = 230;
newsk->state = TCP_LISTEN;
newsk->zapped = 0;
- memcpy(&newsk->protinfo.dn.addr, &sk->protinfo.dn.addr, sizeof(struct sockaddr_dn));
+ memcpy(&(DN_SK(newsk)->addr), &(DN_SK(sk)->addr), sizeof(struct sockaddr_dn));
/*
* If we are listening on a wild socket, we don't want
* the newly created socket on the wrong hash queue.
*/
- newsk->protinfo.dn.addr.sdn_flags &= ~SDF_WILD;
+ DN_SK(newsk)->addr.sdn_flags &= ~SDF_WILD;
- skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &newsk->protinfo.dn.addr, &type));
- skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &newsk->protinfo.dn.peer, &type));
- *(dn_address *)newsk->protinfo.dn.peer.sdn_add.a_addr = cb->src;
- *(dn_address *)newsk->protinfo.dn.addr.sdn_add.a_addr = cb->dst;
+ skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->addr), &type));
+ skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->peer), &type));
+ *(dn_address *)(DN_SK(newsk)->peer.sdn_add.a_addr) = cb->src;
+ *(dn_address *)(DN_SK(newsk)->addr.sdn_add.a_addr) = cb->dst;
menuver = *skb->data;
skb_pull(skb, 1);
if (menuver & DN_MENUVER_ACC)
- dn_access_copy(skb, &newsk->protinfo.dn.accessdata);
+ dn_access_copy(skb, &(DN_SK(newsk)->accessdata));
if (menuver & DN_MENUVER_USR)
- dn_user_copy(skb, &newsk->protinfo.dn.conndata_in);
+ dn_user_copy(skb, &(DN_SK(newsk)->conndata_in));
if (menuver & DN_MENUVER_PRX)
- newsk->protinfo.dn.peer.sdn_flags |= SDF_PROXY;
+ DN_SK(newsk)->peer.sdn_flags |= SDF_PROXY;
if (menuver & DN_MENUVER_UIC)
- newsk->protinfo.dn.peer.sdn_flags |= SDF_UICPROXY;
+ DN_SK(newsk)->peer.sdn_flags |= SDF_UICPROXY;
kfree_skb(skb);
- memcpy(&newsk->protinfo.dn.conndata_out, &sk->protinfo.dn.conndata_out,
+ memcpy(&(DN_SK(newsk)->conndata_out), &(DN_SK(sk)->conndata_out),
sizeof(struct optdata_dn));
- memcpy(&newsk->protinfo.dn.discdata_out, &sk->protinfo.dn.discdata_out,
+ memcpy(&(DN_SK(newsk)->discdata_out), &(DN_SK(sk)->discdata_out),
sizeof(struct optdata_dn));
lock_sock(newsk);
@@ -1031,9 +1045,13 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
dn_send_conn_ack(newsk);
- if (newsk->protinfo.dn.accept_mode == ACC_IMMED) {
- newsk->protinfo.dn.state = DN_CC;
- dn_send_conn_conf(newsk, newsk->allocation);
+ /*
+ * Here we use sk->allocation since although the conn conf is
+ * for the newsk, the context is the old socket.
+ */
+ if (DN_SK(newsk)->accept_mode == ACC_IMMED) {
+ DN_SK(newsk)->state = DN_CC;
+ dn_send_conn_conf(newsk, sk->allocation);
err = dn_wait_accept(newsock, flags);
}
@@ -1046,7 +1064,7 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len
{
struct sockaddr_dn *sa = (struct sockaddr_dn *)uaddr;
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
*uaddr_len = sizeof(struct sockaddr_dn);
@@ -1070,7 +1088,7 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len
static unsigned int dn_poll(struct file *file, struct socket *sock, poll_table *wait)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int mask = datagram_poll(file, sock, wait);
if (skb_queue_len(&scp->other_receive_queue))
@@ -1082,100 +1100,32 @@ static unsigned int dn_poll(struct file *file, struct socket *sock, poll_table
static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int err = -EOPNOTSUPP;
unsigned long amount = 0;
struct sk_buff *skb;
+ int val;
-#if 0
- struct dn_naddr dnaddr;
-#endif
switch(cmd)
{
case SIOCGIFADDR:
case SIOCSIFADDR:
return dn_dev_ioctl(cmd, (void *)arg);
+ case SIOCATMARK:
+ lock_sock(sk);
+ val = (skb_queue_len(&scp->other_receive_queue) != 0);
+ if (scp->state != DN_RUN)
+ val = -ENOTCONN;
+ release_sock(sk);
+ return val;
+
#ifdef CONFIG_DECNET_ROUTER
case SIOCADDRT:
case SIOCDELRT:
return dn_fib_ioctl(sock, cmd, arg);
#endif /* CONFIG_DECNET_ROUTER */
-#if 0
- case SIOCSIFADDR:
- if (!capable(CAP_NET_ADMIN)) return -EPERM;
-
- if ((err = copy_from_user(devname, ioarg->devname, 5)) != 0)
- break;
- if ((err = copy_from_user(addr, ioarg->exec_addr, 6)) != 0)
- break;
- if ((dev = dev_get(devname)) == NULL) {
- err = -ENODEV;
- break;
- }
- if (dev->dn_ptr == NULL) {
- err = -ENODEV;
- break;
- }
-
- dn_dev_devices_off();
-
- decnet_default_device = dev;
- memcpy(decnet_ether_address, addr, ETH_ALEN);
- decnet_address = dn_htons(dn_eth2dn(decnet_ether_address));
-
- dn_dev_devices_on();
-
- break;
-
- case SIOCGIFADDR:
- if (decnet_default_device)
- strcpy(devname, decnet_default_device->name);
- else
- memset(devname, 0, 6);
-
- if ((err = copy_to_user(ioarg->devname, devname, 5)) != 0)
- break;
-
- if ((err = copy_to_user(ioarg->exec_addr, decnet_ether_address, 6)) != 0)
- break;
-
- break;
-#endif
-
-#if 0
- case SIOCSNETADDR:
- if (!capable(CAP_NET_ADMIN)) {
- err = -EPERM;
- break;
- }
-
- if ((err = copy_from_user(&dnaddr, (void *)arg, sizeof(struct dn_naddr))) != 0)
- break;
-
- if (dnaddr.a_len != ETH_ALEN) {
- err = -EINVAL;
- break;
- }
-
- dn_dev_devices_off();
-
- memcpy(decnet_ether_address, dnaddr.a_addr, ETH_ALEN);
- decnet_address = dn_htons(dn_eth2dn(decnet_ether_address));
-
- dn_dev_devices_on();
- break;
-
- case SIOCGNETADDR:
- dnaddr.a_len = ETH_ALEN;
- memcpy(dnaddr.a_addr, decnet_ether_address, ETH_ALEN);
-
- if ((err = copy_to_user((void *)arg, &dnaddr, sizeof(struct dn_naddr))) != 0)
- break;
-
- break;
-#endif
case OSIOCSNETADDR:
if (!capable(CAP_NET_ADMIN)) {
err = -EPERM;
@@ -1237,7 +1187,7 @@ static int dn_listen(struct socket *sock, int backlog)
if (sk->zapped)
goto out;
- if ((sk->protinfo.dn.state != DN_O) || (sk->state == TCP_LISTEN))
+ if ((DN_SK(sk)->state != DN_O) || (sk->state == TCP_LISTEN))
goto out;
sk->max_ack_backlog = backlog;
@@ -1255,7 +1205,7 @@ out:
static int dn_shutdown(struct socket *sock, int how)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int err = -ENOTCONN;
lock_sock(sk);
@@ -1300,14 +1250,27 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char *optv
static int __dn_setsockopt(struct socket *sock, int level,int optname, char *optval, int optlen, int flags)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
- struct optdata_dn opt;
- struct accessdata_dn acc;
+ struct dn_scp *scp = DN_SK(sk);
+ union {
+ struct optdata_dn opt;
+ struct accessdata_dn acc;
+ int mode;
+ unsigned long win;
+ int val;
+ unsigned char services;
+ unsigned char info;
+ } u;
int err;
if (optlen && !optval)
return -EINVAL;
+ if (optlen > sizeof(u))
+ return -EINVAL;
+
+ if (copy_from_user(&u, optval, optlen))
+ return -EFAULT;
+
switch(optname) {
case DSO_CONDATA:
if (sock->state == SS_CONNECTED)
@@ -1318,29 +1281,23 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
if (optlen != sizeof(struct optdata_dn))
return -EINVAL;
- if (copy_from_user(&opt, optval, optlen))
- return -EFAULT;
-
- if (opt.opt_optl > 16)
+ if (u.opt.opt_optl > 16)
return -EINVAL;
- memcpy(&scp->conndata_out, &opt, sizeof(struct optdata_dn));
+ memcpy(&scp->conndata_out, &u.opt, optlen);
break;
case DSO_DISDATA:
- if (sock->state != SS_CONNECTED && sk->protinfo.dn.accept_mode == ACC_IMMED)
+ if (sock->state != SS_CONNECTED && scp->accept_mode == ACC_IMMED)
return -ENOTCONN;
if (optlen != sizeof(struct optdata_dn))
return -EINVAL;
- if (copy_from_user(&opt, optval, sizeof(struct optdata_dn)))
- return -EFAULT;
-
- if (opt.opt_optl > 16)
+ if (u.opt.opt_optl > 16)
return -EINVAL;
- memcpy(&scp->discdata_out, &opt, sizeof(struct optdata_dn));
+ memcpy(&scp->discdata_out, &u.opt, optlen);
break;
case DSO_CONACCESS:
@@ -1352,15 +1309,12 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
if (optlen != sizeof(struct accessdata_dn))
return -EINVAL;
- if (copy_from_user(&acc, optval, sizeof(struct accessdata_dn)))
- return -EFAULT;
-
- if ((acc.acc_accl > DN_MAXACCL) ||
- (acc.acc_passl > DN_MAXACCL) ||
- (acc.acc_userl > DN_MAXACCL))
+ if ((u.acc.acc_accl > DN_MAXACCL) ||
+ (u.acc.acc_passl > DN_MAXACCL) ||
+ (u.acc.acc_userl > DN_MAXACCL))
return -EINVAL;
- memcpy(&scp->accessdata, &acc, sizeof(struct accessdata_dn));
+ memcpy(&scp->accessdata, &u.acc, optlen);
break;
case DSO_ACCEPTMODE:
@@ -1372,16 +1326,10 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
if (optlen != sizeof(int))
return -EINVAL;
- {
- int mode;
-
- if (get_user(mode, optval))
- return -EFAULT;
- if ((mode != ACC_IMMED) && (mode != ACC_DEFER))
- return -EINVAL;
+ if ((u.mode != ACC_IMMED) && (u.mode != ACC_DEFER))
+ return -EINVAL;
- scp->accept_mode = (unsigned char)mode;
- }
+ scp->accept_mode = (unsigned char)u.mode;
break;
case DSO_CONACCEPT:
@@ -1411,8 +1359,55 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt
case DSO_LINKINFO:
case DSO_STREAM:
case DSO_SEQPACKET:
-
return -ENOPROTOOPT;
+
+ case DSO_MAXWINDOW:
+ if (optlen != sizeof(unsigned long))
+ return -EINVAL;
+ if (u.win > NSP_MAX_WINDOW)
+ u.win = NSP_MAX_WINDOW;
+ if (u.win == 0)
+ return -EINVAL;
+ scp->max_window = u.win;
+ if (scp->snd_window > u.win)
+ scp->snd_window = u.win;
+ break;
+
+ case DSO_NODELAY:
+ if (optlen != sizeof(int))
+ return -EINVAL;
+ if (scp->nonagle == 2)
+ return -EINVAL;
+ scp->nonagle = (u.val == 0) ? 0 : 1;
+ /* if (scp->nonagle == 1) { Push pending frames } */
+ break;
+
+ case DSO_CORK:
+ if (optlen != sizeof(int))
+ return -EINVAL;
+ if (scp->nonagle == 1)
+ return -EINVAL;
+ scp->nonagle = (u.val == 0) ? 0 : 2;
+ /* if (scp->nonagle == 0) { Push pending frames } */
+ break;
+
+ case DSO_SERVICES:
+ if (optlen != sizeof(unsigned char))
+ return -EINVAL;
+ if ((u.services & ~NSP_FC_MASK) != 0x01)
+ return -EINVAL;
+ if ((u.services & NSP_FC_MASK) == NSP_FC_MASK)
+ return -EINVAL;
+ scp->services_loc = u.services;
+ break;
+
+ case DSO_INFO:
+ if (optlen != sizeof(unsigned char))
+ return -EINVAL;
+ if (u.info & 0xfc)
+ return -EINVAL;
+ scp->info_loc = u.info;
+ break;
}
return 0;
@@ -1433,44 +1428,40 @@ static int dn_getsockopt(struct socket *sock, int level, int optname, char *optv
static int __dn_getsockopt(struct socket *sock, int level,int optname, char *optval,int *optlen, int flags)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct linkinfo_dn link;
- int mode = scp->accept_mode;
+ int r_len = *optlen;
+ void *r_data = NULL;
+ int val;
switch(optname) {
case DSO_CONDATA:
- if (*optlen != sizeof(struct optdata_dn))
- return -EINVAL;
-
- if (copy_to_user(optval, &scp->conndata_in, sizeof(struct optdata_dn)))
- return -EFAULT;
+ if (r_len > sizeof(struct optdata_dn))
+ r_len = sizeof(struct optdata_dn);
+ r_data = &scp->conndata_in;
break;
case DSO_DISDATA:
- if (*optlen != sizeof(struct optdata_dn))
- return -EINVAL;
-
- if (copy_to_user(optval, &scp->discdata_in, sizeof(struct optdata_dn)))
- return -EFAULT;
-
+ if (r_len > sizeof(struct optdata_dn))
+ r_len = sizeof(struct optdata_dn);
+ r_data = &scp->discdata_in;
break;
case DSO_CONACCESS:
- if (*optlen != sizeof(struct accessdata_dn))
- return -EINVAL;
-
- if (copy_to_user(optval, &scp->accessdata, sizeof(struct accessdata_dn)))
- return -EFAULT;
+ if (r_len > sizeof(struct accessdata_dn))
+ r_len = sizeof(struct accessdata_dn);
+ r_data = &scp->accessdata;
break;
case DSO_ACCEPTMODE:
- if (put_user(mode, optval))
- return -EFAULT;
+ if (r_len > sizeof(unsigned char))
+ r_len = sizeof(unsigned char);
+ r_data = &scp->accept_mode;
break;
case DSO_LINKINFO:
- if (*optlen != sizeof(struct linkinfo_dn))
- return -EINVAL;
+ if (r_len > sizeof(struct linkinfo_dn))
+ r_len = sizeof(struct linkinfo_dn);
switch(sock->state) {
case SS_CONNECTING:
@@ -1486,10 +1477,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt
link.idn_linkstate = LL_INACTIVE;
}
- link.idn_segsize = scp->mss;
-
- if (copy_to_user(optval, &link, sizeof(struct linkinfo_dn)))
- return -EFAULT;
+ link.idn_segsize = scp->segsize_rem;
+ r_data = &link;
break;
default:
@@ -1508,6 +1497,45 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt
case DSO_CONACCEPT:
case DSO_CONREJECT:
return -ENOPROTOOPT;
+
+ case DSO_MAXWINDOW:
+ if (r_len > sizeof(unsigned long))
+ r_len = sizeof(unsigned long);
+ r_data = &scp->max_window;
+ break;
+
+ case DSO_NODELAY:
+ if (r_len > sizeof(int))
+ r_len = sizeof(int);
+ val = (scp->nonagle == 1);
+ r_data = &val;
+ break;
+
+ case DSO_CORK:
+ if (r_len > sizeof(int))
+ r_len = sizeof(int);
+ val = (scp->nonagle == 2);
+ r_data = &val;
+ break;
+
+ case DSO_SERVICES:
+ if (r_len > sizeof(unsigned char))
+ r_len = sizeof(unsigned char);
+ r_data = &scp->services_rem;
+ break;
+
+ case DSO_INFO:
+ if (r_len > sizeof(unsigned char))
+ r_len = sizeof(unsigned char);
+ r_data = &scp->info_rem;
+ break;
+ }
+
+ if (r_data) {
+ if (copy_to_user(optval, r_data, r_len))
+ return -EFAULT;
+ if (put_user(r_len, optlen))
+ return -EFAULT;
}
return 0;
@@ -1520,7 +1548,7 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt
*/
static int dn_wait_run(struct sock *sk, int flags)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int err = 0;
switch(scp->state) {
@@ -1572,7 +1600,7 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int
return skb_queue_len(q) ? 1 : 0;
while(skb != (struct sk_buff *)q) {
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
len += skb->len;
if (cb->nsp_flags & 0x40) {
@@ -1599,7 +1627,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size,
int flags, struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct sk_buff_head *queue = &sk->receive_queue;
int target = size > 1 ? 1 : 0;
int copied = 0;
@@ -1681,7 +1709,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size,
for(skb = queue->next; skb != (struct sk_buff *)queue; skb = nskb) {
int chunk = skb->len;
- cb = (struct dn_skb_cb *)skb->cb;
+ cb = DN_SKB_CB(skb);
if ((chunk + copied) > size)
chunk = size - copied;
@@ -1693,7 +1721,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size,
copied += chunk;
if (!(flags & MSG_PEEK))
- skb->len -= chunk;
+ skb_pull(skb, chunk);
eor = cb->nsp_flags & 0x40;
nskb = skb->next;
@@ -1707,7 +1735,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size,
*/
if ((scp->flowloc_sw == DN_DONTSEND) && !dn_congested(sk)) {
scp->flowloc_sw = DN_SEND;
- dn_nsp_send_lnk(sk, DN_SEND);
+ dn_nsp_send_link(sk, DN_SEND, 0);
}
}
@@ -1727,6 +1755,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size,
rv = copied;
+
if (eor && (sk->type == SOCK_SEQPACKET))
msg->msg_flags |= MSG_EOR;
@@ -1745,16 +1774,31 @@ out:
}
+static inline int dn_queue_too_long(struct dn_scp *scp, struct sk_buff_head *queue, int flags)
+{
+ unsigned char fctype = scp->services_rem & NSP_FC_MASK;
+ if (skb_queue_len(queue) >= scp->snd_window)
+ return 1;
+ if (fctype != NSP_FC_NONE) {
+ if (flags & MSG_OOB) {
+ if (scp->flowrem_oth == 0)
+ return 1;
+ } else {
+ if (scp->flowrem_dat == 0)
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
- struct dn_scp *scp = &sk->protinfo.dn;
- int mss = scp->mss;
- int mtu = 230 - 11; /* maximum value thats always safe */
+ struct dn_scp *scp = DN_SK(sk);
+ int mss;
struct sk_buff_head *queue = &scp->data_xmit_queue;
int flags = msg->msg_flags;
- unsigned short numseg = 0;
int err = 0;
int sent = 0;
int addr_len = msg->msg_namelen;
@@ -1765,6 +1809,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
unsigned char *ptr;
unsigned short ack;
int len;
+ unsigned char fctype;
if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR))
return -EOPNOTSUPP;
@@ -1801,16 +1846,19 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
if ((flags & MSG_TRYHARD) && sk->dst_cache)
dst_negative_advice(&sk->dst_cache);
+ mss = scp->segsize_rem;
+ fctype = scp->services_rem & NSP_FC_MASK;
+
if (sk->dst_cache && sk->dst_cache->neighbour) {
struct dn_neigh *dn = (struct dn_neigh *)sk->dst_cache->neighbour;
- if (dn->blksize > 230)
- mtu = dn->blksize - 11;
+ if (dn->blksize < (mss + 11))
+ mss = dn->blksize - 11;
}
/*
* The only difference between SEQPACKET & STREAM sockets under DECnet
- * AFAIK is that SEQPACKET sockets set the MSG_EOR flag for the last
- * session control message segment.
+ * is that SEQPACKET sockets set the MSG_EOR flag for the last
+ * session control message segment.
*/
if (flags & MSG_OOB) {
@@ -1822,9 +1870,6 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
}
}
- if (mss < mtu)
- mtu = mss;
-
scp->persist_fxn = dn_nsp_xmit_timeout;
while(sent < size) {
@@ -1842,14 +1887,14 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
*/
len = size - sent;
- if (len > mtu)
- len = mtu;
+ if (len > mss)
+ len = mss;
/*
* Wait for queue size to go down below the window
* size.
*/
- if (skb_queue_len(queue) >= scp->snd_window) {
+ if (dn_queue_too_long(scp, queue, flags)) {
if (flags & MSG_DONTWAIT) {
err = -EWOULDBLOCK;
goto out;
@@ -1857,7 +1902,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
SOCK_SLEEP_PRE(sk)
- if (skb_queue_len(queue) >= scp->snd_window)
+ if (dn_queue_too_long(scp, queue, flags))
schedule();
SOCK_SLEEP_POST(sk)
@@ -1876,7 +1921,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
if (!skb)
continue;
- cb = (struct dn_skb_cb *)skb->cb;
+ cb = DN_SKB_CB(skb);
ptr = skb_put(skb, 9);
@@ -1886,26 +1931,34 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
}
if (flags & MSG_OOB) {
- cb->segnum = scp->numoth++;
- scp->numoth &= 0x0fff;
+ cb->segnum = scp->numoth;
+ seq_add(&scp->numoth, 1);
msgflg = 0x30;
- ack = scp->ackxmt_oth | 0x8000;
+ ack = (scp->numoth_rcv & 0x0FFF) | 0x8000;
+ scp->ackxmt_oth = scp->numoth_rcv;
+ if (fctype != NSP_FC_NONE)
+ scp->flowrem_oth--;
} else {
- cb->segnum = scp->numdat++;
- scp->numdat &= 0x0fff;
+ cb->segnum = scp->numdat;
+ seq_add(&scp->numdat, 1);
msgflg = 0x00;
if (sock->type == SOCK_STREAM)
msgflg = 0x60;
- if (scp->seg_size == 0)
+ if (scp->seg_total == 0)
msgflg |= 0x20;
- scp->seg_size += len;
+ scp->seg_total += len;
if (((sent + len) == size) && (flags & MSG_EOR)) {
msgflg |= 0x40;
- scp->seg_size = 0;
+ scp->seg_total = 0;
+ if (fctype == NSP_FC_SCMC)
+ scp->flowrem_dat--;
}
- ack = scp->ackxmt_dat | 0x8000;
+ ack = (scp->numdat_rcv & 0x0FFF) | 0x8000;
+ scp->ackxmt_dat = scp->numdat_rcv;
+ if (fctype == NSP_FC_SRC)
+ scp->flowrem_dat--;
}
*ptr++ = msgflg;
@@ -1918,8 +1971,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size,
*(__u16 *)ptr = dn_htons(cb->segnum);
sent += len;
- dn_nsp_queue_xmit(sk, skb, flags & MSG_OOB);
- numseg++;
+ dn_nsp_queue_xmit(sk, skb, sk->allocation, flags & MSG_OOB);
skb = NULL;
scp->persist = dn_nsp_persist(sk);
@@ -1955,21 +2007,38 @@ static int dn_device_event(struct notifier_block *this, unsigned long event,
}
static struct notifier_block dn_dev_notifier = {
- dn_device_event,
- 0
+ notifier_call: dn_device_event,
};
extern int dn_route_rcv(struct sk_buff *, struct net_device *, struct packet_type *);
-static struct packet_type dn_dix_packet_type =
-{
- __constant_htons(ETH_P_DNA_RT),
- NULL, /* All devices */
- dn_route_rcv,
- (void*)1,
- NULL,
+static struct packet_type dn_dix_packet_type = {
+ type: __constant_htons(ETH_P_DNA_RT),
+ dev: NULL, /* All devices */
+ func: dn_route_rcv,
+ data: (void*)1,
};
+#define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126)
+
+static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf)
+{
+ int i;
+
+ switch (dn_ntohs(dn->sdn_objnamel)) {
+ case 0:
+ sprintf(buf, "%d", dn->sdn_objnum);
+ break;
+ default:
+ for (i = 0; i < dn_ntohs(dn->sdn_objnamel); i++) {
+ buf[i] = dn->sdn_objname[i];
+ if (IS_NOT_PRINTABLE(buf[i]))
+ buf[i] = '.';
+ }
+ buf[i] = 0;
+ }
+}
+
static int dn_get_info(char *buffer, char **start, off_t offset, int length)
{
struct sock *sk;
@@ -1979,15 +2048,20 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length)
off_t begin = 0;
char buf1[DN_ASCBUF_LEN];
char buf2[DN_ASCBUF_LEN];
+ char local_object[DN_MAXOBJL+3];
+ char remote_object[DN_MAXOBJL+3];
- len += sprintf(buffer + len, "Local Remote\n");
+ len += sprintf(buffer + len, "Local Remote\n");
read_lock(&dn_hash_lock);
for(sk = dn_sklist; sk != NULL; sk = sk->next) {
- scp = &sk->protinfo.dn;
+ scp = DN_SK(sk);
+
+ dn_printable_object(&scp->addr, local_object);
+ dn_printable_object(&scp->peer, remote_object);
len += sprintf(buffer + len,
- "%6s/%04X %04d:%04d %04d:%04d %01d %6s/%04X %04d:%04d %04d:%04d %01d %4s %s\n",
+ "%6s/%04X %04d:%04d %04d:%04d %01d %-16s %6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n",
dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1),
scp->addrloc,
scp->numdat,
@@ -1995,6 +2069,7 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length)
scp->ackxmt_dat,
scp->ackxmt_oth,
scp->flowloc_sw,
+ local_object,
dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2),
scp->addrrem,
scp->numdat_rcv,
@@ -2002,6 +2077,7 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length)
scp->ackrcv_dat,
scp->ackrcv_oth,
scp->flowrem_sw,
+ remote_object,
dn_state2asc(scp->state),
((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER"));
@@ -2026,8 +2102,8 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length)
static struct net_proto_family dn_family_ops = {
- AF_DECnet,
- dn_create
+ family: AF_DECnet,
+ create: dn_create,
};
static struct proto_ops dn_proto_ops = {
@@ -2067,6 +2143,7 @@ MODULE_PARM(addr, "2i");
MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node");
#endif
+static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.4.0-test12s (C) 1995-2000 Linux DECnet Project Team\n";
static int __init decnet_init(void)
{
@@ -2085,7 +2162,7 @@ static int __init decnet_init(void)
dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address));
#endif
- printk(KERN_INFO "NET4: DECnet for Linux: V.2.4.0-test10s (C) 1995-2000 Linux DECnet Project Team\n");
+ printk(banner);
sock_register(&dn_family_ops);
dev_add_pack(&dn_dix_packet_type);
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index d8f91ac38..056eaa043 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -52,7 +52,7 @@ static unsigned char dn_eco_version[3] = {0x02,0x00,0x00};
extern struct neigh_table dn_neigh_table;
-struct net_device *decnet_default_device = NULL;
+struct net_device *decnet_default_device;
static struct dn_dev *dn_dev_create(struct net_device *dev, int *err);
static void dn_dev_delete(struct net_device *dev);
@@ -1286,9 +1286,7 @@ void __exit dn_dev_cleanup(void)
}
#endif /* CONFIG_SYSCTL */
-#ifdef CONFIG_PROC_FS
proc_net_remove("decnet_dev");
-#endif /* CONFIG_PROC_FS */
dn_dev_devices_off();
}
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index aff2dc05d..f82e26406 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -55,7 +55,7 @@ extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
#endif /* CONFIG_RTNETLINK */
-static struct dn_fib_info *dn_fib_info_list = NULL;
+static struct dn_fib_info *dn_fib_info_list;
static rwlock_t dn_fib_info_lock = RW_LOCK_UNLOCKED;
int dn_fib_info_cnt;
@@ -641,15 +641,11 @@ static int decnet_rt_get_info(char *buffer, char **start, off_t offset, int leng
return 0;
}
-
#endif /* CONFIG_PROC_FS */
-
void __exit dn_fib_cleanup(void)
{
-#ifdef CONFIG_PROC_FS
proc_net_remove("decnet_route");
-#endif
dn_fib_table_cleanup();
dn_fib_rules_cleanup();
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 00c27cdec..f25f37275 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -18,6 +18,8 @@
* forwarding now stands a good chance of
* working.
* Steve Whitehouse : Fixed neighbour states (for now anyway).
+ * Steve Whitehouse : Made error_report functions dummies. This
+ * is not the right place to return skbs.
*
*/
@@ -52,81 +54,66 @@ static int dn_phase3_output(struct sk_buff *);
* For talking to broadcast devices: Ethernet & PPP
*/
static struct neigh_ops dn_long_ops = {
- AF_DECnet,
- NULL,
- NULL,
- dn_long_error_report,
- dn_long_output,
- dn_long_output,
- dev_queue_xmit,
- dev_queue_xmit
+ family: AF_DECnet,
+ error_report: dn_long_error_report,
+ output: dn_long_output,
+ connected_output: dn_long_output,
+ hh_output: dev_queue_xmit,
+ queue_xmit: dev_queue_xmit,
};
/*
* For talking to pointopoint and multidrop devices: DDCMP and X.25
*/
static struct neigh_ops dn_short_ops = {
- AF_DECnet,
- NULL,
- NULL,
- dn_short_error_report,
- dn_short_output,
- dn_short_output,
- dev_queue_xmit,
- dev_queue_xmit
+ family: AF_DECnet,
+ error_report: dn_short_error_report,
+ output: dn_short_output,
+ connected_output: dn_short_output,
+ hh_output: dev_queue_xmit,
+ queue_xmit: dev_queue_xmit,
};
/*
* For talking to DECnet phase III nodes
*/
static struct neigh_ops dn_phase3_ops = {
- AF_DECnet,
- NULL,
- NULL,
- dn_short_error_report, /* Can use short version here */
- dn_phase3_output,
- dn_phase3_output,
- dev_queue_xmit,
- dev_queue_xmit
+ family: AF_DECnet,
+ error_report: dn_short_error_report, /* Can use short version here */
+ output: dn_phase3_output,
+ connected_output: dn_phase3_output,
+ hh_output: dev_queue_xmit,
+ queue_xmit: dev_queue_xmit
};
struct neigh_table dn_neigh_table = {
- NULL,
- PF_DECnet,
- sizeof(struct dn_neigh),
- sizeof(dn_address),
- dn_neigh_hash,
- dn_neigh_construct,
- NULL, /* pconstructor */
- NULL, /* pdestructor */
- NULL, /* proxyredo */
- "dn_neigh_cache",
- {
- NULL,
- NULL,
- &dn_neigh_table,
- 0,
- NULL,
- NULL,
- 30 * HZ, /* base_reachable_time */
- 1 * HZ, /* retrans_time */
- 60 * HZ, /* gc_staletime */
- 30 * HZ, /* reachable_time */
- 5 * HZ, /* delay_probe_time */
- 3, /* queue_len */
- 0, /* ucast_probes */
- 0, /* app_probes */
- 0, /* mcast_probes */
- 0, /* anycast_delay */
- 0, /* proxy_delay */
- 0, /* proxy_qlen */
- 1 * HZ, /* locktime */
+ family: PF_DECnet,
+ entry_size: sizeof(struct dn_neigh),
+ key_len: sizeof(dn_address),
+ hash: dn_neigh_hash,
+ constructor: dn_neigh_construct,
+ id: "dn_neigh_cache",
+ parms: {
+ tbl: &dn_neigh_table,
+ entries: 0,
+ base_reachable_time: 30 * HZ,
+ retrans_time: 1 * HZ,
+ gc_staletime: 60 * HZ,
+ reachable_time: 30 * HZ,
+ delay_probe_time: 5 * HZ,
+ queue_len: 3,
+ ucast_probes: 0,
+ app_probes: 0,
+ mcast_probes: 0,
+ anycast_delay: 0,
+ proxy_delay: 0,
+ proxy_qlen: 0,
+ locktime: 1 * HZ,
},
- 30 * HZ, /* gc_interval */
- 128, /* gc_thresh1 */
- 512, /* gc_thresh2 */
- 1024, /* gc_thresh3 */
-
+ gc_interval: 30 * HZ,
+ gc_thresh1: 128,
+ gc_thresh2: 512,
+ gc_thresh3: 1024,
};
static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev)
@@ -180,66 +167,15 @@ static int dn_neigh_construct(struct neighbour *neigh)
static void dn_long_error_report(struct neighbour *neigh, struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
- unsigned char *ptr;
-
printk(KERN_DEBUG "dn_long_error_report: called\n");
-
- if (!(cb->rt_flags & DN_RT_F_RQR)) {
- kfree_skb(skb);
- return;
- }
-
- skb_push(skb, skb->data - skb->nh.raw);
- ptr = skb->data;
-
- *(unsigned short *)ptr = dn_htons(skb->len - 2);
- ptr += 2;
-
- if (*ptr & DN_RT_F_PF) {
- char padlen = (*ptr & ~DN_RT_F_PF);
- ptr += padlen;
- }
-
- *ptr++ |= (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS;
-
- ptr += 2;
- dn_dn2eth(ptr, dn_ntohs(cb->src));
- ptr += 8;
- dn_dn2eth(ptr, dn_ntohs(cb->dst));
- ptr += 6;
- *ptr = 0;
-
- skb->dst->neighbour->ops->queue_xmit(skb);
+ kfree_skb(skb);
}
static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
- unsigned char *ptr;
-
printk(KERN_DEBUG "dn_short_error_report: called\n");
-
- if (!(cb->rt_flags & DN_RT_F_RQR)) {
- kfree_skb(skb);
- return;
- }
-
- skb_push(skb, skb->data - skb->nh.raw);
- ptr = skb->data;
-
- *(unsigned short *)ptr = dn_htons(skb->len - 2);
- ptr += 2;
- *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS;
-
- *(dn_address *)ptr = cb->src;
- ptr += 2;
- *(dn_address *)ptr = cb->dst;
- ptr += 2;
- *ptr = 0;
-
- skb->dst->neighbour->ops->queue_xmit(skb);
+ kfree_skb(skb);
}
static int dn_neigh_output_packet(struct sk_buff *skb)
@@ -266,7 +202,7 @@ static int dn_long_output(struct sk_buff *skb)
int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3;
unsigned char *data;
struct dn_long_packet *lp;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
if (skb_headroom(skb) < headroom) {
@@ -312,7 +248,7 @@ static int dn_short_output(struct sk_buff *skb)
int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
struct dn_short_packet *sp;
unsigned char *data;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
if (skb_headroom(skb) < headroom) {
@@ -355,7 +291,7 @@ static int dn_phase3_output(struct sk_buff *skb)
int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
struct dn_short_packet *sp;
unsigned char *data;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
if (skb_headroom(skb) < headroom) {
struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
@@ -659,8 +595,6 @@ void __init dn_neigh_init(void)
void __exit dn_neigh_cleanup(void)
{
-#ifdef CONFIG_PROC_FS
proc_net_remove("decnet_neigh");
-#endif /* CONFIG_PROC_FS */
neigh_table_clear(&dn_neigh_table);
}
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 361729458..11a4e8237 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -25,6 +25,9 @@
* Steve Whitehouse:
* Patrick Caulfield: Checking conninits for correctness & sending of error
* responses.
+ * Steve Whitehouse: Added backlog congestion level return codes.
+ * Patrick Caulfield:
+ * Steve Whitehouse: Added flow control support (outbound)
*/
/******************************************************************************
@@ -79,7 +82,7 @@ static void dn_log_martian(struct sk_buff *skb, const char *msg)
{
if (decnet_log_martians && net_ratelimit()) {
char *devname = skb->dev ? skb->dev->name : "???";
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
printk(KERN_INFO "DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n", msg, devname, cb->src, cb->dst, cb->src_port, cb->dst_port);
}
}
@@ -91,7 +94,7 @@ static void dn_log_martian(struct sk_buff *skb, const char *msg)
*/
static void dn_ack(struct sock *sk, struct sk_buff *skb, unsigned short ack)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
unsigned short type = ((ack >> 12) & 0x0003);
int wakeup = 0;
@@ -212,7 +215,7 @@ static struct {
*/
static struct sock *dn_find_listener(struct sk_buff *skb, unsigned short *reason)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct nsp_conn_init_msg *msg = (struct nsp_conn_init_msg *)skb->data;
struct sockaddr_dn dstaddr;
struct sockaddr_dn srcaddr;
@@ -331,33 +334,26 @@ static void dn_nsp_conn_init(struct sock *sk, struct sk_buff *skb)
static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ struct dn_scp *scp = DN_SK(sk);
+ unsigned char *ptr;
- if (skb->len < 3)
+ if (skb->len < 4)
goto out;
- cb->services = *skb->data;
- cb->info = *(skb->data+1);
- skb_pull(skb, 2);
- cb->segsize = dn_ntohs(*(__u16 *)skb->data);
- skb_pull(skb, 2);
-
- /*
- * FIXME: Check out services and info fields to check that
- * we can talk to this kind of node.
- */
+ ptr = skb->data;
+ cb->services = *ptr++;
+ cb->info = *ptr++;
+ cb->segsize = dn_ntohs(*(__u16 *)ptr);
if ((scp->state == DN_CI) || (scp->state == DN_CD)) {
scp->persist = 0;
scp->addrrem = cb->src_port;
sk->state = TCP_ESTABLISHED;
scp->state = DN_RUN;
-
- if (scp->mss > cb->segsize)
- scp->mss = cb->segsize;
- if (scp->mss < 230)
- scp->mss = 230;
+ scp->services_rem = cb->services;
+ scp->info_rem = cb->info;
+ scp->segsize_rem = cb->segsize;
if (skb->len > 0) {
unsigned char dlen = *skb->data;
@@ -366,7 +362,7 @@ static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb)
memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen);
}
}
- dn_nsp_send_lnk(sk, DN_NOCHANGE);
+ dn_nsp_send_link(sk, DN_NOCHANGE, 0);
if (!sk->dead)
sk->state_change(sk);
}
@@ -377,7 +373,7 @@ out:
static void dn_nsp_conn_ack(struct sock *sk, struct sk_buff *skb)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->state == DN_CI) {
scp->state = DN_CD;
@@ -389,8 +385,8 @@ static void dn_nsp_conn_ack(struct sock *sk, struct sk_buff *skb)
static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb)
{
- struct dn_scp *scp = &sk->protinfo.dn;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_scp *scp = DN_SK(sk);
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
unsigned short reason;
if (skb->len < 2)
@@ -448,7 +444,7 @@ out:
*/
static void dn_nsp_disc_conf(struct sock *sk, struct sk_buff *skb)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
unsigned short reason;
if (skb->len != 2)
@@ -492,38 +488,65 @@ out:
static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_scp *scp = DN_SK(sk);
unsigned short segnum;
unsigned char lsflags;
char fcval;
+ int wake_up = 0;
+ char *ptr = skb->data;
+ unsigned char fctype = scp->services_rem & NSP_FC_MASK;
if (skb->len != 4)
goto out;
- cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data);
- skb_pull(skb, 2);
- lsflags = *(unsigned char *)skb->data;
- skb_pull(skb, 1);
- fcval = *(char *)skb->data;
+ segnum = dn_ntohs(*(__u16 *)ptr);
+ ptr += 2;
+ lsflags = *(unsigned char *)ptr++;
+ fcval = *ptr;
- if (lsflags & 0xf0)
+ /*
+ * Here we ignore erronous packets which should really
+ * should cause a connection abort. It is not critical
+ * for now though.
+ */
+ if (lsflags & 0xf8)
goto out;
- if (((sk->protinfo.dn.numoth_rcv + 1) & 0x0FFF) == (segnum & 0x0FFF)) {
- sk->protinfo.dn.numoth_rcv += 1;
- switch(lsflags & 0x03) {
- case 0x00:
- break;
- case 0x01:
- sk->protinfo.dn.flowrem_sw = DN_DONTSEND;
- break;
- case 0x02:
- sk->protinfo.dn.flowrem_sw = DN_SEND;
+ if (seq_next(scp->numoth_rcv, segnum)) {
+ seq_add(&scp->numoth_rcv, 1);
+ switch(lsflags & 0x04) { /* FCVAL INT */
+ case 0x00: /* Normal Request */
+ switch(lsflags & 0x03) { /* FCVAL MOD */
+ case 0x00: /* Request count */
+ if (fcval < 0) {
+ unsigned char p_fcval = -fcval;
+ if ((scp->flowrem_dat > p_fcval) &&
+ (fctype == NSP_FC_SCMC)) {
+ scp->flowrem_dat -= p_fcval;
+ }
+ } else if (fcval > 0) {
+ scp->flowrem_dat += fcval;
+ wake_up = 1;
+ }
+ break;
+ case 0x01: /* Stop outgoing data */
+ scp->flowrem_sw = DN_DONTSEND;
+ break;
+ case 0x02: /* Ok to start again */
+ scp->flowrem_sw = DN_SEND;
dn_nsp_output(sk);
- if (!sk->dead)
- sk->state_change(sk);
+ wake_up = 1;
+ }
+ break;
+ case 0x04: /* Interrupt Request */
+ if (fcval > 0) {
+ scp->flowrem_oth += fcval;
+ wake_up = 1;
+ }
+ break;
}
-
+ if (wake_up && !sk->dead)
+ sk->state_change(sk);
}
dn_nsp_send_oth_ack(sk);
@@ -582,9 +605,9 @@ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig
static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
unsigned short segnum;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
int queued = 0;
if (skb->len < 2)
@@ -593,10 +616,10 @@ static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb)
cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data);
skb_pull(skb, 2);
- if (((sk->protinfo.dn.numoth_rcv + 1) & 0x0fff) == (segnum & 0x0fff)) {
+ if (seq_next(scp->numoth_rcv, segnum)) {
if (dn_queue_skb(sk, skb, SIGURG, &scp->other_receive_queue) == 0) {
- sk->protinfo.dn.numoth_rcv++;
+ seq_add(&scp->numoth_rcv, 1);
scp->other_report = 0;
queued = 1;
}
@@ -612,8 +635,8 @@ static void dn_nsp_data(struct sock *sk, struct sk_buff *skb)
{
int queued = 0;
unsigned short segnum;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ struct dn_scp *scp = DN_SK(sk);
if (skb->len < 2)
goto out;
@@ -621,17 +644,15 @@ static void dn_nsp_data(struct sock *sk, struct sk_buff *skb)
cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data);
skb_pull(skb, 2);
- if (((sk->protinfo.dn.numdat_rcv + 1) & 0x0FFF) ==
- (segnum & 0x0FFF)) {
-
+ if (seq_next(scp->numdat_rcv, segnum)) {
if (dn_queue_skb(sk, skb, SIGIO, &sk->receive_queue) == 0) {
- sk->protinfo.dn.numdat_rcv++;
+ seq_add(&scp->numdat_rcv, 1);
queued = 1;
}
if ((scp->flowloc_sw == DN_SEND) && dn_congested(sk)) {
scp->flowloc_sw = DN_DONTSEND;
- dn_nsp_send_lnk(sk, DN_DONTSEND);
+ dn_nsp_send_link(sk, DN_DONTSEND, 0);
}
}
@@ -648,7 +669,7 @@ out:
*/
static void dn_returned_conn_init(struct sock *sk, struct sk_buff *skb)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->state == DN_CI) {
scp->state = DN_NC;
@@ -660,28 +681,37 @@ static void dn_returned_conn_init(struct sock *sk, struct sk_buff *skb)
kfree_skb(skb);
}
-static void dn_nsp_no_socket(struct sk_buff *skb, unsigned short reason)
+static int dn_nsp_no_socket(struct sk_buff *skb, unsigned short reason)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ int ret = NET_RX_DROP;
+
+ /* Must not reply to returned packets */
+ if (cb->rt_flags & DN_RT_F_RTS)
+ goto out;
if ((reason != NSP_REASON_OK) && ((cb->nsp_flags & 0x0c) == 0x08)) {
switch(cb->nsp_flags & 0x70) {
case 0x10:
case 0x60: /* (Retransmitted) Connect Init */
dn_nsp_return_disc(skb, NSP_DISCINIT, reason);
+ ret = NET_RX_SUCCESS;
break;
case 0x20: /* Connect Confirm */
dn_nsp_return_disc(skb, NSP_DISCCONF, reason);
+ ret = NET_RX_SUCCESS;
break;
}
}
+out:
kfree_skb(skb);
+ return ret;
}
static int dn_nsp_rx_packet(struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct sock *sk = NULL;
unsigned char *ptr = (unsigned char *)skb->data;
unsigned short reason = NSP_REASON_NL;
@@ -754,14 +784,19 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
sk = dn_find_by_skb(skb);
got_it:
if (sk != NULL) {
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int ret;
/* Reset backoff */
scp->nsp_rxtshift = 0;
bh_lock_sock(sk);
- ret = 0;
+ ret = NET_RX_SUCCESS;
+ if (decnet_debug_level & 8)
+ printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n",
+ (int)cb->rt_flags, (int)cb->nsp_flags,
+ (int)cb->src_port, (int)cb->dst_port,
+ (int)sk->lock.users);
if (sk->lock.users == 0)
ret = dn_nsp_backlog_rcv(sk, skb);
else
@@ -772,12 +807,11 @@ got_it:
return ret;
}
- dn_nsp_no_socket(skb, reason);
- return 1;
+ return dn_nsp_no_socket(skb, reason);
free_out:
kfree_skb(skb);
- return 0;
+ return NET_RX_DROP;
}
int dn_nsp_rx(struct sk_buff *skb)
@@ -792,12 +826,12 @@ int dn_nsp_rx(struct sk_buff *skb)
*/
int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{
- struct dn_scp *scp = &sk->protinfo.dn;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_scp *scp = DN_SK(sk);
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
if (cb->rt_flags & DN_RT_F_RTS) {
dn_returned_conn_init(sk, skb);
- return 0;
+ return NET_RX_SUCCESS;
}
/*
@@ -875,6 +909,6 @@ free_out:
}
}
- return 0;
+ return NET_RX_SUCCESS;
}
diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c
index 6965cbf42..5e8482ce0 100644
--- a/net/decnet/dn_nsp_out.c
+++ b/net/decnet/dn_nsp_out.c
@@ -20,6 +20,7 @@
* Steve Whitehouse: New output state machine
* Paul Koning: Connect Confirm message fix.
* Eduardo Serrat: Fix to stop dn_nsp_do_disc() sending malformed packets.
+ * Steve Whitehouse: dn_nsp_output() and friends needed a spring clean
*/
/******************************************************************************
@@ -165,7 +166,7 @@ struct sk_buff *dn_alloc_send_skb(struct sock *sk, int *size, int noblock, int *
*/
unsigned long dn_nsp_persist(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
@@ -188,7 +189,7 @@ unsigned long dn_nsp_persist(struct sock *sk)
*/
static void dn_nsp_rtt(struct sock *sk, long rtt)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
long srtt = (long)scp->nsp_srtt;
long rttvar = (long)scp->nsp_rttvar;
long delta;
@@ -223,65 +224,64 @@ static void dn_nsp_rtt(struct sock *sk, long rtt)
/* printk(KERN_DEBUG "srtt=%lu rttvar=%lu\n", scp->nsp_srtt, scp->nsp_rttvar); */
}
-/*
- * Walk the queues, otherdata/linkservice first. Send as many
- * frames as the window allows, increment send counts on all
- * skbs which are sent. Reduce the window if we are retransmitting
- * frames.
+/**
+ * dn_nsp_clone_and_send - Send a data packet by cloning it
+ * @skb: The packet to clone and transmit
+ * @gfp: memory allocation flag
+ *
+ * Clone a queued data or other data packet and transmit it.
+ *
+ * Returns: The number of times the packet has been sent previously
*/
-void dn_nsp_output(struct sock *sk)
+static inline unsigned dn_nsp_clone_and_send(struct sk_buff *skb, int gfp)
{
- struct dn_scp *scp = &sk->protinfo.dn;
- unsigned long win = scp->snd_window;
- struct sk_buff *skb, *skb2, *list;
- struct dn_skb_cb *cb;
- int reduce_win = 0;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ struct sk_buff *skb2;
+ int ret = 0;
- /* printk(KERN_DEBUG "dn_nsp_output: ping\n"); */
+ if ((skb2 = skb_clone(skb, gfp)) != NULL) {
+ ret = cb->xmit_count;
+ cb->xmit_count++;
+ cb->stamp = jiffies;
+ skb2->sk = skb->sk;
+ dn_nsp_send(skb2);
+ }
+
+ return ret;
+}
+
+/**
+ * dn_nsp_output - Try and send something from socket queues
+ * @sk: The socket whose queues are to be investigated
+ * @gfp: The memory allocation flags
+ *
+ * Try and send the packet on the end of the data and other data queues.
+ * Other data gets priority over data, and if we retransmit a packet we
+ * reduce the window by dividing it in two.
+ *
+ */
+void dn_nsp_output(struct sock *sk)
+{
+ struct dn_scp *scp = DN_SK(sk);
+ struct sk_buff *skb;
+ unsigned reduce_win = 0;
/*
* First we check for otherdata/linkservice messages
*/
- skb = scp->other_xmit_queue.next;
- list = (struct sk_buff *)&scp->other_xmit_queue;
- while(win && (skb != list)) {
- if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
- cb = (struct dn_skb_cb *)skb;
- if (cb->xmit_count > 0)
- reduce_win = 1;
- else
- cb->stamp = jiffies;
- cb->xmit_count++;
- skb2->sk = sk;
- dn_nsp_send(skb2);
- }
- skb = skb->next;
- win--;
- }
+ if ((skb = skb_peek(&scp->other_xmit_queue)) != NULL)
+ reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC);
/*
* If we may not send any data, we don't.
- * Should this apply to otherdata as well ? - SJW
+ * If we are still trying to get some other data down the
+ * channel, we don't try and send any data.
*/
- if (scp->flowrem_sw != DN_SEND)
+ if (reduce_win || (scp->flowrem_sw != DN_SEND))
goto recalc_window;
- skb = scp->data_xmit_queue.next;
- list = (struct sk_buff *)&scp->data_xmit_queue;
- while(win && (skb != list)) {
- if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
- cb = (struct dn_skb_cb *)skb;
- if (cb->xmit_count > 0)
- reduce_win = 1;
- else
- cb->stamp = jiffies;
- cb->xmit_count++;
- skb2->sk = sk;
- dn_nsp_send(skb2);
- }
- skb = skb->next;
- win--;
- }
+ if ((skb = skb_peek(&scp->data_xmit_queue)) != NULL)
+ reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC);
/*
* If we've sent any frame more than once, we cut the
@@ -290,7 +290,6 @@ void dn_nsp_output(struct sock *sk)
*/
recalc_window:
if (reduce_win) {
- /* printk(KERN_DEBUG "Window reduction %ld\n", scp->snd_window); */
scp->snd_window >>= 1;
if (scp->snd_window < NSP_MIN_WINDOW)
scp->snd_window = NSP_MIN_WINDOW;
@@ -299,7 +298,7 @@ recalc_window:
int dn_nsp_xmit_timeout(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
dn_nsp_output(sk);
@@ -309,14 +308,60 @@ int dn_nsp_xmit_timeout(struct sock *sk)
return 0;
}
-void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int oth)
+static inline unsigned char *dn_mk_common_header(struct dn_scp *scp, struct sk_buff *skb, unsigned char msgflag, int len)
+{
+ unsigned char *ptr = skb_push(skb, len);
+
+ if (len < 5)
+ BUG();
+
+ *ptr++ = msgflag;
+ *((unsigned short *)ptr) = scp->addrrem;
+ ptr += 2;
+ *((unsigned short *)ptr) = scp->addrloc;
+ ptr += 2;
+ return ptr;
+}
+
+static unsigned short *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, unsigned char msgflag, int hlen, int other)
+{
+ struct dn_scp *scp = DN_SK(sk);
+ unsigned short acknum = scp->numdat_rcv & 0x0FFF;
+ unsigned short ackcrs = scp->numoth_rcv & 0x0FFF;
+ unsigned short *ptr;
+
+ if (hlen < 9)
+ BUG();
+
+ scp->ackxmt_dat = acknum;
+ scp->ackxmt_oth = ackcrs;
+ acknum |= 0x8000;
+ ackcrs |= 0x8000;
+
+ /* If this is an "other data/ack" message, swap acknum and ackcrs */
+ if (other) {
+ unsigned short tmp = acknum;
+ acknum = ackcrs;
+ ackcrs = tmp;
+ }
+
+ /* Set "cross subchannel" bit in ackcrs */
+ ackcrs |= 0x2000;
+
+ ptr = (unsigned short *)dn_mk_common_header(scp, skb, msgflag, hlen);
+
+ *ptr++ = dn_htons(acknum);
+ *ptr++ = dn_htons(ackcrs);
+
+ return ptr;
+}
+
+void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oth)
{
- struct dn_scp *scp = &sk->protinfo.dn;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_scp *scp = DN_SK(sk);
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1;
- struct sk_buff *skb2;
- if (t < HZ) t = HZ;
/*
* Slow start: If we have been idle for more than
* one RTT, then reset window to min size.
@@ -336,20 +381,17 @@ void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int oth)
if (scp->flowrem_sw != DN_SEND)
return;
- if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
- cb->stamp = jiffies;
- cb->xmit_count++;
- skb2->sk = sk;
- dn_nsp_send(skb2);
- }
+ dn_nsp_clone_and_send(skb, gfp);
}
+
int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ struct dn_scp *scp = DN_SK(sk);
struct sk_buff *skb2, *list, *ack = NULL;
int wakeup = 0;
+ int try_retrans = 0;
unsigned long reftime = cb->stamp;
unsigned long pkttime;
unsigned short xmit_count;
@@ -358,7 +400,7 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
skb2 = q->next;
list = (struct sk_buff *)q;
while(list != skb2) {
- struct dn_skb_cb *cb2 = (struct dn_skb_cb *)skb2->cb;
+ struct dn_skb_cb *cb2 = DN_SKB_CB(skb2);
if (before_or_equal(cb2->segnum, acknum))
ack = skb2;
@@ -372,27 +414,50 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
/* printk(KERN_DEBUG "check_xmit_queue: %04x, %d\n", acknum, cb2->xmit_count); */
+ /* Does _last_ packet acked have xmit_count > 1 */
+ try_retrans = 0;
+ /* Remember to wake up the sending process */
wakeup = 1;
+ /* Keep various statistics */
pkttime = cb2->stamp;
xmit_count = cb2->xmit_count;
segnum = cb2->segnum;
+ /* Remove and drop ack'ed packet */
skb_unlink(ack);
kfree_skb(ack);
ack = NULL;
+
+ /*
+ * We don't expect to see acknowledgements for packets we
+ * haven't sent yet.
+ */
+ if (xmit_count == 0)
+ BUG();
+ /*
+ * If the packet has only been sent once, we can use it
+ * to calculate the RTT and also open the window a little
+ * further.
+ */
if (xmit_count == 1) {
if (equal(segnum, acknum))
dn_nsp_rtt(sk, (long)(pkttime - reftime));
- if (scp->snd_window < NSP_MAX_WINDOW)
+ if (scp->snd_window < scp->max_window)
scp->snd_window++;
}
+
+ /*
+ * Packet has been sent more than once. If this is the last
+ * packet to be acknowledged then we want to send the next
+ * packet in the send queue again (assumes the remote host does
+ * go-back-N error control).
+ */
+ if (xmit_count > 1)
+ try_retrans = 1;
}
-#if 0 /* Turned off due to possible interference in socket shutdown */
- if ((skb_queue_len(&scp->data_xmit_queue) == 0) &&
- (skb_queue_len(&scp->other_xmit_queue) == 0))
- scp->persist = 0;
-#endif
+ if (try_retrans)
+ dn_nsp_output(sk);
return wakeup;
}
@@ -400,47 +465,31 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
void dn_nsp_send_data_ack(struct sock *sk)
{
struct sk_buff *skb = NULL;
- struct nsp_data_ack_msg *msg;
- if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL)
+ if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)
return;
-
- msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg));
-
- msg->msgflg = 0x04; /* data ack message */
- msg->dstaddr = sk->protinfo.dn.addrrem;
- msg->srcaddr = sk->protinfo.dn.addrloc;
- msg->acknum = dn_htons((sk->protinfo.dn.numdat_rcv & 0x0FFF) | 0x8000);
-
- sk->protinfo.dn.ackxmt_dat = sk->protinfo.dn.numdat_rcv;
+ skb_reserve(skb, 9);
+ dn_mk_ack_header(sk, skb, 0x04, 9, 0);
dn_nsp_send(skb);
}
void dn_nsp_send_oth_ack(struct sock *sk)
{
struct sk_buff *skb = NULL;
- struct nsp_data_ack_msg *msg;
- if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL)
+ if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL)
return;
-
- msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg));
-
- msg->msgflg = 0x14; /* oth ack message */
- msg->dstaddr = sk->protinfo.dn.addrrem;
- msg->srcaddr = sk->protinfo.dn.addrloc;
- msg->acknum = dn_htons((sk->protinfo.dn.numoth_rcv & 0x0FFF) | 0x8000);
-
- sk->protinfo.dn.ackxmt_oth = sk->protinfo.dn.numoth_rcv;
+ skb_reserve(skb, 9);
+ dn_mk_ack_header(sk, skb, 0x14, 9, 1);
dn_nsp_send(skb);
}
void dn_send_conn_ack (struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct sk_buff *skb = NULL;
struct nsp_conn_ack_msg *msg;
@@ -456,7 +505,7 @@ void dn_send_conn_ack (struct sock *sk)
void dn_nsp_delayed_ack(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->ackxmt_oth != scp->numoth_rcv)
dn_nsp_send_oth_ack(sk);
@@ -467,7 +516,7 @@ void dn_nsp_delayed_ack(struct sock *sk)
static int dn_nsp_retrans_conn_conf(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->state == DN_CC)
dn_send_conn_conf(sk, GFP_ATOMIC);
@@ -477,7 +526,7 @@ static int dn_nsp_retrans_conn_conf(struct sock *sk)
void dn_send_conn_conf(struct sock *sk, int gfp)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct sk_buff *skb = NULL;
struct nsp_conn_init_msg *msg;
unsigned char len = scp->conndata_out.opt_optl;
@@ -489,9 +538,9 @@ void dn_send_conn_conf(struct sock *sk, int gfp)
msg->msgflg = 0x28;
msg->dstaddr = scp->addrrem;
msg->srcaddr = scp->addrloc;
- msg->services = 0x01;
- msg->info = 0x03;
- msg->segsize = dn_htons(0x05B3);
+ msg->services = scp->services_loc;
+ msg->info = scp->info_loc;
+ msg->segsize = dn_htons(scp->segsize_loc);
*skb_put(skb,1) = len;
@@ -551,7 +600,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg,
unsigned short reason, int gfp)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
int ddl = 0;
if (msgflg == NSP_DISCINIT)
@@ -568,7 +617,7 @@ void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg,
void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg,
unsigned short reason)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
int ddl = 0;
int gfp = GFP_ATOMIC;
@@ -577,38 +626,35 @@ void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg,
}
-void dn_nsp_send_lnk(struct sock *sk, unsigned short flgs)
+void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval)
{
- struct dn_scp *scp = &sk->protinfo.dn;
- struct sk_buff *skb = NULL;
- struct nsp_data_seg_msg *msg;
- struct nsp_data_opt_msg *msg1;
- struct dn_skb_cb *cb;
+ struct dn_scp *scp = DN_SK(sk);
+ struct sk_buff *skb;
+ unsigned short *segnum;
+ unsigned char *ptr;
+ int gfp = GFP_ATOMIC;
- if ((skb = dn_alloc_skb(sk, 80, GFP_ATOMIC)) == NULL)
+ if ((skb = dn_alloc_skb(sk, 13, gfp)) == NULL)
return;
- cb = (struct dn_skb_cb *)skb->cb;
- msg = (struct nsp_data_seg_msg *)skb_put(skb, sizeof(*msg));
- msg->msgflg = 0x10; /* Link svc message */
- msg->dstaddr = scp->addrrem;
- msg->srcaddr = scp->addrloc;
+ skb_reserve(skb, 13);
+ segnum = dn_mk_ack_header(sk, skb, 0x10, 13, 1);
+ *segnum = dn_htons(scp->numoth);
+ DN_SKB_CB(skb)->segnum = scp->numoth;
+ seq_add(&scp->numoth, 1);
+ ptr = (unsigned char *)(segnum + 1);
+ *ptr++ = lsflags;
+ *ptr = fcval;
- msg1 = (struct nsp_data_opt_msg *)skb_put(skb, sizeof(*msg1));
- msg1->acknum = dn_htons((scp->ackxmt_oth & 0x0FFF) | 0x8000);
- msg1->segnum = dn_htons(cb->segnum = (scp->numoth++ & 0x0FFF));
- msg1->lsflgs = flgs;
-
- dn_nsp_queue_xmit(sk, skb, 1);
+ dn_nsp_queue_xmit(sk, skb, gfp, 1);
scp->persist = dn_nsp_persist(sk);
scp->persist_fxn = dn_nsp_xmit_timeout;
-
}
static int dn_nsp_retrans_conninit(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->state == DN_CI)
dn_nsp_send_conninit(sk, NSP_RCI);
@@ -618,7 +664,7 @@ static int dn_nsp_retrans_conninit(struct sock *sk)
void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
struct sk_buff *skb = NULL;
struct nsp_conn_init_msg *msg;
unsigned char aux;
@@ -629,16 +675,16 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
if ((skb = dn_alloc_skb(sk, 200, (msgflg == NSP_CI) ? sk->allocation : GFP_ATOMIC)) == NULL)
return;
- cb = (struct dn_skb_cb *)skb->cb;
+ cb = DN_SKB_CB(skb);
msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg));
msg->msgflg = msgflg;
msg->dstaddr = 0x0000; /* Remote Node will assign it*/
- msg->srcaddr = sk->protinfo.dn.addrloc;
- msg->services = 1 | NSP_FC_NONE; /* Requested flow control */
- msg->info = 0x03; /* Version Number */
- msg->segsize = dn_htons(1459); /* Max segment size */
+ msg->srcaddr = scp->addrloc;
+ msg->services = scp->services_loc; /* Requested flow control */
+ msg->info = scp->info_loc; /* Version Number */
+ msg->segsize = dn_htons(scp->segsize_loc); /* Max segment size */
if (scp->peer.sdn_objnum)
type = 0;
@@ -674,8 +720,8 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg)
if (aux > 0)
memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux);
- sk->protinfo.dn.persist = dn_nsp_persist(sk);
- sk->protinfo.dn.persist_fxn = dn_nsp_retrans_conninit;
+ scp->persist = dn_nsp_persist(sk);
+ scp->persist_fxn = dn_nsp_retrans_conninit;
cb->rt_flags = DN_RT_F_RQR;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 70646fc11..b40c601b6 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -33,6 +33,9 @@
* Steve Whitehouse : Real SMP at last :-) Also new netfilter
* stuff. Look out raw sockets your days
* are numbered!
+ * Steve Whitehouse : Added return-to-sender functions. Added
+ * backlog congestion level return codes.
+ *
*/
/******************************************************************************
@@ -109,17 +112,16 @@ static struct timer_list dn_rt_flush_timer = { function: dn_run_flush };
int decnet_dst_gc_interval = 2;
static struct dst_ops dn_dst_ops = {
- PF_DECnet,
- __constant_htons(ETH_P_DNA_RT),
- 128,
- dn_dst_gc,
- dn_dst_check,
- dn_dst_reroute,
- NULL,
- dn_dst_negative_advice,
- dn_dst_link_failure,
- sizeof(struct dn_route),
- ATOMIC_INIT(0)
+ family: PF_DECnet,
+ protocol: __constant_htons(ETH_P_DNA_RT),
+ gc_thresh: 128,
+ gc: dn_dst_gc,
+ check: dn_dst_check,
+ reroute: dn_dst_reroute,
+ negative_advice: dn_dst_negative_advice,
+ link_failure: dn_dst_link_failure,
+ entry_size: sizeof(struct dn_route),
+ entries: ATOMIC_INIT(0),
};
static __inline__ unsigned dn_hash(unsigned short src, unsigned short dst)
@@ -294,21 +296,131 @@ void dn_rt_cache_flush(int delay)
spin_unlock_bh(&dn_rt_flush_lock);
}
+/**
+ * dn_return_short - Return a short packet to its sender
+ * @skb: The packet to return
+ *
+ */
+static int dn_return_short(struct sk_buff *skb)
+{
+ struct dn_skb_cb *cb;
+ unsigned char *ptr;
+ dn_address *src;
+ dn_address *dst;
+ dn_address tmp;
+
+ /* Add back headers */
+ skb_push(skb, skb->data - skb->nh.raw);
+
+ if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
+ return NET_RX_DROP;
+
+ cb = DN_SKB_CB(skb);
+ /* Skip packet length and point to flags */
+ ptr = skb->data + 2;
+ *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS;
+
+ dst = (dn_address *)ptr;
+ ptr += 2;
+ src = (dn_address *)ptr;
+ ptr += 2;
+ *ptr = 0; /* Zero hop count */
+
+ /* Swap source and destination */
+ tmp = *src;
+ *src = *dst;
+ *dst = tmp;
+
+ skb->pkt_type = PACKET_OUTGOING;
+ dn_rt_finish_output(skb, NULL);
+ return NET_RX_SUCCESS;
+}
+
+/**
+ * dn_return_long - Return a long packet to its sender
+ * @skb: The long format packet to return
+ *
+ */
+static int dn_return_long(struct sk_buff *skb)
+{
+ struct dn_skb_cb *cb;
+ unsigned char *ptr;
+ unsigned char *src_addr, *dst_addr;
+ unsigned char tmp[ETH_ALEN];
+
+ /* Add back all headers */
+ skb_push(skb, skb->data - skb->nh.raw);
+
+ if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL)
+ return NET_RX_DROP;
+ cb = DN_SKB_CB(skb);
+ /* Ignore packet length and point to flags */
+ ptr = skb->data + 2;
+
+ /* Skip padding */
+ if (*ptr & DN_RT_F_PF) {
+ char padlen = (*ptr & ~DN_RT_F_PF);
+ ptr += padlen;
+ }
+
+ *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS;
+ ptr += 2;
+ dst_addr = ptr;
+ ptr += 8;
+ src_addr = ptr;
+ ptr += 6;
+ *ptr = 0; /* Zero hop count */
+
+ /* Swap source and destination */
+ memcpy(tmp, src_addr, ETH_ALEN);
+ memcpy(src_addr, dst_addr, ETH_ALEN);
+ memcpy(dst_addr, tmp, ETH_ALEN);
+
+ skb->pkt_type = PACKET_OUTGOING;
+ dn_rt_finish_output(skb, tmp);
+ return NET_RX_SUCCESS;
+}
+
+/**
+ * dn_route_rx_packet - Try and find a route for an incoming packet
+ * @skb: The packet to find a route for
+ *
+ * Returns: result of input function if route is found, error code otherwise
+ */
static int dn_route_rx_packet(struct sk_buff *skb)
{
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
int err;
if ((err = dn_route_input(skb)) == 0)
return skb->dst->input(skb);
+ if (decnet_debug_level & 4) {
+ char *devname = skb->dev ? skb->dev->name : "???";
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
+ printk(KERN_DEBUG
+ "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n",
+ (int)cb->rt_flags, devname, skb->len, cb->src, cb->dst,
+ err, skb->pkt_type);
+ }
+
+ if ((skb->pkt_type == PACKET_HOST) && (cb->rt_flags & DN_RT_F_RQR)) {
+ switch(cb->rt_flags & DN_RT_PKT_MSK) {
+ case DN_RT_PKT_SHORT:
+ return dn_return_short(skb);
+ case DN_RT_PKT_LONG:
+ return dn_return_long(skb);
+ }
+ }
+
kfree_skb(skb);
- return err;
+ return NET_RX_DROP;
}
static int dn_route_rx_long(struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
unsigned char *ptr = skb->data;
if (skb->len < 21) /* 20 for long header, 1 for shortest nsp */
@@ -339,14 +451,14 @@ static int dn_route_rx_long(struct sk_buff *skb)
drop_it:
kfree_skb(skb);
- return 0;
+ return NET_RX_DROP;
}
static int dn_route_rx_short(struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
unsigned char *ptr = skb->data;
if (skb->len < 6) /* 5 for short header + 1 for shortest nsp */
@@ -365,29 +477,33 @@ static int dn_route_rx_short(struct sk_buff *skb)
drop_it:
kfree_skb(skb);
- return 0;
+ return NET_RX_DROP;
}
static int dn_route_discard(struct sk_buff *skb)
{
+ /*
+ * I know we drop the packet here, but thats considered success in
+ * this case
+ */
kfree_skb(skb);
- return 0;
+ return NET_RX_SUCCESS;
}
static int dn_route_ptp_hello(struct sk_buff *skb)
{
dn_dev_hello(skb);
dn_neigh_pointopoint_hello(skb);
- return 0;
+ return NET_RX_SUCCESS;
}
int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
{
struct dn_skb_cb *cb;
unsigned char flags = 0;
- int padlen = 0;
__u16 len = dn_ntohs(*(__u16 *)skb->data);
struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr;
+ unsigned char padlen = 0;
if (dn == NULL)
goto dump_it;
@@ -404,7 +520,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
flags = *skb->data;
- cb = (struct dn_skb_cb *)skb->cb;
+ cb = DN_SKB_CB(skb);
cb->stamp = jiffies;
cb->iif = dev->ifindex;
@@ -448,20 +564,16 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
switch(flags & DN_RT_CNTL_MSK) {
case DN_RT_PKT_HELO:
- NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello);
- goto out;
+ return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello);
case DN_RT_PKT_L1RT:
case DN_RT_PKT_L2RT:
- NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard);
- goto out;
+ return NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard);
case DN_RT_PKT_ERTH:
- NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello);
- goto out;
+ return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello);
case DN_RT_PKT_EEDH:
- NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello);
- goto out;
+ return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello);
}
} else {
if (dn->parms.state != DN_DEV_S_RU)
@@ -480,7 +592,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
dump_it:
kfree_skb(skb);
out:
- return 0;
+ return NET_RX_DROP;
}
static int dn_output(struct sk_buff *skb)
@@ -488,7 +600,7 @@ static int dn_output(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
struct dn_route *rt = (struct dn_route *)dst;
struct net_device *dev = dst->dev;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct neighbour *neigh;
int err = -EINVAL;
@@ -524,7 +636,7 @@ error:
#ifdef CONFIG_DECNET_ROUTER
static int dn_forward(struct sk_buff *skb)
{
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct dst_entry *dst = skb->dst;
struct net_device *dev = skb->dev;
struct neighbour *neigh;
@@ -536,7 +648,7 @@ static int dn_forward(struct sk_buff *skb)
/*
* Hop count exceeded.
*/
- err = 0;
+ err = NET_RX_DROP;
if (++cb->hops > 30)
goto drop;
@@ -573,7 +685,7 @@ drop:
static int dn_blackhole(struct sk_buff *skb)
{
kfree_skb(skb);
- return 0;
+ return NET_RX_DROP;
}
/*
@@ -583,7 +695,7 @@ static int dn_blackhole(struct sk_buff *skb)
static int dn_rt_bug(struct sk_buff *skb)
{
if (net_ratelimit()) {
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
printk(KERN_DEBUG "dn_rt_bug: skb from:%04x to:%04x\n",
cb->src, cb->dst);
@@ -591,7 +703,7 @@ static int dn_rt_bug(struct sk_buff *skb)
kfree_skb(skb);
- return -EINVAL;
+ return NET_RX_BAD;
}
static int dn_route_output_slow(struct dst_entry **pprt, dn_address dst, dn_address src, int flags)
@@ -732,7 +844,7 @@ int dn_route_output(struct dst_entry **pprt, dn_address dst, dn_address src, int
static int dn_route_input_slow(struct sk_buff *skb)
{
struct dn_route *rt = NULL;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct net_device *dev = skb->dev;
struct dn_dev *dn_db;
struct neighbour *neigh = NULL;
@@ -880,7 +992,7 @@ add_entry:
int dn_route_input(struct sk_buff *skb)
{
struct dn_route *rt;
- struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
+ struct dn_skb_cb *cb = DN_SKB_CB(skb);
unsigned hash = dn_hash(cb->src, cb->dst);
if (skb->dst)
@@ -964,7 +1076,7 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
if (skb == NULL)
return -ENOBUFS;
skb->mac.raw = skb->data;
- cb = (struct dn_skb_cb *)skb->cb;
+ cb = DN_SKB_CB(skb);
if (rta[RTA_SRC-1])
memcpy(&src, RTA_DATA(rta[RTA_SRC-1]), 2);
@@ -1185,8 +1297,6 @@ void __exit dn_route_cleanup(void)
del_timer(&dn_route_timer);
dn_run_flush(0);
-#ifdef CONFIG_PROC_FS
proc_net_remove("decnet_cache");
-#endif /* CONFIG_PROC_FS */
}
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 133591f0b..32adfecba 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -57,7 +57,12 @@ struct dn_fib_rule
int r_dead;
};
-static struct dn_fib_rule default_rule = { NULL, ATOMIC_INIT(2), 0x7fff, DN_DEFAULT_TABLE, RTN_UNICAST };
+static struct dn_fib_rule default_rule = {
+ r_clntref: ATOMIC_INIT(2),
+ r_preference: 0x7fff,
+ r_table: DN_DEFAULT_TABLE,
+ r_action: RTN_UNICAST
+};
static struct dn_fib_rule *dn_fib_rules = &default_rule;
static rwlock_t dn_fib_rules_lock = RW_LOCK_UNLOCKED;
@@ -291,9 +296,7 @@ static int dn_fib_rules_event(struct notifier_block *this, unsigned long event,
static struct notifier_block dn_fib_rules_notifier = {
- dn_fib_rules_event,
- NULL,
- 0
+ notifier_call: dn_fib_rules_event,
};
#ifdef CONFIG_RTNETLINK
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index ce7a3ac06..bc21acb4b 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -78,7 +78,7 @@ static rwlock_t dn_fib_tables_lock = RW_LOCK_UNLOCKED;
static struct dn_fib_table *dn_fib_tables[DN_NUM_TABLES + 1];
static kmem_cache_t *dn_hash_kmem;
-static int dn_fib_hash_zombies = 0;
+static int dn_fib_hash_zombies;
static __inline__ dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz)
{
diff --git a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c
index bbba58b02..41a4aa602 100644
--- a/net/decnet/dn_timer.c
+++ b/net/decnet/dn_timer.c
@@ -52,7 +52,7 @@ void dn_stop_slow_timer(struct sock *sk)
static void dn_slow_timer(unsigned long arg)
{
struct sock *sk = (struct sock *)arg;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
sock_hold(sk);
bh_lock_sock(sk);
@@ -112,7 +112,7 @@ out:
static void dn_fast_timer(unsigned long arg)
{
struct sock *sk = (struct sock *)arg;
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
bh_lock_sock(sk);
if (sk->lock.users != 0) {
@@ -131,7 +131,7 @@ out:
void dn_start_fast_timer(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (!scp->delack_pending) {
scp->delack_pending = 1;
@@ -145,7 +145,7 @@ void dn_start_fast_timer(struct sock *sk)
void dn_stop_fast_timer(struct sock *sk)
{
- struct dn_scp *scp = &sk->protinfo.dn;
+ struct dn_scp *scp = DN_SK(sk);
if (scp->delack_pending) {
scp->delack_pending = 0;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 1d8002bdd..81fae9233 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -504,8 +504,8 @@ void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
im->timer.function=&igmp_timer_expire;
im->unsolicit_count = IGMP_Unsolicited_Report_Count;
im->reporter = 0;
- im->loaded = 0;
#endif
+ im->loaded = 0;
write_lock_bh(&in_dev->lock);
im->next=in_dev->mc_list;
in_dev->mc_list=im;
diff --git a/net/ipv4/netfilter/Config.in b/net/ipv4/netfilter/Config.in
index 406d2ea3d..5887658fb 100644
--- a/net/ipv4/netfilter/Config.in
+++ b/net/ipv4/netfilter/Config.in
@@ -37,11 +37,20 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
fi
if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
- dep_tristate ' Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES
+ dep_tristate ' Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES $CONFIG_IP_NF_CONNTRACK
if [ "$CONFIG_IP_NF_NAT" != "n" ]; then
define_bool CONFIG_IP_NF_NAT_NEEDED y
dep_tristate ' MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT
dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT
+ # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y),
+ # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh.
+ if [ "$CONFIG_IP_NF_FTP" = "m" ]; then
+ define_tristate CONFIG_IP_NF_NAT_FTP m
+ else
+ if [ "$CONFIG_IP_NF_FTP" = "y" ]; then
+ define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT
+ fi
+ fi
fi
fi
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 995860767..c40caa75e 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
# NAT helpers
-obj-$(CONFIG_IP_NF_FTP) += ip_nat_ftp.o
+obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
# generic IP tables
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 2e4dd82ee..bc7e64c8b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -882,10 +882,15 @@ ip_ct_gather_frags(struct sk_buff *skb)
#ifdef CONFIG_NETFILTER_DEBUG
unsigned int olddebug = skb->nf_debug;
#endif
- if (sk) sock_hold(sk);
+ if (sk) {
+ sock_hold(sk);
+ skb_orphan(skb);
+ }
+
local_bh_disable();
skb = ip_defrag(skb);
- local_bh_enable();
+ local_bh_enable();
+
if (!skb) {
if (sk) sock_put(sk);
return skb;
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 9ba62dc84..cc19e1f0b 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -438,8 +438,27 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple,
conntrack));
ret = 1;
goto clear_fulls;
+ } else if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) {
+ /* Try implicit source NAT; protocol
+ may be able to play with ports to
+ make it unique. */
+ struct ip_nat_range r
+ = { IP_NAT_RANGE_MAP_IPS,
+ tuple->src.ip, tuple->src.ip,
+ { 0 }, { 0 } };
+ DEBUGP("Trying implicit mapping\n");
+ if (proto->unique_tuple(tuple, &r,
+ IP_NAT_MANIP_SRC,
+ conntrack)) {
+ /* Must be unique. */
+ IP_NF_ASSERT(!ip_nat_used_tuple
+ (tuple, conntrack));
+ ret = 1;
+ goto clear_fulls;
+ }
}
- DEBUGP("Protocol can't get unique tuple.\n");
+ DEBUGP("Protocol can't get unique tuple %u.\n",
+ hooknum);
}
/* Eliminate that from range, and try again. */
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 99164a7a0..f2a19702d 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -1,5 +1,6 @@
/* Masquerade. Simple mapping which alters range to a local IP address
(depending on route). */
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/ip.h>
#include <linux/timer.h>
@@ -68,6 +69,7 @@ masquerade_target(struct sk_buff **pskb,
struct ip_nat_multi_range newrange;
u_int32_t newsrc;
struct rtable *rt;
+ struct rt_key key;
IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
@@ -82,10 +84,14 @@ masquerade_target(struct sk_buff **pskb,
mr = targinfo;
- if (ip_route_output(&rt, (*pskb)->nh.iph->daddr,
- 0,
- RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN,
- out->ifindex) != 0) {
+ key.dst = (*pskb)->nh.iph->daddr;
+ key.src = 0; /* Unknown: that's what we're trying to establish */
+ key.tos = RT_TOS((*pskb)->nh.iph->tos)|RTO_CONN;
+ key.oif = out->ifindex;
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ key.fwmark = (*pskb)->nfmark;
+#endif
+ if (ip_route_output_key(&rt, &key) != 0) {
/* Shouldn't happen */
printk("MASQUERADE: No route: Rusty's brain broke!\n");
return NF_DROP;
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 9c1088e76..cc5ffbc4a 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -167,27 +167,9 @@ static unsigned int reject(struct sk_buff **pskb,
case IPT_ICMP_HOST_PROHIBITED:
icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0);
break;
- case IPT_ICMP_ECHOREPLY: {
- struct icmphdr *icmph = (struct icmphdr *)
- ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl);
- unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;
-
- /* Not non-head frags, or truncated */
- if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0)
- && datalen >= 4) {
- /* Usually I don't like cut & pasting code,
- but dammit, my party is starting in 45
- mins! --RR */
- struct icmp_bxm icmp_param;
-
- icmp_param.icmph=*icmph;
- icmp_param.icmph.type=ICMP_ECHOREPLY;
- icmp_param.data_ptr=(icmph+1);
- icmp_param.data_len=datalen;
- icmp_reply(&icmp_param, *pskb);
- }
- }
- break;
+ case IPT_ICMP_ECHOREPLY:
+ printk("REJECT: ECHOREPLY no longer supported.\n");
+ break;
case IPT_TCP_RESET:
send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
break;
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index c52ada64e..60d4698fb 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -53,7 +53,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_standard),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_standard_target), "" } }, { } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 } },
/* LOCAL_OUT */
{ { { { 0 }, { 0 }, { 0 }, { 0 }, "", "", { 0 }, { 0 }, 0, 0, 0 },
@@ -61,7 +61,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_standard),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_standard_target), "" } }, { } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_standard_target)), "" } }, { } },
-NF_ACCEPT - 1 } }
},
/* ERROR */
@@ -70,7 +70,7 @@ static struct
sizeof(struct ipt_entry),
sizeof(struct ipt_error),
0, { 0, 0 }, { } },
- { { { { sizeof(struct ipt_error_target), IPT_ERROR_TARGET } },
+ { { { { IPT_ALIGN(sizeof(struct ipt_error_target)), IPT_ERROR_TARGET } },
{ } },
"ERROR"
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index b370fcdf9..6660e0f72 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -954,7 +954,7 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
*/
skb = sk->write_queue.prev;
if (tp->send_head &&
- (mss_now - skb->len) > 0) {
+ (mss_now > skb->len)) {
copy = skb->len;
if (skb_tailroom(skb) > 0) {
int last_byte_was_odd = (copy % 4);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 4e3eab087..a3f83272b 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1705,7 +1705,7 @@ static __inline__ void tcp_ack_packets_out(struct sock *sk, struct tcp_opt *tp)
if ((__s32)when < (__s32)tp->rttvar)
when = tp->rttvar;
- tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, when);
+ tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, min(when, TCP_RTO_MAX));
}
}
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index aec5db879..fcc9bc058 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o
obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o
obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
+obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o
include $(TOPDIR)/Rules.make
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 57430f29f..659bb3a1e 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -11,7 +11,7 @@
#include <linux/module.h>
#include <linux/tcp.h>
#include <linux/udp.h>
-#include <linux/icmp.h>
+#include <linux/icmpv6.h>
#include <net/ip.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
@@ -1642,7 +1642,7 @@ udp_checkentry(const char *tablename,
/* Returns 1 if the type and code is matched by the range, 0 otherwise */
static inline int
-icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
+icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
u_int8_t type, u_int8_t code,
int invert)
{
@@ -1651,7 +1651,7 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
}
static int
-icmp_match(const struct sk_buff *skb,
+icmp6_match(const struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
const void *matchinfo,
@@ -1660,7 +1660,7 @@ icmp_match(const struct sk_buff *skb,
u_int16_t datalen,
int *hotdrop)
{
- const struct icmphdr *icmp = hdr;
+ const struct icmp6hdr *icmp = hdr;
const struct ip6t_icmp *icmpinfo = matchinfo;
if (offset == 0 && datalen < 2) {
@@ -1673,16 +1673,16 @@ icmp_match(const struct sk_buff *skb,
/* Must not be a fragment. */
return !offset
- && icmp_type_code_match(icmpinfo->type,
+ && icmp6_type_code_match(icmpinfo->type,
icmpinfo->code[0],
icmpinfo->code[1],
- icmp->type, icmp->code,
+ icmp->icmp6_type, icmp->icmp6_code,
!!(icmpinfo->invflags&IP6T_ICMP_INV));
}
/* Called when user tries to insert an entry of this type. */
static int
-icmp_checkentry(const char *tablename,
+icmp6_checkentry(const char *tablename,
const struct ip6t_ip6 *ipv6,
void *matchinfo,
unsigned int matchsize,
@@ -1691,7 +1691,7 @@ icmp_checkentry(const char *tablename,
const struct ip6t_icmp *icmpinfo = matchinfo;
/* Must specify proto == ICMP, and no unknown invflags */
- return ipv6->proto == IPPROTO_ICMP
+ return ipv6->proto == IPPROTO_ICMPV6
&& !(ipv6->invflags & IP6T_INV_PROTO)
&& matchsize == IP6T_ALIGN(sizeof(struct ip6t_icmp))
&& !(icmpinfo->invflags & ~IP6T_ICMP_INV);
@@ -1711,8 +1711,8 @@ static struct ip6t_match tcp_matchstruct
= { { NULL, NULL }, "tcp", &tcp_match, &tcp_checkentry, NULL };
static struct ip6t_match udp_matchstruct
= { { NULL, NULL }, "udp", &udp_match, &udp_checkentry, NULL };
-static struct ip6t_match icmp_matchstruct
-= { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL };
+static struct ip6t_match icmp6_matchstruct
+= { { NULL, NULL }, "icmp6", &icmp6_match, &icmp6_checkentry, NULL };
#ifdef CONFIG_PROC_FS
static inline int print_name(const struct ip6t_table *t,
@@ -1761,7 +1761,7 @@ static int __init init(void)
list_append(&ip6t_target, &ip6t_error_target);
list_append(&ip6t_match, &tcp_matchstruct);
list_append(&ip6t_match, &udp_matchstruct);
- list_append(&ip6t_match, &icmp_matchstruct);
+ list_append(&ip6t_match, &icmp6_matchstruct);
up(&ip6t_mutex);
/* Register setsockopt */
diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c
index dd8bb3226..08df336e8 100644
--- a/net/ipv6/netfilter/ip6t_MARK.c
+++ b/net/ipv6/netfilter/ip6t_MARK.c
@@ -4,8 +4,8 @@
#include <linux/ip.h>
#include <net/checksum.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ipt_MARK.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <linux/netfilter_ipv6/ip6t_MARK.h>
static unsigned int
target(struct sk_buff **pskb,
@@ -15,26 +15,26 @@ target(struct sk_buff **pskb,
const void *targinfo,
void *userinfo)
{
- const struct ipt_mark_target_info *markinfo = targinfo;
+ const struct ip6t_mark_target_info *markinfo = targinfo;
if((*pskb)->nfmark != markinfo->mark) {
(*pskb)->nfmark = markinfo->mark;
(*pskb)->nfcache |= NFC_ALTERED;
}
- return IPT_CONTINUE;
+ return IP6T_CONTINUE;
}
static int
checkentry(const char *tablename,
- const struct ipt_entry *e,
+ const struct ip6t_entry *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
- if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) {
+ if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) {
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
targinfosize,
- IPT_ALIGN(sizeof(struct ipt_mark_target_info)));
+ IP6T_ALIGN(sizeof(struct ip6t_mark_target_info)));
return 0;
}
@@ -46,12 +46,13 @@ checkentry(const char *tablename,
return 1;
}
-static struct ipt_target ipt_mark_reg
+static struct ip6t_target ip6t_mark_reg
= { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE };
static int __init init(void)
{
- if (ipt_register_target(&ipt_mark_reg))
+ printk(KERN_DEBUG "registreing ipv6 mark target\n");
+ if (ip6t_register_target(&ip6t_mark_reg))
return -EINVAL;
return 0;
@@ -59,7 +60,7 @@ static int __init init(void)
static void __exit fini(void)
{
- ipt_unregister_target(&ipt_mark_reg);
+ ip6t_unregister_target(&ip6t_mark_reg);
}
module_init(init);
diff --git a/net/ipv6/netfilter/ip6t_mark.c b/net/ipv6/netfilter/ip6t_mark.c
index babe202a4..9a78b1ca2 100644
--- a/net/ipv6/netfilter/ip6t_mark.c
+++ b/net/ipv6/netfilter/ip6t_mark.c
@@ -2,7 +2,7 @@
#include <linux/module.h>
#include <linux/skbuff.h>
-#include <linux/netfilter_ipv4/ipt_mark.h>
+#include <linux/netfilter_ipv6/ip6t_mark.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
static int
@@ -15,7 +15,7 @@ match(const struct sk_buff *skb,
u_int16_t datalen,
int *hotdrop)
{
- const struct ipt_mark_info *info = matchinfo;
+ const struct ip6t_mark_info *info = matchinfo;
return ((skb->nfmark & info->mask) == info->mark) ^ info->invert;
}
@@ -27,7 +27,7 @@ checkentry(const char *tablename,
unsigned int matchsize,
unsigned int hook_mask)
{
- if (matchsize != IP6T_ALIGN(sizeof(struct ipt_mark_info)))
+ if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info)))
return 0;
return 1;
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
new file mode 100644
index 000000000..612c292c4
--- /dev/null
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -0,0 +1,189 @@
+/*
+ * IPv6 packet mangling table, a port of the IPv4 mangle table to IPv6
+ *
+ * Copyright (C) 2000 by Harald Welte <laforge@gnumonks.org>
+ */
+#include <linux/module.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+
+#define MANGLE_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT))
+
+#if 1
+#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args)
+#else
+#define DEBUGP(x, args...)
+#endif
+
+/* Standard entry. */
+struct ip6t_standard
+{
+ struct ip6t_entry entry;
+ struct ip6t_standard_target target;
+};
+
+struct ip6t_error_target
+{
+ struct ip6t_entry_target target;
+ char errorname[IP6T_FUNCTION_MAXNAMELEN];
+};
+
+struct ip6t_error
+{
+ struct ip6t_entry entry;
+ struct ip6t_error_target target;
+};
+
+static struct
+{
+ struct ip6t_replace repl;
+ struct ip6t_standard entries[2];
+ struct ip6t_error term;
+} initial_table __initdata
+= { { "mangle", MANGLE_VALID_HOOKS, 3,
+ sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error),
+ { [NF_IP6_PRE_ROUTING] 0,
+ [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
+ { [NF_IP6_PRE_ROUTING] 0,
+ [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) },
+ 0, NULL, { } },
+ {
+ /* PRE_ROUTING */
+ { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+ 0,
+ sizeof(struct ip6t_entry),
+ sizeof(struct ip6t_standard),
+ 0, { 0, 0 }, { } },
+ { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
+ -NF_ACCEPT - 1 } },
+ /* LOCAL_OUT */
+ { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+ 0,
+ sizeof(struct ip6t_entry),
+ sizeof(struct ip6t_standard),
+ 0, { 0, 0 }, { } },
+ { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } },
+ -NF_ACCEPT - 1 } }
+ },
+ /* ERROR */
+ { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 },
+ 0,
+ sizeof(struct ip6t_entry),
+ sizeof(struct ip6t_error),
+ 0, { 0, 0 }, { } },
+ { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } },
+ { } },
+ "ERROR"
+ }
+ }
+};
+
+static struct ip6t_table packet_mangler
+= { { NULL, NULL }, "mangle", &initial_table.repl,
+ MANGLE_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL };
+
+/* The work comes in here from netfilter.c. */
+static unsigned int
+ip6t_hook(unsigned int hook,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ return ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL);
+}
+
+static unsigned int
+ip6t_local_out_hook(unsigned int hook,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+
+ unsigned long nfmark;
+ unsigned int ret;
+ struct in6_addr saddr, daddr;
+ u_int8_t hop_limit;
+ u_int32_t flowlabel;
+
+#if 0
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
+ if (net_ratelimit())
+ printk("ip6t_hook: happy cracking.\n");
+ return NF_ACCEPT;
+ }
+#endif
+
+ /* save source/dest address, nfmark, hoplimit, flowlabel, priority, */
+ memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
+ memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
+ nfmark = (*pskb)->nfmark;
+ hop_limit = (*pskb)->nh.ipv6h->hop_limit;
+
+ /* flowlabel and prio (includes version, which shouldn't change either */
+ flowlabel = (u_int32_t) (*pskb)->nh.ipv6h;
+
+ ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL);
+
+ if (ret != NF_DROP && ret != NF_STOLEN
+ && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr))
+ || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr))
+ || (*pskb)->nfmark != nfmark
+ || (*pskb)->nh.ipv6h->hop_limit != hop_limit)) {
+
+ /* something which could affect routing has changed */
+
+ DEBUGP("ip6table_mangle: we'd need to re-route a packet\n");
+ }
+
+ return ret;
+}
+
+static struct nf_hook_ops ip6t_ops[]
+= { { { NULL, NULL }, ip6t_hook, PF_INET6, NF_IP6_PRE_ROUTING, NF_IP6_PRI_MANGLE },
+ { { NULL, NULL }, ip6t_local_out_hook, PF_INET6, NF_IP6_LOCAL_OUT,
+ NF_IP6_PRI_MANGLE }
+};
+
+static int __init init(void)
+{
+ int ret;
+
+ /* Register table */
+ ret = ip6t_register_table(&packet_mangler);
+ if (ret < 0)
+ return ret;
+
+ /* Register hooks */
+ ret = nf_register_hook(&ip6t_ops[0]);
+ if (ret < 0)
+ goto cleanup_table;
+
+ ret = nf_register_hook(&ip6t_ops[1]);
+ if (ret < 0)
+ goto cleanup_hook0;
+
+ return ret;
+
+ cleanup_hook0:
+ nf_unregister_hook(&ip6t_ops[0]);
+ cleanup_table:
+ ip6t_unregister_table(&packet_mangler);
+
+ return ret;
+}
+
+static void __exit fini(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++)
+ nf_unregister_hook(&ip6t_ops[i]);
+
+ ip6t_unregister_table(&packet_mangler);
+}
+
+module_init(init);
+module_exit(fini);
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 */
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index e5504ee96..250b22ae9 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -2409,6 +2409,7 @@ int __init irda_proto_init(void)
#endif
return 0;
}
+module_init(irda_proto_init);
/*
* Function irda_proto_cleanup (void)
@@ -2429,11 +2430,9 @@ void irda_proto_cleanup(void)
return;
}
-module_init(irda_proto_init);
module_exit(irda_proto_cleanup);
MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
MODULE_PARM(irda_debug, "1l");
#endif /* MODULE */
-
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 550519e0b..43ed8e26b 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -252,7 +252,7 @@ static u32 gen_new_htid(struct tc_u_common *tp_c)
do {
if (++tp_c->hgenerator == 0x7FF)
tp_c->hgenerator = 1;
- } while (i>0 && u32_lookup_ht(tp_c, (tp_c->hgenerator|0x800)<<20));
+ } while (--i>0 && u32_lookup_ht(tp_c, (tp_c->hgenerator|0x800)<<20));
return i > 0 ? (tp_c->hgenerator|0x800)<<20 : 0;
}
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 76f2fc394..a66fd2b45 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -39,16 +39,22 @@
* x:y y>0 y+1 use entry [y]
* ... ... ...
* x:indices-1 indices use entry [indices-1]
+ * ... ... ...
+ * x:y y+1 use entry [y & (indices-1)]
+ * ... ... ...
+ * 0xffff 0x10000 use entry [indices-1]
*/
+#define NO_DEFAULT_INDEX (1 << 16)
+
struct dsmark_qdisc_data {
struct Qdisc *q;
struct tcf_proto *filter_list;
__u8 *mask; /* "owns" the array */
__u8 *value;
__u16 indices;
- __u16 default_index;
+ __u32 default_index; /* index range is 0...0xffff */
int set_tc_index;
};
@@ -217,7 +223,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch)
case TC_POLICE_UNSPEC:
/* fall through */
default:
- if (p->default_index)
+ if (p->default_index != NO_DEFAULT_INDEX)
skb->tc_index = p->default_index;
break;
};
@@ -325,14 +331,12 @@ int dsmark_init(struct Qdisc *sch,struct rtattr *opt)
if (tmp & 1)
return -EINVAL;
}
- p->default_index = 0;
+ p->default_index = NO_DEFAULT_INDEX;
if (tb[TCA_DSMARK_DEFAULT_INDEX-1]) {
if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX-1]) < sizeof(__u16))
return -EINVAL;
p->default_index =
*(__u16 *) RTA_DATA(tb[TCA_DSMARK_DEFAULT_INDEX-1]);
- if (!p->default_index || p->default_index >= p->indices)
- return -EINVAL;
}
p->set_tc_index = !!tb[TCA_DSMARK_SET_TC_INDEX-1];
p->mask = kmalloc(p->indices*2,GFP_KERNEL);
@@ -411,9 +415,11 @@ static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb)
rta = (struct rtattr *) b;
RTA_PUT(skb,TCA_OPTIONS,0,NULL);
RTA_PUT(skb,TCA_DSMARK_INDICES,sizeof(__u16),&p->indices);
- if (p->default_index)
- RTA_PUT(skb,TCA_DSMARK_DEFAULT_INDEX, sizeof(__u16),
- &p->default_index);
+ if (p->default_index != NO_DEFAULT_INDEX) {
+ __u16 tmp = p->default_index;
+
+ RTA_PUT(skb,TCA_DSMARK_DEFAULT_INDEX, sizeof(__u16), &tmp);
+ }
if (p->set_tc_index)
RTA_PUT(skb, TCA_DSMARK_SET_TC_INDEX, 0, NULL);
rta->rta_len = skb->tail-b;
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 4983e898e..3a48c3ebf 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -110,12 +110,9 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
unsigned long qave=0;
int i=0;
- if (!t->initd) {
- DPRINTK("NO GRED Queues setup yet! Enqueued anyway\n");
- if (q->backlog <= q->limit) {
- __skb_queue_tail(&sch->q, skb);
- return NET_XMIT_DROP; /* @@@@ */
- }
+ if (!t->initd && skb_queue_len(&sch->q) <= sch->dev->tx_queue_len) {
+ D2PRINTK("NO GRED Queues setup yet! Enqueued anyway\n");
+ goto do_enqueue;
}
@@ -179,11 +176,12 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch)
q->qcount = -1;
enqueue:
if (q->backlog <= q->limit) {
+ q->backlog += skb->len;
+do_enqueue:
__skb_queue_tail(&sch->q, skb);
sch->stats.backlog += skb->len;
sch->stats.bytes += skb->len;
sch->stats.packets++;
- q->backlog += skb->len;
return 0;
} else {
q->pdrop++;
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index a295ecaf7..a6af993c8 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -267,22 +267,26 @@ rpcauth_holdcred(struct rpc_task *task)
dprintk("RPC: %4d holding %s cred %p\n",
task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred);
if (task->tk_msg.rpc_cred) {
+ spin_lock(&rpc_credcache_lock);
task->tk_msg.rpc_cred->cr_count++;
task->tk_msg.rpc_cred->cr_expire = jiffies + task->tk_auth->au_expire;
+ spin_unlock(&rpc_credcache_lock);
}
}
void
rpcauth_releasecred(struct rpc_auth *auth, struct rpc_cred *cred)
{
+ spin_lock(&rpc_credcache_lock);
if (cred != NULL && cred->cr_count > 0) {
- cred->cr_count--;
- if (cred->cr_flags & RPCAUTH_CRED_DEAD) {
+ if (!--cred->cr_count && (cred->cr_flags & RPCAUTH_CRED_DEAD)) {
+ spin_unlock(&rpc_credcache_lock);
rpcauth_remove_credcache(auth, cred);
- if (!cred->cr_count)
- rpcauth_crdestroy(auth, cred);
+ rpcauth_crdestroy(auth, cred);
+ return;
}
}
+ spin_unlock(&rpc_credcache_lock);
}
void
@@ -335,13 +339,19 @@ rpcauth_invalcred(struct rpc_task *task)
{
dprintk("RPC: %4d invalidating %s cred %p\n",
task->tk_pid, task->tk_auth->au_ops->au_name, task->tk_msg.rpc_cred);
+ spin_lock(&rpc_credcache_lock);
if (task->tk_msg.rpc_cred)
task->tk_msg.rpc_cred->cr_flags &= ~RPCAUTH_CRED_UPTODATE;
+ spin_unlock(&rpc_credcache_lock);
}
int
rpcauth_uptodatecred(struct rpc_task *task)
{
- return !(task->tk_msg.rpc_cred) ||
+ int retval;
+ spin_lock(&rpc_credcache_lock);
+ retval = !(task->tk_msg.rpc_cred) ||
(task->tk_msg.rpc_cred->cr_flags & RPCAUTH_CRED_UPTODATE);
+ spin_unlock(&rpc_credcache_lock);
+ return retval;
}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index e53759e3e..1c5fd3740 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -36,6 +36,7 @@ EXPORT_SYMBOL(rpciod_down);
EXPORT_SYMBOL(rpciod_up);
EXPORT_SYMBOL(rpc_new_task);
EXPORT_SYMBOL(rpc_wake_up_status);
+EXPORT_SYMBOL(rpc_release_task);
/* RPC client functions */
EXPORT_SYMBOL(rpc_create_client);
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index bda8d54d8..61f948390 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -26,10 +26,6 @@ extern ctl_table ipx_table[];
extern ctl_table core_table[];
-#ifdef CONFIG_UNIX
-extern ctl_table unix_table[];
-#endif
-
#ifdef CONFIG_NET
extern ctl_table ether_table[], e802_table[];
#endif
@@ -48,9 +44,6 @@ extern ctl_table econet_table[];
ctl_table net_table[] = {
{NET_CORE, "core", NULL, 0, 0555, core_table},
-#ifdef CONFIG_UNIX
- {NET_UNIX, "unix", NULL, 0, 0555, unix_table},
-#endif
#ifdef CONFIG_NET
{NET_802, "802", NULL, 0, 0555, e802_table},
{NET_ETHER, "ethernet", NULL, 0, 0555, ether_table},
diff --git a/net/unix/Makefile b/net/unix/Makefile
index 88a262671..9a840afde 100644
--- a/net/unix/Makefile
+++ b/net/unix/Makefile
@@ -16,5 +16,3 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_unix.o
include $(TOPDIR)/Rules.make
-tar:
- tar -cvf /dev/f1 .
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index e48b8549a..121e4d9de 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1,5 +1,5 @@
/*
- * NET3: Implementation of BSD Unix domain sockets.
+ * NET4: Implementation of BSD Unix domain sockets.
*
* Authors: Alan Cox, <alan.cox@linux.org>
*
@@ -8,7 +8,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
- * Version: $Id: af_unix.c,v 1.108 2000/11/10 04:02:04 davem Exp $
+ * Version: $Id: af_unix.c,v 1.109 2001/01/06 00:42:23 davem Exp $
*
* Fixes:
* Linus Torvalds : Assorted bug cures.
@@ -124,13 +124,12 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
#define UNIX_ABSTRACT(sk) ((sk)->protinfo.af_unix.addr->hash!=UNIX_HASH_SIZE)
/*
- SMP locking strategy.
- * hash table is protceted with rwlock unix_table_lock
- * each socket state is protected by separate rwlock.
-
+ * SMP locking strategy:
+ * hash table is protected with rwlock unix_table_lock
+ * each socket state is protected by separate rwlock.
*/
-extern __inline__ unsigned unix_hash_fold(unsigned hash)
+static inline unsigned unix_hash_fold(unsigned hash)
{
hash ^= hash>>16;
hash ^= hash>>8;
@@ -139,17 +138,17 @@ extern __inline__ unsigned unix_hash_fold(unsigned hash)
#define unix_peer(sk) ((sk)->pair)
-extern __inline__ int unix_our_peer(unix_socket *sk, unix_socket *osk)
+static inline int unix_our_peer(unix_socket *sk, unix_socket *osk)
{
return unix_peer(osk) == sk;
}
-extern __inline__ int unix_may_send(unix_socket *sk, unix_socket *osk)
+static inline int unix_may_send(unix_socket *sk, unix_socket *osk)
{
return (unix_peer(osk) == NULL || unix_our_peer(sk, osk));
}
-static __inline__ unix_socket * unix_peer_get(unix_socket *s)
+static inline unix_socket * unix_peer_get(unix_socket *s)
{
unix_socket *peer;
@@ -161,7 +160,7 @@ static __inline__ unix_socket * unix_peer_get(unix_socket *s)
return peer;
}
-extern __inline__ void unix_release_addr(struct unix_address *addr)
+extern inline void unix_release_addr(struct unix_address *addr)
{
if (atomic_dec_and_test(&addr->refcnt))
kfree(addr);
@@ -231,14 +230,14 @@ static void __unix_insert_socket(unix_socket **list, unix_socket *sk)
sock_hold(sk);
}
-static __inline__ void unix_remove_socket(unix_socket *sk)
+static inline void unix_remove_socket(unix_socket *sk)
{
write_lock(&unix_table_lock);
__unix_remove_socket(sk);
write_unlock(&unix_table_lock);
}
-static __inline__ void unix_insert_socket(unix_socket **list, unix_socket *sk)
+static inline void unix_insert_socket(unix_socket **list, unix_socket *sk)
{
write_lock(&unix_table_lock);
__unix_insert_socket(list, sk);
@@ -258,7 +257,7 @@ static unix_socket *__unix_find_socket_byname(struct sockaddr_un *sunname,
return NULL;
}
-static __inline__ unix_socket *
+static inline unix_socket *
unix_find_socket_byname(struct sockaddr_un *sunname,
int len, int type, unsigned hash)
{
@@ -291,7 +290,7 @@ static unix_socket *unix_find_socket_byinode(struct inode *i)
return s;
}
-static __inline__ int unix_writable(struct sock *sk)
+static inline int unix_writable(struct sock *sk)
{
return ((atomic_read(&sk->wmem_alloc)<<2) <= sk->sndbuf);
}
@@ -1823,7 +1822,7 @@ struct proto_ops unix_stream_ops = {
struct proto_ops unix_dgram_ops = {
family: PF_UNIX,
-
+
release: unix_release,
bind: unix_bind,
connect: unix_dgram_connect,
@@ -1842,20 +1841,25 @@ struct proto_ops unix_dgram_ops = {
};
struct net_proto_family unix_family_ops = {
- PF_UNIX,
- unix_create
+ family: PF_UNIX,
+ create: unix_create
};
#ifdef CONFIG_SYSCTL
extern void unix_sysctl_register(void);
extern void unix_sysctl_unregister(void);
+#else
+static inline unix_sysctl_register() {};
+static inline unix_sysctl_unregister() {};
#endif
+static const char banner[] __initdata = KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n";
+
static int __init af_unix_init(void)
{
struct sk_buff *dummy_skb;
-
- printk(KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n");
+
+ printk(banner);
if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb))
{
printk(KERN_CRIT "unix_proto_init: panic\n");
@@ -1865,23 +1869,15 @@ static int __init af_unix_init(void)
#ifdef CONFIG_PROC_FS
create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL);
#endif
-
-#ifdef CONFIG_SYSCTL
unix_sysctl_register();
-#endif
-
return 0;
}
static void __exit af_unix_exit(void)
{
sock_unregister(PF_UNIX);
-#ifdef CONFIG_SYSCTL
unix_sysctl_unregister();
-#endif
-#ifdef CONFIG_PROC_FS
remove_proc_entry("net/unix", 0);
-#endif
}
module_init(af_unix_init);
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index 885119da3..eceea5c95 100644
--- a/net/unix/sysctl_net_unix.c
+++ b/net/unix/sysctl_net_unix.c
@@ -1,10 +1,8 @@
/*
- * NET3: Sysctl interface to net af_unix subsystem.
+ * NET4: Sysctl interface to net af_unix subsystem.
*
* Authors: Mike Shaver.
*
- * Added /proc/sys/net/unix directory entry (empty =) ).
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -13,9 +11,6 @@
#include <linux/mm.h>
#include <linux/sysctl.h>
-#include <linux/config.h>
-
-#ifdef CONFIG_SYSCTL
extern int sysctl_unix_max_dgram_qlen;
@@ -26,20 +21,18 @@ ctl_table unix_table[] = {
{0}
};
-static struct ctl_table_header * unix_sysctl_header;
-static struct ctl_table unix_root_table[];
-static struct ctl_table unix_net_table[];
-
-ctl_table unix_root_table[] = {
- {CTL_NET, "net", NULL, 0, 0555, unix_net_table},
+static ctl_table unix_net_table[] = {
+ {NET_UNIX, "unix", NULL, 0, 0555, unix_table},
{0}
};
-ctl_table unix_net_table[] = {
- {NET_UNIX, "unix", NULL, 0, 0555, unix_table},
+static ctl_table unix_root_table[] = {
+ {CTL_NET, "net", NULL, 0, 0555, unix_net_table},
{0}
};
+static struct ctl_table_header * unix_sysctl_header;
+
void unix_sysctl_register(void)
{
unix_sysctl_header = register_sysctl_table(unix_root_table, 0);
@@ -50,4 +43,3 @@ void unix_sysctl_unregister(void)
unregister_sysctl_table(unix_sysctl_header);
}
-#endif /* CONFIG_SYSCTL */
diff --git a/net/x25/Makefile b/net/x25/Makefile
index 0890eff84..d0082933f 100644
--- a/net/x25/Makefile
+++ b/net/x25/Makefile
@@ -17,5 +17,3 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_x25.o
include $(TOPDIR)/Rules.make
-tar:
- tar -cvf /dev/f1 .
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index c8f8c3e97..a938f3bc1 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1084,6 +1084,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
msg->msg_namelen = sizeof(struct sockaddr_x25);
skb_free_datagram(sk, skb);
+ lock_sock(sk);
+ x25_check_rbuf(sk);
+ release_sock(sk);
return copied;
}
@@ -1258,8 +1261,8 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
}
struct net_proto_family x25_family_ops = {
- AF_X25,
- x25_create
+ family: AF_X25,
+ create: x25_create,
};
static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
@@ -1286,18 +1289,13 @@ static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
SOCKOPS_WRAP(x25_proto, AF_X25);
-static struct packet_type x25_packet_type =
-{
- 0, /* MUTTER ntohs(ETH_P_X25),*/
- 0, /* copy */
- x25_lapb_receive_frame,
- NULL,
- NULL,
+static struct packet_type x25_packet_type = {
+ type: __constant_htons(ETH_P_X25),
+ func: x25_lapb_receive_frame,
};
struct notifier_block x25_dev_notifier = {
- x25_device_event,
- 0
+ notifier_call: x25_device_event,
};
void x25_kill_by_neigh(struct x25_neigh *neigh)
@@ -1317,7 +1315,6 @@ static int __init x25_init(void)
#endif /* MODULE */
sock_register(&x25_family_ops);
- x25_packet_type.type = htons(ETH_P_X25);
dev_add_pack(&x25_packet_type);
register_netdevice_notifier(&x25_dev_notifier);
diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
index fbc781dce..1abb28358 100644
--- a/net/x25/x25_dev.c
+++ b/net/x25/x25_dev.c
@@ -18,7 +18,6 @@
*/
#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -249,8 +248,3 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh)
dev_queue_xmit(skb);
}
-
-#endif
-
-
-
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index ad41d1cde..adf757e56 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -18,8 +18,6 @@
* negotiation.
*/
-#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -232,7 +230,3 @@ void x25_limit_facilities(struct x25_facilities *facilities,
}
}
}
-
-#endif
-
-
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index bcb5f1cf4..73a567e89 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -22,8 +22,6 @@
* i-frames.
*/
-#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -369,5 +367,3 @@ int x25_backlog_rcv(struct sock *sk, struct sk_buff *skb)
return 0;
}
-
-#endif
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index d6b878371..841499325 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -20,8 +20,6 @@
* 2000-09-04 Henner Eisen dev_hold() / dev_put() for x25_neigh.
*/
-#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -42,9 +40,10 @@
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <net/x25.h>
-static struct x25_neigh *x25_neigh_list = NULL;
+static struct x25_neigh *x25_neigh_list /* = NULL initially */;
static void x25_t20timer_expiry(unsigned long);
@@ -422,12 +421,11 @@ int x25_subscr_ioctl(unsigned int cmd, void *arg)
return 0;
}
-#ifdef MODULE
/*
* Release all memory associated with X.25 neighbour structures.
*/
-void x25_link_free(void)
+void __exit x25_link_free(void)
{
struct x25_neigh *neigh, *x25_neigh = x25_neigh_list;
@@ -438,7 +436,3 @@ void x25_link_free(void)
x25_remove_neigh(neigh);
}
}
-
-#endif
-
-#endif
diff --git a/net/x25/x25_out.c b/net/x25/x25_out.c
index b3ce30477..2521078a6 100644
--- a/net/x25/x25_out.c
+++ b/net/x25/x25_out.c
@@ -21,8 +21,6 @@
* needed cleaned seq-number fields.
*/
-#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -229,5 +227,3 @@ void x25_enquiry_response(struct sock *sk)
x25_stop_timer(sk);
}
-
-#endif
diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c
index 4cb51300b..a4651699e 100644
--- a/net/x25/x25_route.c
+++ b/net/x25/x25_route.c
@@ -17,7 +17,6 @@
*/
#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -42,9 +41,10 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
+#include <linux/init.h>
#include <net/x25.h>
-static struct x25_route *x25_route_list = NULL;
+static struct x25_route *x25_route_list /* = NULL initially */;
/*
* Add a new route.
@@ -255,12 +255,10 @@ int x25_routes_get_info(char *buffer, char **start, off_t offset, int length)
return len;
}
-#ifdef MODULE
-
/*
* Release all memory associated with X.25 routing structures.
*/
-void x25_route_free(void)
+void __exit x25_route_free(void)
{
struct x25_route *route, *x25_route = x25_route_list;
@@ -271,7 +269,3 @@ void x25_route_free(void)
x25_remove_route(route);
}
}
-
-#endif
-
-#endif
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index 25a700af9..635c872e5 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -19,8 +19,6 @@
* negotiation.
*/
-#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -351,4 +349,18 @@ void x25_disconnect(struct sock *sk, int reason, unsigned char cause, unsigned c
sk->dead = 1;
}
-#endif
+/*
+ * Clear an own-rx-busy condition and tell the peer about this, provided
+ * that there is a significant amount of free receive buffer space available.
+ */
+void x25_check_rbuf(struct sock *sk)
+{
+ if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
+ (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) {
+ sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
+ sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
+ sk->protinfo.x25->vl = sk->protinfo.x25->vr;
+ x25_write_internal(sk, X25_RR);
+ x25_stop_timer(sk);
+ }
+}
diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c
index 20672419e..cf9b42606 100644
--- a/net/x25/x25_timer.c
+++ b/net/x25/x25_timer.c
@@ -18,8 +18,6 @@
* Centralised disconnection processing.
*/
-#include <linux/config.h>
-#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE)
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
@@ -121,6 +119,11 @@ static void x25_heartbeat_expiry(unsigned long param)
{
struct sock *sk = (struct sock *)param;
+ bh_lock_sock(sk);
+ if (sk->lock.users) { /* can currently only occur in state 3 */
+ goto restart_heartbeat;
+ }
+
switch (sk->protinfo.x25->state) {
case X25_STATE_0:
@@ -128,7 +131,7 @@ static void x25_heartbeat_expiry(unsigned long param)
is accepted() it isn't 'dead' so doesn't get removed. */
if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) {
x25_destroy_socket(sk);
- return;
+ goto unlock;
}
break;
@@ -136,29 +139,21 @@ static void x25_heartbeat_expiry(unsigned long param)
/*
* Check for the state of the receive buffer.
*/
- if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) &&
- (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) {
- sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY;
- sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING;
- sk->protinfo.x25->vl = sk->protinfo.x25->vr;
- x25_write_internal(sk, X25_RR);
- x25_stop_timer(sk);
- break;
- }
+ x25_check_rbuf(sk);
break;
}
-
+ restart_heartbeat:
x25_start_heartbeat(sk);
+ unlock:
+ bh_unlock_sock(sk);
}
/*
* Timer has expired, it may have been T2, T21, T22, or T23. We can tell
* by the state machine state.
*/
-static void x25_timer_expiry(unsigned long param)
+static inline void x25_do_timer_expiry(struct sock * sk)
{
- struct sock *sk = (struct sock *)param;
-
switch (sk->protinfo.x25->state) {
case X25_STATE_3: /* T2 */
@@ -181,4 +176,17 @@ static void x25_timer_expiry(unsigned long param)
}
}
-#endif
+static void x25_timer_expiry(unsigned long param)
+{
+ struct sock *sk = (struct sock *)param;
+
+ bh_lock_sock(sk);
+ if (sk->lock.users) { /* can currently only occur in state 3 */
+ if (sk->protinfo.x25->state == X25_STATE_3) {
+ x25_start_t2timer(sk);
+ }
+ } else {
+ x25_do_timer_expiry(sk);
+ }
+ bh_unlock_sock(sk);
+}