diff options
Diffstat (limited to 'net/appletalk')
| -rw-r--r-- | net/appletalk/aarp.c | 156 | ||||
| -rw-r--r-- | net/appletalk/atalk_proc.c | 6 | ||||
| -rw-r--r-- | net/appletalk/ddp.c | 585 | ||||
| -rw-r--r-- | net/appletalk/sysctl_net_atalk.c | 10 | 
4 files changed, 370 insertions, 387 deletions
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 50dce798132..d1c55d8dd0a 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -39,6 +39,8 @@  #include <linux/init.h>  #include <linux/proc_fs.h>  #include <linux/seq_file.h> +#include <linux/export.h> +#include <linux/etherdevice.h>  int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;  int sysctl_aarp_tick_time = AARP_TICK_TIME; @@ -66,7 +68,7 @@ struct aarp_entry {  	unsigned long		expires_at;  	struct atalk_addr	target_addr;  	struct net_device	*dev; -	char			hwaddr[6]; +	char			hwaddr[ETH_ALEN];  	unsigned short		xmit_count;  	struct aarp_entry	*next;  }; @@ -133,7 +135,7 @@ static void __aarp_send_query(struct aarp_entry *a)  	eah->pa_len	 = AARP_PA_ALEN;  	eah->function	 = htons(AARP_REQUEST); -	memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); +	ether_addr_copy(eah->hw_src, dev->dev_addr);  	eah->pa_src_zero = 0;  	eah->pa_src_net	 = sat->s_net; @@ -180,7 +182,7 @@ static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us,  	eah->pa_len	 = AARP_PA_ALEN;  	eah->function	 = htons(AARP_REPLY); -	memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); +	ether_addr_copy(eah->hw_src, dev->dev_addr);  	eah->pa_src_zero = 0;  	eah->pa_src_net	 = us->s_net; @@ -189,7 +191,7 @@ static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us,  	if (!sha)  		memset(eah->hw_dst, '\0', ETH_ALEN);  	else -		memcpy(eah->hw_dst, sha, ETH_ALEN); +		ether_addr_copy(eah->hw_dst, sha);  	eah->pa_dst_zero = 0;  	eah->pa_dst_net	 = them->s_net; @@ -231,7 +233,7 @@ static void aarp_send_probe(struct net_device *dev, struct atalk_addr *us)  	eah->pa_len	 = AARP_PA_ALEN;  	eah->function	 = htons(AARP_PROBE); -	memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN); +	ether_addr_copy(eah->hw_src, dev->dev_addr);  	eah->pa_src_zero = 0;  	eah->pa_src_net	 = us->s_net; @@ -331,7 +333,7 @@ static void aarp_expire_timeout(unsigned long unused)  static int aarp_device_event(struct notifier_block *this, unsigned long event,  			     void *ptr)  { -	struct net_device *dev = ptr; +	struct net_device *dev = netdev_notifier_info_to_dev(ptr);  	int ct;  	if (!net_eq(dev_net(dev), &init_net)) @@ -779,87 +781,87 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,  	}  	switch (function) { -		case AARP_REPLY: -			if (!unresolved_count)	/* Speed up */ -				break; - -			/* Find the entry.  */ -			a = __aarp_find_entry(unresolved[hash], dev, &sa); -			if (!a || dev != a->dev) -				break; +	case AARP_REPLY: +		if (!unresolved_count)	/* Speed up */ +			break; -			/* 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) -				mod_timer(&aarp_timer, -					  jiffies + sysctl_aarp_expiry_time); +		/* Find the entry.  */ +		a = __aarp_find_entry(unresolved[hash], dev, &sa); +		if (!a || dev != a->dev)  			break; -		case AARP_REQUEST: -		case AARP_PROBE: +		/* We can fill one in - this is good. */ +		ether_addr_copy(a->hwaddr, ea->hw_src); +		__aarp_resolved(&unresolved[hash], a, hash); +		if (!unresolved_count) +			mod_timer(&aarp_timer, +				  jiffies + sysctl_aarp_expiry_time); +		break; + +	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. +		 * +		 * 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. */ +		ma = __aarp_proxy_find(dev, &sa); +		if (!ma) +			ma = &ifa->address; +		else { /* We need to make a copy of the entry. */ +			da.s_node = sa.s_node; +			da.s_net = sa.s_net; +			ma = &da; +		} +		if (function == 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. -			 * -			 * Support for proxy-AARP added. We check if the -			 * address is one of our proxies before we toss the -			 * packet out. +			 * A probe implies someone trying to get an +			 * address. So as a precaution flush any +			 * entries we have for this address.  			 */ +			a = __aarp_find_entry(resolved[sa.s_node % +						       (AARP_HASH_SIZE - 1)], +					      skb->dev, &sa); -			sa.s_node = ea->pa_dst_node; -			sa.s_net  = ea->pa_dst_net; - -			/* See if we have a matching proxy. */ -			ma = __aarp_proxy_find(dev, &sa); -			if (!ma) -				ma = &ifa->address; -			else { /* We need to make a copy of the entry. */ -				da.s_node = sa.s_node; -				da.s_net = sa.s_net; -				ma = &da; -			} - -			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. -				 */ -				a = __aarp_find_entry(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) { -					a->expires_at = jiffies - 1; -					mod_timer(&aarp_timer, jiffies + -							sysctl_aarp_tick_time); -				} +			/* +			 * 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) { +				a->expires_at = jiffies - 1; +				mod_timer(&aarp_timer, jiffies + +					  sysctl_aarp_tick_time);  			} +		} -			if (sa.s_node != ma->s_node) -				break; +		if (sa.s_node != ma->s_node) +			break; -			if (sa.s_net && ma->s_net && sa.s_net != ma->s_net) -				break; +		if (sa.s_net && ma->s_net && sa.s_net != ma->s_net) +			break; -			sa.s_node = ea->pa_src_node; -			sa.s_net = ea->pa_src_net; +		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_send_reply(dev, ma, &sa, ea->hw_src); -			break; +		/* aarp_my_address has found the address to use for us. +		 */ +		aarp_send_reply(dev, ma, &sa, ea->hw_src); +		break;  	}  unlock: @@ -924,7 +926,7 @@ static struct aarp_entry *iter_next(struct aarp_iter_state *iter, loff_t *pos)  	struct aarp_entry *entry;   rescan: -	while(ct < AARP_HASH_SIZE) { +	while (ct < AARP_HASH_SIZE) {  		for (entry = table[ct]; entry; entry = entry->next) {  			if (!pos || ++off == *pos) {  				iter->table = table; @@ -993,7 +995,7 @@ static const char *dt2str(unsigned long ticks)  {  	static char buf[32]; -	sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100 ) / HZ); +	sprintf(buf, "%ld.%02ld", ticks / HZ, ((ticks % HZ) * 100) / HZ);  	return buf;  } diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c index 6ef0e761e5d..af46bc49e1e 100644 --- a/net/appletalk/atalk_proc.c +++ b/net/appletalk/atalk_proc.c @@ -14,6 +14,7 @@  #include <net/net_namespace.h>  #include <net/sock.h>  #include <linux/atalk.h> +#include <linux/export.h>  static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos) @@ -177,12 +178,13 @@ static int atalk_seq_socket_show(struct seq_file *seq, void *v)  	at = at_sk(s);  	seq_printf(seq, "%02X   %04X:%02X:%02X  %04X:%02X:%02X  %08X:%08X " -			"%02X %d\n", +			"%02X %u\n",  		   s->sk_type, ntohs(at->src_net), at->src_node, at->src_port,  		   ntohs(at->dest_net), at->dest_node, at->dest_port,  		   sk_wmem_alloc_get(s),  		   sk_rmem_alloc_get(s), -		   s->sk_state, SOCK_INODE(s->sk_socket)->i_uid); +		   s->sk_state, +		   from_kuid_munged(seq_user_ns(seq), sock_i_uid(s)));  out:  	return 0;  } diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index c410b93fda2..bfcf6be1d66 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -54,7 +54,6 @@  #include <linux/capability.h>  #include <linux/module.h>  #include <linux/if_arp.h> -#include <linux/smp_lock.h>  #include <linux/termios.h>	/* For TIOCOUTQ/INQ */  #include <linux/compat.h>  #include <linux/slab.h> @@ -64,7 +63,7 @@  #include <net/tcp_states.h>  #include <net/route.h>  #include <linux/atalk.h> -#include "../core/kmap_skb.h" +#include <linux/highmem.h>  struct datalink_proto *ddp_dl, *aarp_dl;  static const struct proto_ops atalk_dgram_ops; @@ -94,10 +93,9 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to,  					struct atalk_iface *atif)  {  	struct sock *s; -	struct hlist_node *node;  	read_lock_bh(&atalk_sockets_lock); -	sk_for_each(s, node, &atalk_sockets) { +	sk_for_each(s, &atalk_sockets) {  		struct atalk_sock *at = at_sk(s);  		if (to->sat_port != at->src_port) @@ -130,8 +128,8 @@ found:  /**   * atalk_find_or_insert_socket - Try to find a socket matching ADDR - * @sk - socket to insert in the list if it is not there already - * @sat - address to search for + * @sk: socket to insert in the list if it is not there already + * @sat: address to search for   *   * Try to find a socket matching ADDR in the socket list, if found then return   * it. If not, insert SK into the socket list. @@ -142,11 +140,10 @@ static struct sock *atalk_find_or_insert_socket(struct sock *sk,  						struct sockaddr_at *sat)  {  	struct sock *s; -	struct hlist_node *node;  	struct atalk_sock *at;  	write_lock_bh(&atalk_sockets_lock); -	sk_for_each(s, node, &atalk_sockets) { +	sk_for_each(s, &atalk_sockets) {  		at = at_sk(s);  		if (at->src_net == sat->sat_addr.s_net && @@ -296,7 +293,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 atalk_addr* proxy_addr) +				   struct atalk_addr *proxy_addr)  {  	int netrange = ntohs(atif->nets.nr_lastnet) -  			ntohs(atif->nets.nr_firstnet) + 1; @@ -584,7 +581,7 @@ out:  }  /* Delete a route. Find it and discard it */ -static int atrtr_delete(struct atalk_addr * addr) +static int atrtr_delete(struct atalk_addr *addr)  {  	struct atalk_route **r = &atalk_routes;  	int retval = 0; @@ -647,7 +644,7 @@ static inline void atalk_dev_down(struct net_device *dev)  static int ddp_device_event(struct notifier_block *this, unsigned long event,  			    void *ptr)  { -	struct net_device *dev = ptr; +	struct net_device *dev = netdev_notifier_info_to_dev(ptr);  	if (!net_eq(dev_net(dev), &init_net))  		return NOTIFY_DONE; @@ -685,192 +682,192 @@ static int atif_ioctl(int cmd, void __user *arg)  	atif = atalk_find_dev(dev);  	switch (cmd) { -		case SIOCSIFADDR: -			if (!capable(CAP_NET_ADMIN)) -				return -EPERM; -			if (sa->sat_family != AF_APPLETALK) -				return -EINVAL; -			if (dev->type != ARPHRD_ETHER && -			    dev->type != ARPHRD_LOOPBACK && -			    dev->type != ARPHRD_LOCALTLK && -			    dev->type != ARPHRD_PPP) -				return -EPROTONOSUPPORT; - -			nr = (struct atalk_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 ((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"); -				add_route = 0; -			} - -			/* -			 * Phase 1 is fine on LocalTalk but we don't do -			 * EtherTalk phase 1. Anyone wanting to add it go ahead. -			 */ -			if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) -				return -EPROTONOSUPPORT; -			if (sa->sat_addr.s_node == ATADDR_BCAST || -			    sa->sat_addr.s_node == 254) -				return -EINVAL; -			if (atif) { -				/* Already setting address */ -				if (atif->status & ATIF_PROBE) -					return -EBUSY; - -				atif->address.s_net  = sa->sat_addr.s_net; -				atif->address.s_node = sa->sat_addr.s_node; -				atrtr_device_down(dev);	/* Flush old routes */ -			} else { -				atif = atif_add_device(dev, &sa->sat_addr); -				if (!atif) -					return -ENOMEM; -			} -			atif->nets = *nr; - -			/* -			 * Check if the chosen address is used. If so we -			 * error and atalkd will try another. -			 */ - -			if (!(dev->flags & IFF_LOOPBACK) && -			    !(dev->flags & IFF_POINTOPOINT) && -			    atif_probe_device(atif) < 0) { -				atif_drop_device(dev); -				return -EADDRINUSE; -			} +	case SIOCSIFADDR: +		if (!capable(CAP_NET_ADMIN)) +			return -EPERM; +		if (sa->sat_family != AF_APPLETALK) +			return -EINVAL; +		if (dev->type != ARPHRD_ETHER && +		    dev->type != ARPHRD_LOOPBACK && +		    dev->type != ARPHRD_LOCALTLK && +		    dev->type != ARPHRD_PPP) +			return -EPROTONOSUPPORT; + +		nr = (struct atalk_netrange *)&sa->sat_zero[0]; +		add_route = 1; -			/* 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; -			sa->sat_addr.s_node = atif->address.s_node; -			sa = (struct sockaddr_at *)&rtdef.rt_dst; -			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) -				rtdef.rt_flags |= RTF_HOST; - -			/* Routerless initial state */ -			if (nr->nr_firstnet == htons(0) && -			    nr->nr_lastnet == htons(0xFFFE)) { -				sa->sat_addr.s_net = atif->address.s_net; -				atrtr_create(&rtdef, dev); -				atrtr_set_default(dev); -			} else { -				limit = ntohs(nr->nr_lastnet); -				if (limit - ntohs(nr->nr_firstnet) > 4096) { -					printk(KERN_WARNING "Too many routes/" -							    "iface.\n"); -					return -EINVAL; -				} -				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_global(dev, aarp_mcast); -			return 0; +		/* +		 * 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"); +			add_route = 0; +		} -		case SIOCGIFADDR: +		/* +		 * Phase 1 is fine on LocalTalk but we don't do +		 * EtherTalk phase 1. Anyone wanting to add it go ahead. +		 */ +		if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) +			return -EPROTONOSUPPORT; +		if (sa->sat_addr.s_node == ATADDR_BCAST || +		    sa->sat_addr.s_node == 254) +			return -EINVAL; +		if (atif) { +			/* Already setting address */ +			if (atif->status & ATIF_PROBE) +				return -EBUSY; + +			atif->address.s_net  = sa->sat_addr.s_net; +			atif->address.s_node = sa->sat_addr.s_node; +			atrtr_device_down(dev);	/* Flush old routes */ +		} else { +			atif = atif_add_device(dev, &sa->sat_addr);  			if (!atif) -				return -EADDRNOTAVAIL; +				return -ENOMEM; +		} +		atif->nets = *nr; -			sa->sat_family = AF_APPLETALK; -			sa->sat_addr = atif->address; -			break; +		/* +		 * Check if the chosen address is used. If so we +		 * error and atalkd will try another. +		 */ -		case SIOCGIFBRDADDR: -			if (!atif) -				return -EADDRNOTAVAIL; +		if (!(dev->flags & IFF_LOOPBACK) && +		    !(dev->flags & IFF_POINTOPOINT) && +		    atif_probe_device(atif) < 0) { +			atif_drop_device(dev); +			return -EADDRINUSE; +		} -			sa->sat_family = AF_APPLETALK; +		/* 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; +		sa->sat_addr.s_node = atif->address.s_node; +		sa = (struct sockaddr_at *)&rtdef.rt_dst; +		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) +			rtdef.rt_flags |= RTF_HOST; + +		/* Routerless initial state */ +		if (nr->nr_firstnet == htons(0) && +		    nr->nr_lastnet == htons(0xFFFE)) {  			sa->sat_addr.s_net = atif->address.s_net; -			sa->sat_addr.s_node = ATADDR_BCAST; -			break; - -		case SIOCATALKDIFADDR: -		case SIOCDIFADDR: -			if (!capable(CAP_NET_ADMIN)) -				return -EPERM; -			if (sa->sat_family != AF_APPLETALK) -				return -EINVAL; -			atalk_dev_down(dev); -			break; - -		case SIOCSARP: -			if (!capable(CAP_NET_ADMIN)) -				return -EPERM; -			if (sa->sat_family != AF_APPLETALK) +			atrtr_create(&rtdef, dev); +			atrtr_set_default(dev); +		} else { +			limit = ntohs(nr->nr_lastnet); +			if (limit - ntohs(nr->nr_firstnet) > 4096) { +				printk(KERN_WARNING "Too many routes/" +				       "iface.\n");  				return -EINVAL; -			/* -			 * for now, we only support proxy AARP on ELAP; -			 * we should be able to do it for LocalTalk, too. -			 */ -			if (dev->type != ARPHRD_ETHER) -				return -EPROTONOSUPPORT; - -			/* -			 * 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. -			 */ -			if (!atif) -				return -EADDRNOTAVAIL; +			} +			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_global(dev, aarp_mcast); +		return 0; + +	case SIOCGIFADDR: +		if (!atif) +			return -EADDRNOTAVAIL; + +		sa->sat_family = AF_APPLETALK; +		sa->sat_addr = atif->address; +		break; + +	case SIOCGIFBRDADDR: +		if (!atif) +			return -EADDRNOTAVAIL; + +		sa->sat_family = AF_APPLETALK; +		sa->sat_addr.s_net = atif->address.s_net; +		sa->sat_addr.s_node = ATADDR_BCAST; +		break; + +	case SIOCATALKDIFADDR: +	case SIOCDIFADDR: +		if (!capable(CAP_NET_ADMIN)) +			return -EPERM; +		if (sa->sat_family != AF_APPLETALK) +			return -EINVAL; +		atalk_dev_down(dev); +		break; -			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. -			 */ -			if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) -				return -EPROTONOSUPPORT; +	case SIOCSARP: +		if (!capable(CAP_NET_ADMIN)) +			return -EPERM; +		if (sa->sat_family != AF_APPLETALK) +			return -EINVAL; +		/* +		 * for now, we only support proxy AARP on ELAP; +		 * we should be able to do it for LocalTalk, too. +		 */ +		if (dev->type != ARPHRD_ETHER) +			return -EPROTONOSUPPORT; -			if (sa->sat_addr.s_node == ATADDR_BCAST || -			    sa->sat_addr.s_node == 254) -				return -EINVAL; +		/* +		 * 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. +		 */ +		if (!atif) +			return -EADDRNOTAVAIL; -			/* -			 * Check if the chosen address is used. If so we -			 * error and ATCP will try another. -			 */ -			if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) -				return -EADDRINUSE; +		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. +		 */ +		if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) +			return -EPROTONOSUPPORT; -			/* -			 * 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; +		if (sa->sat_addr.s_node == ATADDR_BCAST || +		    sa->sat_addr.s_node == 254) +			return -EINVAL; -		case SIOCDARP: -			if (!capable(CAP_NET_ADMIN)) -				return -EPERM; -			if (sa->sat_family != AF_APPLETALK) -				return -EINVAL; -			if (!atif) -				return -EADDRNOTAVAIL; +		/* +		 * Check if the chosen address is used. If so we +		 * error and ATCP will try another. +		 */ +		if (atif_proxy_probe_device(atif, &(sa->sat_addr)) < 0) +			return -EADDRINUSE; -			/* give to aarp module to remove proxy entry */ -			aarp_proxy_remove(atif->dev, &(sa->sat_addr)); -			return 0; +		/* +		 * 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; + +	case SIOCDARP: +		if (!capable(CAP_NET_ADMIN)) +			return -EPERM; +		if (sa->sat_family != AF_APPLETALK) +			return -EINVAL; +		if (!atif) +			return -EADDRNOTAVAIL; + +		/* give to aarp module to remove proxy entry */ +		aarp_proxy_remove(atif->dev, &(sa->sat_addr)); +		return 0;  	}  	return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; @@ -885,25 +882,25 @@ static int atrtr_ioctl(unsigned int cmd, void __user *arg)  		return -EFAULT;  	switch (cmd) { -		case SIOCDELRT: -			if (rt.rt_dst.sa_family != AF_APPLETALK) -				return -EINVAL; -			return atrtr_delete(&((struct sockaddr_at *) -						&rt.rt_dst)->sat_addr); - -		case SIOCADDRT: { -			struct net_device *dev = NULL; -			if (rt.rt_dev) { -				char name[IFNAMSIZ]; -				if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) -					return -EFAULT; -				name[IFNAMSIZ-1] = '\0'; -				dev = __dev_get_by_name(&init_net, name); -				if (!dev) -					return -ENODEV; -			} -			return atrtr_create(&rt, dev); +	case SIOCDELRT: +		if (rt.rt_dst.sa_family != AF_APPLETALK) +			return -EINVAL; +		return atrtr_delete(&((struct sockaddr_at *) +				      &rt.rt_dst)->sat_addr); + +	case SIOCADDRT: { +		struct net_device *dev = NULL; +		if (rt.rt_dev) { +			char name[IFNAMSIZ]; +			if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1)) +				return -EFAULT; +			name[IFNAMSIZ-1] = '\0'; +			dev = __dev_get_by_name(&init_net, name); +			if (!dev) +				return -ENODEV;  		} +		return atrtr_create(&rt, dev); +	}  	}  	return -EINVAL;  } @@ -939,11 +936,11 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,  	int i, copy;  	/* checksum stuff in header space */ -	if ( (copy = start - offset) > 0) { +	if ((copy = start - offset) > 0) {  		if (copy > len)  			copy = len;  		sum = atalk_sum_partial(skb->data + offset, copy, sum); -		if ( (len -= copy) == 0) +		if ((len -= copy) == 0)  			return sum;  		offset += copy; @@ -952,20 +949,19 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,  	/* checksum stuff in frags */  	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {  		int end; - +		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];  		WARN_ON(start > offset + len); -		end = start + skb_shinfo(skb)->frags[i].size; +		end = start + skb_frag_size(frag);  		if ((copy = end - offset) > 0) {  			u8 *vaddr; -			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];  			if (copy > len)  				copy = len; -			vaddr = kmap_skb_frag(frag); +			vaddr = kmap_atomic(skb_frag_page(frag));  			sum = atalk_sum_partial(vaddr + frag->page_offset +  						  offset - start, copy, sum); -			kunmap_skb_frag(vaddr); +			kunmap_atomic(vaddr);  			if (!(len -= copy))  				return sum; @@ -1052,20 +1048,24 @@ static int atalk_release(struct socket *sock)  {  	struct sock *sk = sock->sk; -	lock_kernel();  	if (sk) { +		sock_hold(sk); +		lock_sock(sk); +  		sock_orphan(sk);  		sock->sk = NULL;  		atalk_destroy_socket(sk); + +		release_sock(sk); +		sock_put(sk);  	} -	unlock_kernel();  	return 0;  }  /**   * atalk_pick_and_bind_port - Pick a source port when one is not given - * @sk - socket to insert into the tables - * @sat - address to search for + * @sk: socket to insert into the tables + * @sat: address to search for   *   * Pick a source port when one is not given. If we can find a suitable free   * one, we insert the socket into the tables using it. @@ -1082,9 +1082,8 @@ static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat)  	     sat->sat_port < ATPORT_LAST;  	     sat->sat_port++) {  		struct sock *s; -		struct hlist_node *node; -		sk_for_each(s, node, &atalk_sockets) { +		sk_for_each(s, &atalk_sockets) {  			struct atalk_sock *at = at_sk(s);  			if (at->src_net == sat->sat_addr.s_net && @@ -1143,7 +1142,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)  	if (addr->sat_family != AF_APPLETALK)  		return -EAFNOSUPPORT; -	lock_kernel(); +	lock_sock(sk);  	if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) {  		struct atalk_addr *ap = atalk_find_primary(); @@ -1152,7 +1151,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)  			goto out;  		at->src_net  = addr->sat_addr.s_net = ap->s_net; -		at->src_node = addr->sat_addr.s_node= ap->s_node; +		at->src_node = addr->sat_addr.s_node = ap->s_node;  	} else {  		err = -EADDRNOTAVAIL;  		if (!atalk_find_interface(addr->sat_addr.s_net, @@ -1179,7 +1178,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)  	sock_reset_flag(sk, SOCK_ZAPPED);  	err = 0;  out: -	unlock_kernel(); +	release_sock(sk);  	return err;  } @@ -1206,16 +1205,14 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,  	if (addr->sat_addr.s_node == ATADDR_BCAST &&  	    !sock_flag(sk, SOCK_BROADCAST)) {  #if 1 -		printk(KERN_WARNING "%s is broken and did not set " -				    "SO_BROADCAST. It will break when 2.2 is " -				    "released.\n", +		pr_warn("atalk_connect: %s is broken and did not set SO_BROADCAST.\n",  			current->comm);  #else  		return -EACCES;  #endif  	} -	lock_kernel(); +	lock_sock(sk);  	err = -EBUSY;  	if (sock_flag(sk, SOCK_ZAPPED))  		if (atalk_autobind(sk) < 0) @@ -1233,7 +1230,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,  	sk->sk_state = TCP_ESTABLISHED;  	err = 0;  out: -	unlock_kernel(); +	release_sock(sk);  	return err;  } @@ -1249,14 +1246,14 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,  	struct atalk_sock *at = at_sk(sk);  	int err; -	lock_kernel(); +	lock_sock(sk);  	err = -ENOBUFS;  	if (sock_flag(sk, SOCK_ZAPPED))  		if (atalk_autobind(sk) < 0)  			goto out;  	*uaddr_len = sizeof(struct sockaddr_at); -	memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); +	memset(&sat, 0, sizeof(sat));  	if (peer) {  		err = -ENOTCONN; @@ -1277,17 +1274,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,  	memcpy(uaddr, &sat, sizeof(sat));  out: -	unlock_kernel(); -	return err; -} - -static unsigned int atalk_poll(struct file *file, struct socket *sock, -			   poll_table *wait) -{ -	int err; -	lock_kernel(); -	err = datagram_poll(file, sock, wait); -	unlock_kernel(); +	release_sock(sk);  	return err;  } @@ -1502,8 +1489,6 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,  		goto drop;  	/* Queue packet (standard) */ -	skb->sk = sock; -  	if (sock_queue_rcv_skb(sock, skb) < 0)  		goto drop; @@ -1579,7 +1564,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  {  	struct sock *sk = sock->sk;  	struct atalk_sock *at = at_sk(sk); -	struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; +	DECLARE_SOCKADDR(struct sockaddr_at *, usat, msg->msg_name);  	int flags = msg->msg_flags;  	int loopback = 0;  	struct sockaddr_at local_satalk, gsat; @@ -1596,7 +1581,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  	if (len > DDP_MAXSZ)  		return -EMSGSIZE; -	lock_kernel(); +	lock_sock(sk);  	if (usat) {  		err = -EBUSY;  		if (sock_flag(sk, SOCK_ZAPPED)) @@ -1651,11 +1636,12 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  			sk, size, dev->name);  	size += dev->hard_header_len; +	release_sock(sk);  	skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); +	lock_sock(sk);  	if (!skb)  		goto out; -	skb->sk = sk;  	skb_reserve(skb, ddp_dl->header_length);  	skb_reserve(skb, dev->hard_header_len);  	skb->dev = dev; @@ -1680,7 +1666,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  		goto out;  	} -	if (sk->sk_no_check == 1) +	if (sk->sk_no_check_tx)  		ddp->deh_sum = 0;  	else  		ddp->deh_sum = atalk_checksum(skb, len + sizeof(*ddp)); @@ -1738,7 +1724,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  	SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len);  out: -	unlock_kernel(); +	release_sock(sk);  	return err ? : len;  } @@ -1746,16 +1732,16 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  			 size_t size, int flags)  {  	struct sock *sk = sock->sk; -	struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;  	struct ddpehdr *ddp;  	int copied = 0;  	int offset = 0;  	int err = 0;  	struct sk_buff *skb; -	lock_kernel();  	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,  						flags & MSG_DONTWAIT, &err); +	lock_sock(sk); +  	if (!skb)  		goto out; @@ -1774,20 +1760,19 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr  	}  	err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); -	if (!err) { -		if (sat) { -			sat->sat_family      = AF_APPLETALK; -			sat->sat_port        = ddp->deh_sport; -			sat->sat_addr.s_node = ddp->deh_snode; -			sat->sat_addr.s_net  = ddp->deh_snet; -		} -		msg->msg_namelen = sizeof(*sat); +	if (!err && msg->msg_name) { +		DECLARE_SOCKADDR(struct sockaddr_at *, sat, msg->msg_name); +		sat->sat_family      = AF_APPLETALK; +		sat->sat_port        = ddp->deh_sport; +		sat->sat_addr.s_node = ddp->deh_snode; +		sat->sat_addr.s_net  = ddp->deh_snet; +		msg->msg_namelen     = sizeof(*sat);  	}  	skb_free_datagram(sk, skb);	/* Free the datagram. */  out: -	unlock_kernel(); +	release_sock(sk);  	return err ? : copied;  } @@ -1802,53 +1787,53 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)  	void __user *argp = (void __user *)arg;  	switch (cmd) { -		/* Protocol layer */ -		case TIOCOUTQ: { -			long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); - -			if (amount < 0) -				amount = 0; -			rc = put_user(amount, (int __user *)argp); -			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->sk_receive_queue); -			long amount = 0; +	/* Protocol layer */ +	case TIOCOUTQ: { +		long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk); + +		if (amount < 0) +			amount = 0; +		rc = put_user(amount, (int __user *)argp); +		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->sk_receive_queue); +		long amount = 0; -			if (skb) -				amount = skb->len - sizeof(struct ddpehdr); -			rc = put_user(amount, (int __user *)argp); -			break; -		} -		case SIOCGSTAMP: -			rc = sock_get_timestamp(sk, argp); -			break; -		case SIOCGSTAMPNS: -			rc = sock_get_timestampns(sk, argp); -			break; -		/* Routing */ -		case SIOCADDRT: -		case SIOCDELRT: -			rc = -EPERM; -			if (capable(CAP_NET_ADMIN)) -				rc = atrtr_ioctl(cmd, argp); -			break; -		/* Interface */ -		case SIOCGIFADDR: -		case SIOCSIFADDR: -		case SIOCGIFBRDADDR: -		case SIOCATALKDIFADDR: -		case SIOCDIFADDR: -		case SIOCSARP:		/* proxy AARP */ -		case SIOCDARP:		/* proxy AARP */ -			rtnl_lock(); -			rc = atif_ioctl(cmd, argp); -			rtnl_unlock(); -			break; +		if (skb) +		amount = skb->len - sizeof(struct ddpehdr); +		rc = put_user(amount, (int __user *)argp); +		break; +	} +	case SIOCGSTAMP: +		rc = sock_get_timestamp(sk, argp); +		break; +	case SIOCGSTAMPNS: +		rc = sock_get_timestampns(sk, argp); +		break; +	/* Routing */ +	case SIOCADDRT: +	case SIOCDELRT: +		rc = -EPERM; +		if (capable(CAP_NET_ADMIN)) +			rc = atrtr_ioctl(cmd, argp); +		break; +	/* Interface */ +	case SIOCGIFADDR: +	case SIOCSIFADDR: +	case SIOCGIFBRDADDR: +	case SIOCATALKDIFADDR: +	case SIOCDIFADDR: +	case SIOCSARP:		/* proxy AARP */ +	case SIOCDARP:		/* proxy AARP */ +		rtnl_lock(); +		rc = atif_ioctl(cmd, argp); +		rtnl_unlock(); +		break;  	}  	return rc; @@ -1887,7 +1872,7 @@ static const struct proto_ops atalk_dgram_ops = {  	.socketpair	= sock_no_socketpair,  	.accept		= sock_no_accept,  	.getname	= atalk_getname, -	.poll		= atalk_poll, +	.poll		= datagram_poll,  	.ioctl		= atalk_ioctl,  #ifdef CONFIG_COMPAT  	.compat_ioctl	= atalk_compat_ioctl, diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c index 04e9c0da7aa..ebb864361f7 100644 --- a/net/appletalk/sysctl_net_atalk.c +++ b/net/appletalk/sysctl_net_atalk.c @@ -42,20 +42,14 @@ static struct ctl_table atalk_table[] = {  	{ },  }; -static struct ctl_path atalk_path[] = { -	{ .procname = "net", }, -	{ .procname = "appletalk", }, -	{ } -}; -  static struct ctl_table_header *atalk_table_header;  void atalk_register_sysctl(void)  { -	atalk_table_header = register_sysctl_paths(atalk_path, atalk_table); +	atalk_table_header = register_net_sysctl(&init_net, "net/appletalk", atalk_table);  }  void atalk_unregister_sysctl(void)  { -	unregister_sysctl_table(atalk_table_header); +	unregister_net_sysctl_table(atalk_table_header);  }  | 
