[733] in linux-net channel archive

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

Fix forwarding, SNMP and maybe broken ring

daemon@ATHENA.MIT.EDU (A.Cox)
Thu Jul 20 01:11:43 1995

Date: Tue, 18 Jul 95 23:04 BST
From: anarchy@thunder.swansea.linux.org.uk (A.Cox)
To: linux-net3@www.linux.org.uk, linux-net@vger.rutgers.edu,
        torvalds@cs.helsinki.fi

*
*	Fix IP forwarding.
*	Fix SNMP counts up.
*	Remove masquerading compile warn.
*	Possibly fix token ring (I dont have a broken ring to check).
*

--- include/linux/trdevice.h.old	Wed Jul 19 00:40:55 1995
+++ include/linux/trdevice.h	Wed Jul 19 00:41:09 1995
@@ -28,9 +28,9 @@
 #include <linux/if_tr.h>
 
 #ifdef __KERNEL__
-extern int		tr_header(unsigned char *buff, struct device *dev,
+extern int		tr_header(struct sk_buff *skb, struct device *dev,
 				   unsigned short type, void *daddr,
-				   void *saddr, unsigned len, struct sk_buff *skb);
+				   void *saddr, unsigned len);
 extern int		tr_rebuild_header(void *buff, struct device *dev,
 			unsigned long raddr, struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct device *dev);
--- net/802/tr.c.old	Wed Jul 19 00:40:26 1995
+++ net/802/tr.c	Wed Jul 19 00:40:26 1995
@@ -38,11 +38,12 @@
 #define RIF_CHECK_INTERVAL 60*HZ
 static struct timer_list rif_timer={ NULL,NULL,RIF_CHECK_INTERVAL,0L,rif_check_expire };
 
-int tr_header(unsigned char *buff, struct device *dev, unsigned short type,
-              void *daddr, void *saddr, unsigned len, struct sk_buff *skb) {
+int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+              void *daddr, void *saddr, unsigned len) 
+{
 
 	struct trh_hdr *trh=(struct trh_hdr *)skb_push(skb,dev->hard_header_len);
-	struct trllc *trllc=(struct trllc *)(buff+sizeof(struct trh_hdr));
+	struct trllc *trllc=(struct trllc *)(trh+1);
 
 	trh->ac=AC;
 	trh->fc=LLC_FRAME;
@@ -91,6 +92,8 @@
 
 	struct trh_hdr *trh=(struct trh_hdr *)skb->data;
 	struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr));
+	
+	skb->mac.raw = skb->data;
 	
 	skb_pull(skb,dev->hard_header_len);
 	
--- net/core/dev.c.old	Tue Jul 18 22:48:10 1995
+++ net/core/dev.c	Tue Jul 18 22:48:10 1995
@@ -172,6 +172,7 @@
 			return;
 		}
 	}
+	printk("dev_remove_pack: %p not found.\n", pt);
 }
 
 /*****************************************************************************************
--- net/ipv4/ip.c.old	Wed Jul 19 00:11:49 1995
+++ net/ipv4/ip.c	Wed Jul 19 00:32:05 1995
@@ -85,6 +85,8 @@
  *	Dave Bonn,Alan Cox	:	Faster IP forwarding whenever possible.
  *		Alan Cox	:	Memory leaks, tramples, misc debugging.
  *		Alan Cox	:	Fixed multicast (by popular demand 8))
+ *		Alan Cox	:	Fixed forwarding (by even more popular demand 8))
+ *		Alan Cox	:	Fixed SNMP statistics [I think]
  *
  *  
  *
@@ -1139,7 +1141,7 @@
 	 */
 
 	dev2 = rt->rt_dev;
-
+	
 	/*
 	 *	In IP you never have to forward a frame on the interface that it 
 	 *	arrived upon. We now generate an ICMP HOST REDIRECT giving the route
@@ -1165,33 +1167,35 @@
 		if (!(is_frag&4) && fw_res==2)
 			ip_fw_masquerade(&skb, dev2);
 #endif
+		IS_SKB(skb);
 
 		if(skb_headroom(skb)<dev2->hard_header_len)
+		{
 			skb2 = alloc_skb(dev2->hard_header_len + skb->len + 15, GFP_ATOMIC);
-		else skb2=skb;
+			IS_SKB(skb2);
 		
-		/*
-		 *	This is rare and since IP is tolerant of network failures
-		 *	quite harmless.
-		 */
+			/*
+			 *	This is rare and since IP is tolerant of network failures
+			 *	quite harmless.
+			 */
 		
