patch-2.1.67 linux/net/appletalk/ddp.c

Next file: linux/net/sunrpc/clnt.c
Previous file: linux/net/appletalk/aarp.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.66/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
@@ -54,10 +54,11 @@
 #include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
-#include <linux/route.h>
-#include <linux/inet.h>
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
+/*#include <linux/inetdevice.h> -- coming soon */
+#include <linux/route.h>
+#include <linux/inet.h>
 #include <linux/etherdevice.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
@@ -268,12 +269,12 @@
 			*iface = tmp->next;
 			kfree_s(tmp, sizeof(struct atalk_iface));
 			dev->atalk_ptr=NULL;
+			MOD_DEC_USE_COUNT;
 		}
 		else
 			iface = &tmp->next;
 	}
 
-	MOD_DEC_USE_COUNT;
 }
 
 static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa)
@@ -301,49 +302,42 @@
 }
 
 /*
+ * Probe a Phase 1 device or a device that requires its Net:Node to
+ * be set via an ioctl.
+ */
+void atif_send_probe_phase1(struct atalk_iface *iface)
+{
+        struct ifreq atreq;
+        struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
+
+        sa->sat_addr.s_node = iface->address.s_node;
+        sa->sat_addr.s_net  = ntohs(iface->address.s_net);
+
+         /* We pass the Net:Node to the drivers/cards by a Device ioctl. */
+        if(!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR)))
+        {
+                (void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR);
+                if((iface->address.s_net != htons(sa->sat_addr.s_net))
+			|| (iface->address.s_node != sa->sat_addr.s_node))
+                        iface->status |= ATIF_PROBE_FAIL;
+
+                iface->address.s_net  = htons(sa->sat_addr.s_net);
+		iface->address.s_node = sa->sat_addr.s_node;
+        }
+
+        return;
+}
+
+/*
  * Perform phase 2 AARP probing on our tentative address.
  */
 static int atif_probe_device(struct atalk_iface *atif)
 {
-	int ct;
 	int netrange=ntohs(atif->nets.nr_lastnet)-ntohs(atif->nets.nr_firstnet)+1;
 	int probe_net=ntohs(atif->address.s_net);
 	int probe_node=atif->address.s_node;
-	int netct;
-	int nodect;
-
-	struct ifreq atreq;
-	struct sockaddr_at *sa;
-	int err;
+	int ct, netct, nodect;
 
-/*
- *	THIS IS A HACK: Farallon cards want to do their own picking of
- *	addresses. This needs tidying up when someone does localtalk
- *	drivers
- */
-
-	if((atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP)
-		&& atif->dev->do_ioctl)
-	{
-		/* fake up the request and pass it down */
-		sa = (struct sockaddr_at*)&atreq.ifr_addr;
-		sa->sat_addr.s_node = probe_node;
-        	sa->sat_addr.s_net  = probe_net;
-		if(!(err=atif->dev->do_ioctl(atif->dev,&atreq,SIOCSIFADDR)))
-		{
-			(void)atif->dev->do_ioctl(atif->dev,&atreq,SIOCGIFADDR);
-			atif->address.s_net=htons(sa->sat_addr.s_net);
-			atif->address.s_node=sa->sat_addr.s_node;
-			return (0);
-		}
-		/*
-		 *	If it didn't like our faked request then fail:
-		 *	This should check against -ENOIOCTLCMD and fall
-		 *	through. That needs us to fix all the devices up
-		 *	properly. We can then also dump the localtalk test.
-		 */
-		return (err);
-	}
 	/*
 	 * Offset the network we start probing with.
 	 */
@@ -378,17 +372,23 @@
 				/*
 				 * Probe a proposed address.
 				 */
-				for(ct = 0; ct < AARP_RETRANSMIT_LIMIT; ct++)
-				{
-					aarp_send_probe(atif->dev, &atif->address);
-					/*
-					 * Defer 1/10th
-					 */
-					current->timeout = jiffies + (HZ/10);
-					current->state = TASK_INTERRUPTIBLE;
-					schedule();
-					if(atif->status & ATIF_PROBE_FAIL)
-						break;
+
+				if(atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP)
+                                        atif_send_probe_phase1(atif);
+                                else
+                                {
+					for(ct = 0; ct < AARP_RETRANSMIT_LIMIT; ct++)
+					{
+						aarp_send_probe(atif->dev, &atif->address);
+						/*
+						 * Defer 1/10th
+						 */
+						current->timeout = jiffies + (HZ/10);
+						current->state = TASK_INTERRUPTIBLE;
+						schedule();
+						if(atif->status & ATIF_PROBE_FAIL)
+							break;
+					}
 				}
 				if(!(atif->status & ATIF_PROBE_FAIL))
 					return (0);
@@ -664,6 +664,16 @@
 }
 
 /*
+ * Actually down the interface.
+ */
+static inline void atalk_dev_down(struct device *dev)
+{
+	atrtr_device_down(dev);	/* Remove all routes for the device */
+	aarp_device_down(dev);	/* Remove AARP entries for the device */
+	atif_drop_device(dev);	/* Remove the device */
+}
+
+/*
  * A device event has occurred. Watch for devices going down and
  * delete our use of them (iface and route).
  */
@@ -672,8 +682,7 @@
 	if(event == NETDEV_DOWN)
 	{
 		/* Discard any use of this */
-		atrtr_device_down((struct device *)ptr);
-		atif_drop_device((struct device *)ptr);
+	        atalk_dev_down((struct device *) ptr);
 	}
 
 	return (NOTIFY_DONE);
@@ -820,14 +829,12 @@
 			break;
 
 	        case SIOCATALKDIFADDR:
+	        case SIOCDIFADDR:
 			if(!suser())
 				return (-EPERM);
 			if(sa->sat_family != AF_APPLETALK)
 				return (-EINVAL);
-			if(atif == NULL)
-				return (-EADDRNOTAVAIL);
-			atrtr_device_down(atif->dev);
-			atif_drop_device(atif->dev);
+			atalk_dev_down(dev);
 			break;			
 	}
 
@@ -1431,6 +1438,7 @@
 		skb_pull(skb, 13);
 		skb->dev = dev;
 		skb->h.raw = skb->data;
+		skb->nh.raw = skb->data;
 
 	/*	printk("passing up ipddp, 0x%02x better be 45\n",skb->data[0]);
 	 *	printk("tot_len %d, skb->len %d\n",
@@ -1821,6 +1829,7 @@
 		case SIOCSIFADDR:
 		case SIOCGIFBRDADDR:
 		case SIOCATALKDIFADDR:
+		case SIOCDIFADDR:
 			return (atif_ioctl(cmd,(void *)arg));
 
 		/*
@@ -1834,10 +1843,12 @@
 		case SIOCGIFMTU:
 		case SIOCGIFCONF:
 		case SIOCADDMULTI:
-		case SIOCDELMULTI:
+		case SIOCDELMULTI:		
 		case SIOCGIFCOUNT:
-		case SIOGIFINDEX:
-		case SIOGIFNAME:
+#if 0			/* Also coming in the IP merge */
+		case SIOCGIFINDEX:
+#endif		
+		case SIOCGIFNAME:
 			return ((dev_ioctl(cmd,(void *) arg)));
 
 		case SIOCSIFMETRIC:
@@ -1984,18 +1995,6 @@
 }
 
 /*
- * Actually down the interface.
- */
-static void atalk_iface_down(struct atalk_iface *iface)
-{
-	atrtr_device_down(iface->dev);	/* Remove all routes for the device */
-	aarp_device_down(iface->dev);	/* Remove AARP entries for the device */
-	atif_drop_device(iface->dev);	/* Remove the device */
-
-	return;
-}
-
-/*
  * Note on MOD_{INC,DEC}_USE_COUNT:
  *
  * Use counts are incremented/decremented when
@@ -2010,16 +2009,6 @@
 
 void cleanup_module(void)
 {
-	struct atalk_iface *ifaces = atalk_iface_list, *tmp;
-
-        while(ifaces != NULL)
-        {
-                tmp = ifaces->next;
-                ifaces->dev->atalk_ptr = NULL;
-                atalk_iface_down(ifaces);
-                ifaces = tmp;
-        }
-
 #ifdef CONFIG_SYSCTL
 	atalk_unregister_sysctl();
 #endif /* CONFIG_SYSCTL */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov