summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/atalk.h168
-rw-r--r--net/appletalk/aarp.c201
-rw-r--r--net/appletalk/ddp.c385
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 */