-		if (skb2 == NULL)
-		{
-			NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
-			return -1;
-		}
+			if (skb2 == NULL)
+			{
+				NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
+				return -1;
+			}
 		
+			/*
+			 *	Add the physical headers.
+			 */
 
-		/* Now build the MAC header. */
-		(void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
+		 	ip_send(skb2,raddr,skb->len,dev2,dev2->pa_addr);
 
-		/*
-		 *	We have to copy the bytes over as the new header wouldn't fit
-		 *	the old buffer. This should be very rare.
-		 */
-		 
-		if(skb2!=skb)
-		{
+			/*
+			 *	We have to copy the bytes over as the new header wouldn't fit
+			 *	the old buffer. This should be very rare.
+			 */		 
+		 	
 			ptr = skb_put(skb2,skb->len);
 			skb2->free = 1;
 			skb2->h.raw = ptr;
@@ -1201,9 +1205,22 @@
 			 */
 			memcpy(ptr, skb->h.raw, skb->len);
 		}
+		else
+		{
+			/* 
+			 *	Build a new MAC header. 
+			 */
 
-		ip_statistics.IpForwDatagrams++;
-
+			skb2 = skb;		
+			skb2->dev=dev2;
+			skb->arp=1;
+			if(dev->hard_header)
+			{
+				if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
+					skb->arp=0;
+			}
+			ip_statistics.IpForwDatagrams++;
+		}
 		/*
 		 *	See if it needs fragmenting. Note in ip_rcv we tagged
 		 *	the fragment type. This must be right so that
@@ -2347,6 +2364,7 @@
 	struct iphdr *iph;
 	int local=0;
 	struct device *dev;
+	int nfrags=0;
 	
 	ip_statistics.IpOutRequests++;
 
@@ -2437,7 +2455,10 @@
 		int error;
 		struct sk_buff *skb=sock_alloc_send_skb(sk, length+20+15+dev->hard_header_len,0,&error);
 		if(skb==NULL)
+		{
+			ip_statistics.IpOutDiscards++;
 			return error;
+		}
 		skb->dev=dev;
 		skb->free=1;
 		skb->when=jiffies;
@@ -2555,8 +2576,13 @@
 
 		skb = sock_alloc_send_skb(sk, fraglen+15, 0, &error);
 		if (skb == NULL)
+		{
+			ip_statistics.IpOutDiscards++;
+			if(nfrags>1)
+				ip_statistics.IpFragCreates++;			
 			return(error);
-
+		}
+		
 		/*
 		 *	Fill in the control structures
 		 */
@@ -2689,6 +2715,9 @@
 				kfree_skb(skb, FREE_READ);
 		}
 #endif
+
+		nfrags++;
+		
 		/*
 		 *	BSD loops broadcasts
 		 */
@@ -2715,12 +2744,15 @@
 			 */
 			 
 			ip_statistics.IpOutDiscards++;
+			if(nfrags>1)
+				ip_statistics.IpFragCreates+=nfrags;
 			kfree_skb(skb, FREE_WRITE);
 			return(0); /* lose rest of fragments */
 		}
 	} 
 	while (offset >= 0);
-	
+	if(nfrags>1)
+		ip_statistics.IpFragCreates+=nfrags;
 	return(0);
 }
     
--- net/ipv4/ip_fw.c~	Tue Jul 18 22:24:06 1995
+++ net/ipv4/ip_fw.c	Tue Jul 18 22:24:06 1995
@@ -1483,7 +1483,7 @@
 		int timer_active = del_timer(&ms->timer);
 		if (!timer_active)
 			ms->timer.expires = 0;
-		len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08lX %5d %lu\n",
+		len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %lu\n",
 			strProt[ms->protocol==IPPROTO_TCP],
 			ntohl(ms->src),ntohs(ms->sport),
 			ntohl(ms->dst),ntohs(ms->dport),
--- net/ipv4/ip.c~	Wed Jul 19 00:54:27 1995
+++ net/ipv4/ip.c	Wed Jul 19 00:54:27 1995
@@ -1214,6 +1214,7 @@
 			skb2 = skb;		
 			skb2->dev=dev2;
 			skb->arp=1;
+			skb->raddr=raddr;
 			if(dev->hard_header)
 			{
 				if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)

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