diff options
| -rw-r--r-- | include/linux/atalk.h | 168 | ||||
| -rw-r--r-- | net/appletalk/aarp.c | 201 | ||||
| -rw-r--r-- | net/appletalk/ddp.c | 385 |
3 files changed, 397 insertions, 357 deletions
diff --git a/include/linux/atalk.h b/include/linux/atalk.h index c76adf7fdd04..e26dc1db8a41 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h @@ -1,86 +1,89 @@ +#ifndef __LINUX_ATALK_H__ +#define __LINUX_ATALK_H__ /* - * AppleTalk networking structures + * AppleTalk networking structures * - * The following are directly referenced from the University Of Michigan - * netatalk for compatibility reasons. + * The following are directly referenced from the University Of Michigan + * netatalk for compatibility reasons. */ - -#ifndef __LINUX_ATALK_H__ -#define __LINUX_ATALK_H__ - #define ATPORT_FIRST 1 #define ATPORT_RESERVED 128 -#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ +#define ATPORT_LAST 254 /* 254 is only legal on localtalk */ #define ATADDR_ANYNET (__u16)0 #define ATADDR_ANYNODE (__u8)0 #define ATADDR_ANYPORT (__u8)0 #define ATADDR_BCAST (__u8)255 #define DDP_MAXSZ 587 -#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ +#define DDP_MAXHOPS 15 /* 4 bits of hop counter */ #define SIOCATALKDIFADDR (SIOCPROTOPRIVATE + 0) -struct at_addr -{ +struct atalk_addr { __u16 s_net; __u8 s_node; }; -struct sockaddr_at -{ - sa_family_t sat_family; - __u8 sat_port; - struct at_addr sat_addr; - char sat_zero[ 8 ]; +struct sockaddr_at { + sa_family_t sat_family; + __u8 sat_port; + struct atalk_addr sat_addr; + char sat_zero[8]; }; -struct netrange -{ +struct atalk_netrange { __u8 nr_phase; __u16 nr_firstnet; __u16 nr_lastnet; }; -struct atalk_route -{ - struct net_device *dev; - struct at_addr target; - struct at_addr gateway; - int flags; +struct atalk_route { + struct net_device *dev; + struct atalk_addr target; + struct atalk_addr gateway; + int flags; struct atalk_route *next; }; -struct atalk_iface -{ - struct net_device *dev; - struct at_addr address; /* Our address */ - int status; /* What are we doing? */ +/** + * struct atalk_iface - AppleTalk Interface + * @dev - Network device associated with this interface + * @address - Our address + * @status - What are we doing? + * @nets - Associated direct netrange + * @next - next element in the list of interfaces + */ +struct atalk_iface { + struct net_device *dev; + struct atalk_addr address; + int status; #define ATIF_PROBE 1 /* Probing for an address */ #define ATIF_PROBE_FAIL 2 /* Probe collided */ - struct netrange nets; /* Associated direct netrange */ - struct atalk_iface *next; + struct atalk_netrange nets; + struct atalk_iface *next; }; -struct atalk_sock -{ - unsigned short dest_net; - unsigned short src_net; - unsigned char dest_node; - unsigned char src_node; - unsigned char dest_port; - unsigned char src_port; +struct atalk_sock { + unsigned short dest_net; + unsigned short src_net; + unsigned char dest_node; + unsigned char src_node; + unsigned char dest_port; + unsigned char src_port; }; #ifdef __KERNEL__ #include <asm/byteorder.h> -struct ddpehdr -{ +struct ddpehdr { #ifdef __LITTLE_ENDIAN_BITFIELD - __u16 deh_len:10, deh_hops:4, deh_pad:2; + __u16 deh_len:10, + deh_hops:4, + deh_pad:2; #else - __u16 deh_pad:2, deh_hops:4, deh_len:10; + __u16 deh_pad:2, + deh_hops:4, + deh_len:10; #endif __u16 deh_sum; __u16 deh_dnet; @@ -92,30 +95,35 @@ struct ddpehdr /* And netatalk apps expect to stick the type in themselves */ }; +static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb) +{ + return (struct ddpehdr *)skb->h.raw; +} + /* * Don't drop the struct into the struct above. You'll get some * surprise padding. */ - -struct ddpebits -{ +struct ddpebits { #ifdef __LITTLE_ENDIAN_BITFIELD - __u16 deh_len:10, deh_hops:4, deh_pad:2; + __u16 deh_len:10, + deh_hops:4, + deh_pad:2; #else - __u16 deh_pad:2, deh_hops:4, deh_len:10; + __u16 deh_pad:2, + deh_hops:4, + deh_len:10; #endif }; -/* - * Short form header - */ - -struct ddpshdr -{ +/* Short form header */ +struct ddpshdr { #ifdef __LITTLE_ENDIAN_BITFIELD - __u16 dsh_len:10, dsh_pad:6; + __u16 dsh_len:10, + dsh_pad:6; #else - __u16 dsh_pad:6, dsh_len:10; + __u16 dsh_pad:6, + dsh_len:10; #endif __u8 dsh_dport; __u8 dsh_sport; @@ -123,9 +131,7 @@ struct ddpshdr }; /* AppleTalk AARP headers */ - -struct elapaarp -{ +struct elapaarp { __u16 hw_type; #define AARP_HW_TYPE_ETHERNET 1 #define AARP_HW_TYPE_TOKENRING 2 @@ -147,30 +153,44 @@ struct elapaarp __u8 pa_dst_node __attribute__ ((packed)); }; -#define AARP_EXPIRY_TIME (5*60*HZ) /* Not specified - how long till we drop a resolved entry */ -#define AARP_HASH_SIZE 16 /* Size of hash table */ -#define AARP_TICK_TIME (HZ/5) /* Fast retransmission timer when resolving */ -#define AARP_RETRANSMIT_LIMIT 10 /* Send 10 requests then give up (2 seconds) */ -#define AARP_RESOLVE_TIME (10*HZ) /* Some value bigger than total retransmit time + a bit for last reply to appear and to stop continual requests */ +static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) +{ + return (struct elapaarp *)skb->h.raw; +} + +/* Not specified - how long till we drop a resolved entry */ +#define AARP_EXPIRY_TIME (5 * 60 * HZ) +/* Size of hash table */ +#define AARP_HASH_SIZE 16 +/* Fast retransmission timer when resolving */ +#define AARP_TICK_TIME (HZ / 5) +/* Send 10 requests then give up (2 seconds) */ +#define AARP_RETRANSMIT_LIMIT 10 +/* + * Some value bigger than total retransmit time + a bit for last reply to + * appear and to stop continual requests + */ +#define AARP_RESOLVE_TIME (10 * HZ) extern struct datalink_proto *ddp_dl, *aarp_dl; extern void aarp_proto_init(void); -/* Inter module exports */ -/* - * Give a device find its atif control structure - */ +/* Inter module exports */ +/* Give a device find its atif control structure */ static inline struct atalk_iface *atalk_find_dev(struct net_device *dev) { return dev->atalk_ptr; } -extern struct at_addr *atalk_find_dev_addr(struct net_device *dev); -extern struct net_device *atrtr_get_dev(struct at_addr *sa); -extern int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr); -extern void aarp_send_probe(struct net_device *dev, struct at_addr *addr); -extern void aarp_device_down(struct net_device *dev); +extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev); +extern struct net_device *atrtr_get_dev(struct atalk_addr *sa); +extern int aarp_send_ddp(struct net_device *dev, + struct sk_buff *skb, + struct atalk_addr *sa, void *hwaddr); +extern void aarp_send_probe(struct net_device *dev, + struct atalk_addr *addr); +extern void aarp_device_down(struct net_device *dev); #ifdef MODULE extern void aarp_cleanup_module(void); diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 55ca43d7ca6b..c020a70381a8 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -30,7 +30,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include <asm/uaccess.h> #include <asm/system.h> #include <asm/bitops.h> @@ -84,7 +83,7 @@ struct aarp_entry { struct sk_buff_head packet_queue; int status; unsigned long expires_at; - struct at_addr target_addr; + struct atalk_addr target_addr; struct net_device *dev; char hwaddr[6]; unsigned short xmit_count; @@ -122,14 +121,13 @@ static void __aarp_expire(struct aarp_entry *a) static void __aarp_send_query(struct aarp_entry *a) { - static char aarp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + static unsigned 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; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - struct at_addr *sat = atalk_find_dev_addr(dev); struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + struct atalk_addr *sat = atalk_find_dev_addr(dev); if (!skb) return; @@ -141,30 +139,29 @@ static void __aarp_send_query(struct aarp_entry *a) /* Set up the buffer */ skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - 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; + skb->nh.raw = skb->h.raw = skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_REQUEST); + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_REQUEST); memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - eah->pa_src_zero= 0; - eah->pa_src_net = sat->s_net; - eah->pa_src_node= sat->s_node; + eah->pa_src_zero = 0; + eah->pa_src_net = sat->s_net; + eah->pa_src_node = sat->s_node; memset(eah->hw_dst, '\0', ETH_ALEN); - eah->pa_dst_zero= 0; - eah->pa_dst_net = a->target_addr.s_net; - eah->pa_dst_node= a->target_addr.s_node; + eah->pa_dst_zero = 0; + 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 */ aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast); @@ -177,46 +174,44 @@ static void __aarp_send_query(struct aarp_entry *a) /* 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) +static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us, + struct atalk_addr *them, unsigned char *sha) { - 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; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); if (!skb) return; /* Set up the buffer */ skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - 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; + skb->nh.raw = skb->h.raw = skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_REPLY); + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_REPLY); memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - eah->pa_src_zero= 0; - eah->pa_src_net = us->s_net; - eah->pa_src_node= us->s_node; + eah->pa_src_zero = 0; + eah->pa_src_net = us->s_net; + eah->pa_src_node = us->s_node; if (!sha) memset(eah->hw_dst, '\0', ETH_ALEN); else memcpy(eah->hw_dst, sha, ETH_ALEN); - eah->pa_dst_zero= 0; - eah->pa_dst_net = them->s_net; - eah->pa_dst_node= them->s_node; + eah->pa_dst_zero = 0; + eah->pa_dst_net = them->s_net; + eah->pa_dst_node = them->s_node; /* Add ELAP headers and set target to the AARP multicast */ aarp_dl->datalink_header(aarp_dl, skb, sha); @@ -229,44 +224,42 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us, * aarp_proxy_probe_network. */ -void aarp_send_probe(struct net_device *dev, struct at_addr *us) +void aarp_send_probe(struct net_device *dev, struct atalk_addr *us) { - int len = dev->hard_header_len + sizeof(struct elapaarp) + - aarp_dl->header_length; - struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - static char aarp_eth_multicast[ETH_ALEN] = - { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; struct elapaarp *eah; + int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length; + struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); + static unsigned char aarp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; if (!skb) return; /* Set up the buffer */ skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - 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; + skb->nh.raw = skb->h.raw = skb_put(skb, sizeof(*eah)); + skb->protocol = htons(ETH_P_ATALK); + skb->dev = dev; + eah = aarp_hdr(skb); /* Set up the ARP */ - eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); - eah->pa_type = htons(ETH_P_ATALK); - eah->hw_len = ETH_ALEN; - eah->pa_len = AARP_PA_ALEN; - eah->function = htons(AARP_PROBE); + eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); + eah->pa_type = htons(ETH_P_ATALK); + eah->hw_len = ETH_ALEN; + eah->pa_len = AARP_PA_ALEN; + eah->function = htons(AARP_PROBE); memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); - eah->pa_src_zero= 0; - eah->pa_src_net = us->s_net; - eah->pa_src_node= us->s_node; + eah->pa_src_zero = 0; + eah->pa_src_net = us->s_net; + eah->pa_src_node = us->s_node; memset(eah->hw_dst, '\0', ETH_ALEN); - eah->pa_dst_zero= 0; - eah->pa_dst_net = us->s_net; - eah->pa_dst_node= us->s_node; + eah->pa_dst_zero = 0; + eah->pa_dst_net = us->s_net; + eah->pa_dst_node = us->s_node; /* Add ELAP headers and set target to the AARP multicast */ aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast); @@ -398,7 +391,7 @@ static struct aarp_entry *aarp_alloc(void) */ static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list, struct net_device *dev, - struct at_addr *sat) + struct atalk_addr *sat) { while (list) { if (list->target_addr.s_net == sat->s_net && @@ -412,7 +405,7 @@ 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) +void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa) { int hash = sa->s_node % (AARP_HASH_SIZE - 1); struct aarp_entry *a; @@ -427,8 +420,8 @@ 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 atalk_addr *__aarp_proxy_find(struct net_device *dev, + struct atalk_addr *sa) { int hash = sa->s_node % (AARP_HASH_SIZE - 1); struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa); @@ -482,7 +475,7 @@ void aarp_probe_network(struct atalk_iface *atif) } } -int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa) +int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa) { int hash, retval = -EPROTONOSUPPORT; struct aarp_entry *entry; @@ -545,7 +538,7 @@ out: /* Send a DDP frame */ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, - struct at_addr *sa, void *hwaddr) + struct atalk_addr *sa, void *hwaddr) { static char ddp_eth_multicast[ETH_ALEN] = { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; @@ -556,15 +549,15 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, /* Check for LocalTalk first */ if (dev->type == ARPHRD_LOCALTLK) { - struct at_addr *at = atalk_find_dev_addr(dev); + struct atalk_addr *at = atalk_find_dev_addr(dev); struct ddpehdr *ddp = (struct ddpehdr *)skb->data; int ft = 2; /* - * Compressible ? + * Compressible ? * - * IFF: src_net==dest_net==device_net - * (zero matches anything) + * IFF: src_net == dest_net == device_net + * (zero matches anything) */ if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) && @@ -580,15 +573,15 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, ft = 1; } /* - * Nice and easy. No AARP type protocols occur here - * so we can just shovel it out with a 3 byte LLAP header + * Nice and easy. No AARP type protocols occur here so we can + * just shovel it out with a 3 byte LLAP header */ skb_push(skb, 3); skb->data[0] = sa->s_node; skb->data[1] = at->s_node; skb->data[2] = ft; - skb->dev = dev; + skb->dev = dev; goto sendit; } @@ -652,8 +645,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, __aarp_send_query(a); /* - * Switch to fast timer if needed (That is if this is the - * first unresolved entry to get added) + * Switch to fast timer if needed (That is if this is the first + * unresolved entry to get added) */ if (unresolved_count == 1) @@ -713,11 +706,11 @@ static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, 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 = aarp_hdr(skb); int hash, ret = 0; __u16 function; struct aarp_entry *a; - struct at_addr sa, *ma, da; + struct atalk_addr sa, *ma, da; struct atalk_iface *ifa; /* We only do Ethernet SNAP AARP. */ @@ -791,20 +784,21 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, 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; + sa.s_net = ea->pa_dst_net; /* See if we have a matching proxy. */ ma = __aarp_proxy_find(dev, &sa); @@ -817,16 +811,22 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, } if (function == AARP_PROBE) { - /* A probe implies someone trying to get an + /* + * 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); - /* Make it expire next tick - that avoids us + 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. */ + * to respond host addr. + */ if (a) { a->expires_at = jiffies - 1; mod_timer(&aarp_timer, jiffies + @@ -862,7 +862,7 @@ static struct notifier_block aarp_notifier = { .notifier_call =aarp_device_event, }; -static char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; +static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; void __init aarp_proto_init(void) { @@ -1003,5 +1003,4 @@ void aarp_unregister_proc_fs(void) proc_net_remove("aarp"); } #endif -#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ MODULE_LICENSE("GPL"); diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index e5be5f439698..c82111b86d33 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -49,7 +49,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #include <linux/module.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -96,8 +95,8 @@ 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 void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa); + struct atalk_addr *sa); +extern void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa); #ifdef CONFIG_SYSCTL extern inline void atalk_register_sysctl(void); @@ -332,7 +331,7 @@ static void atif_drop_device(struct net_device *dev) } static struct atalk_iface *atif_add_device(struct net_device *dev, - struct at_addr *sa) + struct atalk_addr *sa) { struct atalk_iface *iface; @@ -407,7 +406,7 @@ 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) + struct atalk_addr* proxy_addr) { int netrange = ntohs(atif->nets.nr_lastnet) - ntohs(atif->nets.nr_firstnet) + 1; @@ -451,16 +450,16 @@ static int atif_proxy_probe_device(struct atalk_iface *atif, } -struct at_addr *atalk_find_dev_addr(struct net_device *dev) +struct atalk_addr *atalk_find_dev_addr(struct net_device *dev) { struct atalk_iface *iface = dev->atalk_ptr; return iface ? &iface->address : NULL; } -static struct at_addr *atalk_find_primary(void) +static struct atalk_addr *atalk_find_primary(void) { struct atalk_iface *fiface = NULL; - struct at_addr *retval; + struct atalk_addr *retval; struct atalk_iface *iface; /* @@ -497,14 +496,17 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) struct atalk_iface *iface = dev->atalk_ptr; if (!iface || iface->status & ATIF_PROBE) - return NULL; + goto out_err; - if (node == ATADDR_BCAST || - iface->address.s_node == node || - node == ATADDR_ANYNODE) - return iface; - - return NULL; + if (node != ATADDR_BCAST && + iface->address.s_node != node && + node != ATADDR_ANYNODE) + goto out_err; +out: + return iface; +out_err: + iface = NULL; + goto out; } /* Find a match for a specific network:node pair */ @@ -537,7 +539,7 @@ static struct atalk_iface *atalk_find_interface(int net, int node) * the socket (later on...). We know about host routes and the fact * that a route must be direct to broadcast. */ -static struct atalk_route *atrtr_find(struct at_addr *target) +static struct atalk_route *atrtr_find(struct atalk_addr *target) { /* * we must search through all routes unless we find a @@ -589,7 +591,7 @@ out: * Given an AppleTalk network, find the device to use. This can be * a simple lookup. */ -struct net_device *atrtr_get_dev(struct at_addr *sa) +struct net_device *atrtr_get_dev(struct atalk_addr *sa) { struct atalk_route *atr = atrtr_find(sa); return atr ? atr->dev : NULL; @@ -598,9 +600,9 @@ struct net_device *atrtr_get_dev(struct at_addr *sa) /* Set up a default router */ static void atrtr_set_default(struct net_device *dev) { - atrtr_default.dev = dev; - atrtr_default.flags = RTF_UP; - atrtr_default.gateway.s_net = htons(0); + atrtr_default.dev = dev; + atrtr_default.flags = RTF_UP; + atrtr_default.gateway.s_net = htons(0); atrtr_default.gateway.s_node = 0; } @@ -691,7 +693,7 @@ out: } /* Delete a route. Find it and discard it */ -static int atrtr_delete(struct at_addr * addr) +static int atrtr_delete(struct atalk_addr * addr) { struct atalk_route **r = &atalk_router_list; int retval = 0; @@ -750,7 +752,7 @@ static inline void atalk_dev_down(struct net_device *dev) * delete our use of them (iface and route). */ static int ddp_device_event(struct notifier_block *this, unsigned long event, - void *ptr) + void *ptr) { if (event == NETDEV_DOWN) /* Discard any use of this */ @@ -765,7 +767,7 @@ static int atif_ioctl(int cmd, void *arg) { static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF }; struct ifreq atreq; - struct netrange *nr; + struct atalk_netrange *nr; struct sockaddr_at *sa; struct net_device *dev; struct atalk_iface *atif; @@ -796,7 +798,7 @@ static int atif_ioctl(int cmd, void *arg) dev->type != ARPHRD_PPP) return -EPROTONOSUPPORT; - nr = (struct netrange *)&sa->sat_zero[0]; + nr = (struct atalk_netrange *)&sa->sat_zero[0]; add_route = 1; /* @@ -936,7 +938,7 @@ static int atif_ioctl(int cmd, void *arg) if (!atif) return -EADDRNOTAVAIL; - nr = (struct netrange *)&(atif->nets); + nr = (struct atalk_netrange *)&(atif->nets); /* * Phase 1 is fine on Localtalk but we don't do * Ethertalk phase 1. Anyone wanting to add it go ahead. @@ -982,7 +984,6 @@ static int atif_ioctl(int cmd, void *arg) /* Routing ioctl() calls */ static int atrtr_ioctl(unsigned int cmd, void *arg) { - struct net_device *dev = NULL; struct rtentry rt; if (copy_from_user(&rt, arg, sizeof(rt))) @@ -995,15 +996,19 @@ static int atrtr_ioctl(unsigned int cmd, void *arg) return atrtr_delete(&((struct sockaddr_at *) &rt.rt_dst)->sat_addr); - case SIOCADDRT: - /* FIXME: the name of the device is still in user - * space, isn't it? */ + case SIOCADDRT: { + struct net_device *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); + } } return -EINVAL; } @@ -1159,14 +1164,13 @@ static int atalk_release(struct socket *sock) { struct sock *sk = sock->sk; - if (!sk) - goto out; - if (!sk->dead) - sk->state_change(sk); - sk->dead = 1; - sock->sk = NULL; - atalk_destroy_socket(sk); -out: + if (sk) { + if (!sk->dead) + sk->state_change(sk); + sk->dead = 1; + sock->sk = NULL; + atalk_destroy_socket(sk); + } return 0; } @@ -1222,7 +1226,7 @@ static int atalk_autobind(struct sock *sk) { struct atalk_sock *at = at_sk(sk); struct sockaddr_at sat; - struct at_addr *ap = atalk_find_primary(); + struct atalk_addr *ap = atalk_find_primary(); int n = -EADDRNOTAVAIL; if (!ap || ap->s_net == htons(ATADDR_ANYNET)) @@ -1252,7 +1256,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) return -EAFNOSUPPORT; if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { - struct at_addr *ap = atalk_find_primary(); + struct atalk_addr *ap = atalk_find_primary(); if (!ap) return -EADDRNOTAVAIL; @@ -1330,7 +1334,6 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, return 0; } - /* * Find the name of an AppleTalk socket. Just copy the right * fields into the sockaddr. @@ -1366,22 +1369,140 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, return 0; } +#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) +static __inline__ int is_ip_over_ddp(struct sk_buff *skb) +{ + return skb->data[12] == 22; +} + +static int handle_ip_over_ddp(struct sk_buff *skb) +{ + 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) + return -ENODEV; + + skb->protocol = htons(ETH_P_IP); + skb_pull(skb, 13); + skb->dev = dev; + skb->h.raw = skb->data; + + 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; +} +#else +/* make it easy for gcc to optimize this test out, i.e. kill the code */ +#define is_ip_over_ddp(skb) 0 +#define handle_ip_over_ddp(skb) 0 +#endif + +static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev, + struct ddpehdr *ddp, struct ddpebits *ddphv, + int origlen) +{ + struct atalk_route *rt; + struct atalk_addr ta; + + /* + * Don't route multicast, etc., packets, or packets sent to "this + * 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"); + goto free_it; + } + + ta.s_net = ddp->deh_dnet; + ta.s_node = ddp->deh_dnode; + + /* Route the packet */ + rt = atrtr_find(&ta); + if (!rt || ddphv->deh_hops == DDP_MAXHOPS) + goto free_it; + /* FIXME: use skb->cb to be able to use shared skbs */ + ddphv->deh_hops++; + + /* + * Route goes through another gateway, so set the target to the + * gateway instead. + */ + + if (rt->flags & RTF_GATEWAY) { + ta.s_net = rt->gateway.s_net; + ta.s_node = rt->gateway.s_node; + } + + /* Fix up skb->len field */ + skb_trim(skb, min_t(unsigned int, origlen, + (rt->dev->hard_header_len + + ddp_dl->header_length + ddphv->deh_len))); + + /* Mend the byte order */ + /* FIXME: use skb->cb to be able to use shared skbs */ + *((__u16 *)ddp) = ntohs(*((__u16 *)ddphv)); + + /* + * Send the buffer onwards + * + * Now we must always be careful. If it's come from LocalTalk to + * EtherTalk it might not fit + * + * Order matters here: If a packet has to be copied to make a new + * headroom (rare hopefully) then it won't need unsharing. + * + * Note. ddp-> becomes invalid at the realloc. + */ + if (skb_headroom(skb) < 22) { + /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ + struct sk_buff *nskb = skb_realloc_headroom(skb, 32); + kfree_skb(skb); + 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 && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1) + goto free_it; +out: + return; +free_it: + kfree_skb(skb); +} + /** - * atalk_rcv - Receive a packet (in skb) from device dev - * @skb - packet received - * @dev - network device where the packet comes from - * @pt - packet type + * atalk_rcv - Receive a packet (in skb) from device dev + * @skb - packet received + * @dev - network device where the packet comes from + * @pt - packet type * - * Receive a packet (in skb) from device dev. This has come from the SNAP - * decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP - * header, skb->len is the DDP length. The physical headers have been - * extracted. PPP should probably pass frames marked as for this layer. - * [ie ARPHRD_ETHERTALK] + * Receive a packet (in skb) from device dev. This has come from the SNAP + * decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP + * header, skb->len is the DDP length. The physical headers have been + * 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) { - struct ddpehdr *ddp = (void *)skb->h.raw; + struct ddpehdr *ddp = ddp_hdr(skb); struct sock *sock; struct atalk_iface *atif; struct sockaddr_at tosat; @@ -1432,106 +1553,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, /* Not ours, so we route the packet via the correct AppleTalk iface */ if (!atif) { - struct atalk_route *rt; - struct at_addr ta; - - /* - * Don't route multicast, etc., packets, or packets - * sent to "this 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"); - goto freeit; - } - - ta.s_net = ddp->deh_dnet; - ta.s_node = ddp->deh_dnode; - - /* Route the packet */ - rt = atrtr_find(&ta); - if (!rt || ddphv.deh_hops == DDP_MAXHOPS) - goto freeit; - /* FIXME: use skb->cb to be able to use shared skbs */ - ddphv.deh_hops++; - - /* - * Route goes through another gateway, so - * set the target to the gateway instead. - */ - if (rt->flags & RTF_GATEWAY) { - ta.s_net = rt->gateway.s_net; - ta.s_node = rt->gateway.s_node; - } - - /* Fix up skb->len field */ - skb_trim(skb, min_t(unsigned int, origlen, - (rt->dev->hard_header_len + - ddp_dl->header_length + ddphv.deh_len))); - - /* Mend the byte order */ - /* FIXME: use skb->cb to be able to use shared skbs */ - *((__u16 *)ddp) = ntohs(*((__u16 *)&ddphv)); - - /* - * Send the buffer onwards - * - * Now we must always be careful. If it's come from - * LocalTalk to EtherTalk it might not fit - * - * Order matters here: If a packet has to be copied - * to make a new headroom (rare hopefully) then it - * won't need unsharing. - * - * Note. ddp-> becomes invalid at the realloc. - */ - if (skb_headroom(skb) < 22) { - /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ - struct sk_buff *nskb = skb_realloc_headroom(skb, 32); - kfree_skb(skb); - 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 && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1) - goto freeit; + atalk_route_packet(skb, dev, ddp, &ddphv, origlen); goto out; } -#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) - /* Check if IP-over-DDP */ - if (skb->data[12] == 22) { - 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) - return -ENODEV; - - skb->protocol = htons(ETH_P_IP); - skb_pull(skb, 13); - skb->dev = dev; - skb->h.raw = skb->data; - - stats = dev->priv; - stats->rx_packets++; - stats->rx_bytes += skb->len + 13; - netif_rx(skb); /* Send the SKB up to a higher place. */ - goto out; - } -#endif + /* if IP over DDP is not selected this code will be optimized out */ + if (is_ip_over_ddp(skb)) + return handle_ip_over_ddp(skb); /* * Which socket - atalk_search_socket() looks for a *full match* * of the <net, node, port> tuple. @@ -1568,7 +1596,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, if (skb->mac.raw[2] == 1) { struct ddpehdr *ddp; /* Find our address */ - struct at_addr *ap = atalk_find_dev_addr(dev); + struct atalk_addr *ap = atalk_find_dev_addr(dev); if (!ap || skb->len < sizeof(struct ddpshdr)) goto freeit; @@ -1674,7 +1702,7 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, dev = rt->dev; } else { - struct at_addr at_hint; + struct atalk_addr at_hint; at_hint.s_node = 0; at_hint.s_net = at->src_net; @@ -1792,7 +1820,7 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size, return err; /* FIXME: use skb->cb to be able to use shared skbs */ - ddp = (struct ddpehdr *)(skb->h.raw); + ddp = ddp_hdr(skb); *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); if (sk->type == SOCK_RAW) { @@ -1833,40 +1861,48 @@ 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; + int rc = -EINVAL; struct sock *sk = sock->sk; switch (cmd) { /* Protocol layer */ - case TIOCOUTQ: - amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); + case TIOCOUTQ: { + long amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); + if (amount < 0) amount = 0; + rc = put_user(amount, (int *)arg); break; + } case TIOCINQ: { /* * These two are safe on a single CPU system as only * user tasks fiddle here */ struct sk_buff *skb = skb_peek(&sk->receive_queue); + long amount = 0; if (skb) amount = skb->len - sizeof(struct ddpehdr); + rc = put_user(amount, (int *)arg); break; } case SIOCGSTAMP: if (!sk) - return -EINVAL; + break; + rc = -ENOENT; if (!sk->stamp.tv_sec) - return -ENOENT; - return copy_to_user((void *)arg, &sk->stamp, - sizeof(struct timeval)) ? -EFAULT : 0; + break; + rc = copy_to_user((void *)arg, &sk->stamp, + sizeof(struct timeval)) ? -EFAULT : 0; + break; /* Routing */ case SIOCADDRT: case SIOCDELRT: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - return atrtr_ioctl(cmd, (void *)arg); + rc = -EPERM; + if (capable(CAP_NET_ADMIN)) + rc = atrtr_ioctl(cmd, (void *)arg); + break; /* Interface */ case SIOCGIFADDR: case SIOCSIFADDR: @@ -1874,15 +1910,11 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCATALKDIFADDR: case SIOCDIFADDR: case SIOCSARP: /* proxy AARP */ - case SIOCDARP: { /* proxy AARP */ - int ret; - + case SIOCDARP: /* proxy AARP */ rtnl_lock(); - ret = atif_ioctl(cmd, (void *)arg); + rc = atif_ioctl(cmd, (void *)arg); rtnl_unlock(); - - return ret; - } + break; /* Physical layer ioctl calls */ case SIOCSIFLINK: case SIOCGIFHWADDR: @@ -1896,21 +1928,11 @@ 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); - case SIOCSIFMETRIC: - case SIOCSIFBRDADDR: - case SIOCGIFNETMASK: - case SIOCSIFNETMASK: - case SIOCGIFMEM: - case SIOCSIFMEM: - case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: - return -EINVAL; - default: - return -EINVAL; + rc = dev_ioctl(cmd, (void *)arg); + break; } - return put_user(amount, (int *)arg); + return rc; } static struct net_proto_family atalk_family_ops = { @@ -1955,7 +1977,7 @@ struct packet_type ppptalk_packet_type = { .func = atalk_rcv, }; -static char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; +static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; /* Export symbols for use by drivers when AppleTalk is a module */ EXPORT_SYMBOL(aarp_send_ddp); @@ -2023,4 +2045,3 @@ static void __exit atalk_exit(void) } module_exit(atalk_exit); #endif /* MODULE */ -#endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ |
