[718] in linux-net channel archive

home help back first fref pref prev next nref lref last post

More bug fixes

daemon@ATHENA.MIT.EDU (A.Cox)
Tue Jul 18 19:32:14 1995

Date: Mon, 17 Jul 95 22:06 BST
From: anarchy@thunder.swansea.linux.org.uk (A.Cox)
To: linux-net3@www.linux.org.uk, linux-net@vger.rutgers.edu,
        torvalds@linux.helsinki.fi


*
*	Fix the AX.25 crashes when running digipeated VC sessions
*	Allow TCP to cope with route changes. 
*	[Linus, it should be safe to merge the infinite SLIP channel patch now]
*	Clean up header lengths
*	Ought to fix masquerade of ftp crashes (untested).
*
*
*	Known bugs outstanding that need fixing before the next stage of code
*	merging.
*
*		Token ring is broken
*		One odd crash while forwarding with skb_put panic - cause
*			still a mystery
*		IPX bug reports
*		TCP syn not resetting close_wait connections
*

--- drivers/net/slip.c.old	Mon Jul 17 21:49:32 1995
+++ drivers/net/slip.c	Mon Jul 17 21:50:28 1995
@@ -36,6 +36,7 @@
  *                                      statistics. Include CSLIP code only
  *                                      if it really needed.
  *		Alan Cox	:	Free slhc buffers in the right place.
+ *		Alan Cox	:	Allow for digipeated IP over AX.25
  *
  *
  *
@@ -1014,7 +1015,7 @@
 #else
 		if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) {
 			sl->dev->addr_len=AX25_ADDR_LEN;	  /* sizeof an AX.25 addr */
-			sl->dev->hard_header_len=AX25_HEADER_LEN; /* We don't do digipeaters */
+			sl->dev->hard_header_len=73; /* We don't do digipeaters */
 		} else	{
 			sl->dev->addr_len=0;	/* No mac addr in slip mode */
 			sl->dev->hard_header_len=0;
--- drivers/net/pi2.c.old	Mon Jul 17 21:49:15 1995
+++ drivers/net/pi2.c	Mon Jul 17 21:49:15 1995
@@ -49,6 +49,7 @@
    April 23, 1995 (dp) Fixed ioctl so it works properly with piconfig program
                        when changing the baud rate or clock mode.
                        version 0.8 ALPHA
+   July 17, 1995 (ac)  Finally polishing of AX25.030+ support
          
 */
 
@@ -59,7 +60,7 @@
    of each transmitted packet. If this causes you to lose sleep, #undefine it.
 */
 
-#define STUFF2 1
+/*#define STUFF2 1*/
 
 /* The default configuration */
 #define PI_DMA 3
@@ -1429,10 +1430,10 @@
     dev->rebuild_header = pi_rebuild_header;
     dev->set_mac_address = pi_set_mac_address;
 
-    dev->type = ARPHRD_AX25;	/* AF_AX25 device */
-    dev->hard_header_len = 17;	/* We don't do digipeaters */
-    dev->mtu = 1500;		/* eth_mtu is the default */
-    dev->addr_len = 7;		/* sizeof an ax.25 address */
+    dev->type = ARPHRD_AX25;			/* AF_AX25 device */
+    dev->hard_header_len = 73;			/* We do digipeaters now */
+    dev->mtu = 1500;				/* eth_mtu is the default */
+    dev->addr_len = 7;				/* sizeof an ax.25 address */
     memcpy(dev->broadcast, ax25_bcast, 7);
     memcpy(dev->dev_addr, ax25_test, 7);
 
--- tcp.c.old	Wed Jul 12 22:16:06 1995
+++ tcp.c	Mon Jul 17 21:41:10 1995
@@ -145,6 +145,9 @@
  *					sk->retransmits misupdating fixed.
  *					Fixed tcp_write_timeout: stuck close,
  *					and TCP syn retries gets used now.
+ *		Alan Cox	:	Look up device on a retransmit - routes may
+ *					change. Doesn't yet cope with MSS shrink right
+ *					but its a start!
  *
  *
  * To Fix:
@@ -439,6 +442,7 @@
 	struct proto *prot;
 	struct device *dev;
 	int ct=0;
+	struct rtable *rt;
 
 	prot = sk->prot;
 	skb = sk->send_head;
@@ -454,6 +458,12 @@
 		skb->when = jiffies;
 
 		/*
+		 *	Discard the surplus MAC header
+		 */
+		 
+		skb_pull(skb,((unsigned char *)skb->ip_hdr)-skb->data);
+
+		/*
 		 * In general it's OK just to use the old packet.  However we
 		 * need to use the current ack and window fields.  Urg and
 		 * urg_ptr could possibly stand to be updated as well, but we
@@ -462,60 +472,89 @@
 		 * changing the packet, we have to issue a new IP identifier.
 		 */
 
-		iph = (struct iphdr *)(skb->data + dev->hard_header_len);
+		iph = (struct iphdr *)skb->data;
 		th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2));
-		size = skb->len - (((unsigned char *) th) - skb->data);
+		size = ntohs(iph->tot_len) - (iph->ihl<<2);
 		
 		/*
 		 *	Note: We ought to check for window limits here but
 		 *	currently this is done (less efficiently) elsewhere.
-		 *	We do need to check for a route change but can't handle
-		 *	that until we have the new 1.3.x buffers in.
-		 *
 		 */
 
 		iph->id = htons(ip_id_count++);
 		ip_send_check(iph);
-
-		/*
-		 *	This is not the right way to handle this. We have to
-		 *	issue an up to date window and ack report with this 
-		 *	retransmit to keep the odd buggy tcp that relies on 
-		 *	the fact BSD does this happy. 
-		 *	We don't however need to recalculate the entire 
-		 *	checksum, so someone wanting a small problem to play
-		 *	with might like to implement RFC1141/RFC1624 and speed
-		 *	this up by avoiding a full checksum.
-		 */
-		 
-		th->ack_seq = ntohl(sk->acked_seq);
-		th->window = ntohs(tcp_select_window(sk));
-		tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
 		
 		/*
-		 *	If the interface is (still) up and running, kick it.
+		 *	Put a MAC header back on (may cause ARPing)
 		 */
-
-		if (dev->flags & IFF_UP)
+		 
+		if(skb->localroute)
+			rt=ip_rt_local(iph->daddr,NULL,NULL);
+		else
+			rt=ip_rt_route(iph->daddr,NULL,NULL);
+			
+		if(rt==NULL)	/* Deep poo */
 		{
+			if(skb->sk)
+			{
+				skb->sk->err=ENETUNREACH;
+				skb->sk->error_report(skb->sk);
+			}
+		}
+		else
+		{
+			dev=rt->rt_dev;
+			skb->raddr=rt->rt_gateway;
+			if(skb->raddr==0)
+				skb->raddr=iph->daddr;
+			skb->dev=dev;
+			skb->arp=1;
+			if(dev->hard_header)
+			{
+				if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
+					skb->arp=0;
+			}
+		
 			/*
-			 *	If the packet is still being sent by the device/protocol
-			 *	below then don't retransmit. This is both needed, and good -
-			 *	especially with connected mode AX.25 where it stops resends
-			 *	occurring of an as yet unsent anyway frame!
-			 *	We still add up the counts as the round trip time wants
-			 *	adjusting.
+			 *	This is not the right way to handle this. We have to
+			 *	issue an up to date window and ack report with this 
+			 *	retransmit to keep the odd buggy tcp that relies on 
+			 *	the fact BSD does this happy. 
+			 *	We don't however need to recalculate the entire 
+			 *	checksum, so someone wanting a small problem to play
+			 *	with might like to implement RFC1141/RFC1624 and speed
+			 *	this up by avoiding a full checksum.
 			 */
-			if (sk && !skb_device_locked(skb))
+		 
+			th->ack_seq = ntohl(sk->acked_seq);
+			th->window = ntohs(tcp_select_window(sk));
+			tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
+		
+			/*
+			 *	If the interface is (still) up and running, kick it.
+			 */
+	
+			if (dev->flags & IFF_UP)
 			{
-				/* Remove it from any existing driver queue first! */
-				skb_unlink(skb);
-				/* Now queue it */
-				ip_statistics.IpOutRequests++;
-				dev_queue_xmit(skb, dev, sk->priority);
+				/*
+				 *	If the packet is still being sent by the device/protocol
+				 *	below then don't retransmit. This is both needed, and good -
+				 *	especially with connected mode AX.25 where it stops resends
+				 *	occurring of an as yet unsent anyway frame!
+				 *	We still add up the counts as the round trip time wants
+				 *	adjusting.
+				 */
+				if (sk && !skb_device_locked(skb))
+				{
+					/* Remove it from any existing driver queue first! */
+					skb_unlink(skb);
+					/* Now queue it */
+					ip_statistics.IpOutRequests++;
+					dev_queue_xmit(skb, dev, sk->priority);
+				}
 			}
 		}
-
+		
 		/*
 		 *	Count retransmissions
 		 */
@@ -3034,8 +3073,7 @@
  * Ack and window will in general have changed since this packet was put
  * on the write queue.
  */
-			iph = (struct iphdr *)(skb->data +
-					       skb->dev->hard_header_len);
+			iph = skb->ip_hdr;
 			th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
 			size = skb->len - (((unsigned char *) th) - skb->data);
 			
--- include/linux/netdevice.h.old	Mon Jul 17 21:54:03 1995
+++ include/linux/netdevice.h	Mon Jul 17 21:54:03 1995
@@ -31,7 +31,11 @@
 /* for future expansion when we will have different priorities. */
 #define DEV_NUMBUFFS	3
 #define MAX_ADDR_LEN	7
-#define MAX_HEADER	38
+#ifndef CONFIG_AX25
+#define MAX_HEADER	32		/* We really need about 18 worst case .. so 32 is aligned */
+#else
+#define MAX_HEADER	96		/* AX.25 + NetROM */
+#endif
 
 #define IS_MYADDR	1		/* address is (one of) our own	*/
 #define IS_LOOPBACK	2		/* address is for LOOPBACK	*/
--- ip_fw.c~	Mon Jul 17 23:52:47 1995
+++ ip_fw.c	Mon Jul 17 23:52:47 1995
@@ -733,7 +733,7 @@
  		if (portptr[1]==htons(21)) 
  		{
  			skb = revamp(*skb_ptr, dev, ms);
- 			skb = *skb_ptr;
+ 			*skb_ptr = skb;
  			iph = skb->h.iph;
  			portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
  		}
--- ip.c.ook	Tue Jul 18 00:15:32 1995
+++ ip.c	Tue Jul 18 00:15:32 1995
@@ -201,6 +201,26 @@
 	return mac;
 }
 
+static int ip_send_room(struct sk_buff *skb, unsigned long daddr, int len, struct device *dev, unsigned long saddr)
+{
+	int mac = 0;
+
+	skb->dev = dev;
+	skb->arp = 1;
+	if (dev->hard_header)
+	{
+		skb_reserve(skb,MAX_HEADER);
+		mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
+		if (mac < 0)
+		{
+			mac = -mac;
+			skb->arp = 0;
+			skb->raddr = daddr;	/* next routing address */
+		}
+	}
+	return mac;
+}
+
 int ip_id_count = 0;
 
 /*
@@ -283,7 +303,10 @@
 	 *	Now build the MAC header.
 	 */
 
-	tmp = ip_send(skb, raddr, len, *dev, saddr);
+	if(type==IPPROTO_TCP)
+		tmp = ip_send_room(skb, raddr, len, *dev, saddr);
+	else
+		tmp = ip_send(skb, raddr, len, *dev, saddr);
 
 	/*
 	 *	Book keeping
--- route.c.old	Tue Jul 18 00:09:23 1995
+++ route.c	Tue Jul 18 00:10:43 1995
@@ -30,6 +30,7 @@
  *		Alan Cox	:	TCP irtt support.
  *		Jonathan Naylor	:	Added Metric support.
  *	Miquel van Smoorenburg	:	BSD API fixes.
+ *		Alan Cox	: 	Disallow route add xxx dev yyy when yyy is down
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -396,6 +397,8 @@
 		putname(devname);
 		if (!dev)
 			return -EINVAL;
+		if(!(dev->flags&IFF_UP))
+			return -ENXIO;
 	}
 	
 	/*


home help back first fref pref prev next nref lref last post