[3722] in linux-net channel archive

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

Bugs in Net code

daemon@ATHENA.MIT.EDU (Alan Cox)
Tue Jul 16 13:59:28 1996

Date: 	Tue, 16 Jul 96 12:37 BST
From: iialan@iifeak.swan.ac.uk (Alan Cox)
To: linux-kernel@vger.rutgers.edu, linux-net@vger.rutgers.edu


Can people having problems with multicast routing and tunnels try this diff and
see how it goes. Its a combo of patches several people have sent in. Also
contains the extra bridge fix.

Alan

diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/drivers/net/new_tunnel.c linux/drivers/net/new_tunnel.c
--- linux.vanilla/drivers/net/new_tunnel.c	Sun Jun  9 13:12:13 1996
+++ linux/drivers/net/new_tunnel.c	Mon Jul 15 22:53:01 1996
@@ -233,8 +233,9 @@
 printk("Room left at tail: %d\n", skb_tailroom(skb));
 printk("Required room: %d, Tunnel hlen: %d\n", max_headroom, TUNL_HLEN);
 #endif
-	if (skb_headroom(skb) >= max_headroom) {
+	if (skb_headroom(skb) >= max_headroom && skb->free) {
 		skb->h.iph = (struct iphdr *) skb_push(skb, tunnel_hlen);
+		skb_device_unlock(skb);
 	} else {
 		struct sk_buff *new_skb;
 
@@ -289,7 +290,7 @@
 	iph->tot_len		=	htons(skb->len);
 	iph->id			=	htons(ip_id_count++);	/* Race condition here? */
 	ip_send_check(iph);
-	skb->ip_hdr 		= skb->h.iph;
+	skb->ip_hdr 		=	skb->h.iph;
 	skb->protocol		=	htons(ETH_P_IP);
 #ifdef TUNNEL_DEBUG
 	printk("New IP Header....\n");
@@ -303,7 +304,7 @@
 	 */
 
 #ifdef CONFIG_IP_FORWARD
-	if (ip_forward(skb, dev, 0, target))
+	if (ip_forward(skb, dev, IPFWD_NOTTLDEC, target))
 #endif
 		kfree_skb(skb, FREE_WRITE);
 
diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/include/net/ip_forward.h linux/include/net/ip_forward.h
--- linux.vanilla/include/net/ip_forward.h	Sun Jun  9 13:11:55 1996
+++ linux/include/net/ip_forward.h	Mon Jul 15 22:53:06 1996
@@ -5,6 +5,7 @@
 #define IPFWD_LASTFRAG		2
 #define IPFWD_MASQUERADED	4
 #define IPFWD_MULTICASTING	8
-#define IPFWD_MULTITUNNEL	16
+#define IPFWD_MULTITUNNEL	0x10
+#define IPFWD_NOTTLDEC		0x20
 
 #endif
diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/include/net/netlink.h linux/include/net/netlink.h
--- linux.vanilla/include/net/netlink.h	Sun Jun  9 13:11:55 1996
+++ linux/include/net/netlink.h	Mon Jul 15 23:40:11 1996
@@ -2,8 +2,9 @@
 #define __NET_NETLINK_H
 
 #define NET_MAJOR 36		/* Major 18 is reserved for networking 						*/
-#define MAX_LINKS 10		/* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved 	*/
+#define MAX_LINKS 11		/* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved 	*/
 				/* 4-7 are psi0-psi3  8 is arpd 9 is ppp */
+				/* 10 is for IPSEC <John Ioannidis> */
 #define MAX_QBYTES 32768	/* Maximum bytes in the queue 							*/
 
 #include <linux/config.h>
@@ -21,6 +22,7 @@
 #define NETLINK_PSI		4	/* PSI devices - 4 to 7 */
 #define NETLINK_ARPD		8
 #define NETLINK_NET_PPP		9	/* Non tty PPP devices */
+#define NETLINK_IPSEC		10	/* IPSEC */
 
 #ifdef CONFIG_RTNETLINK
 extern void ip_netlink_msg(unsigned long, __u32, __u32, __u32, short, short, char *);
diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/net/bridge/br.c linux/net/bridge/br.c
--- linux.vanilla/net/bridge/br.c	Mon Jul 15 22:29:32 1996
+++ linux/net/bridge/br.c	Mon Jul 15 22:37:05 1996
@@ -1307,7 +1307,7 @@
 		/*
 		 *	Sending
 		 */
-		if (port_info[f->port].state == Forwarding) {
+		if (f->port!=port && port_info[f->port].state == Forwarding) {
 			/* has entry expired? */
 			if (f->timer + fdb_aging_time < CURRENT_TIME) {
 				/* timer expired, invalidate entry */
diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/net/ipv4/ip_forward.c linux/net/ipv4/ip_forward.c
--- linux.vanilla/net/ipv4/ip_forward.c	Thu Jul  4 00:23:35 1996
+++ linux/net/ipv4/ip_forward.c	Mon Jul 15 22:53:44 1996
@@ -57,8 +57,11 @@
 	 *	Firstly push down and install the IPIP header.
 	 */
 	struct iphdr *iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr));
+
 	if(len>65515)
 		len=65515;
+
+
 	iph->version	= 	4;
 	iph->tos	=	skb->ip_hdr->tos;
 	iph->ttl	=	skb->ip_hdr->ttl;
@@ -67,17 +70,26 @@
 	iph->saddr	=	out->pa_addr;
 	iph->protocol	=	IPPROTO_IPIP;
 	iph->ihl	=	5;
-	iph->tot_len	=	htons(skb->len);
+	iph->tot_len	=	htons(skb->len + len);  /* Anand, ernet */
 	iph->id		=	htons(ip_id_count++);
 	ip_send_check(iph);
 
 	skb->dev = out;
 	skb->arp = 1;
-	skb->raddr=daddr;
+	skb->raddr=daddr;  /* Router address is not destination address. The
+			    * correct value is given eventually. I have not
+			    * removed this statement. But could have. 
+			    * Anand, ernet.
+			    */ 
 	/*
 	 *	Now add the physical header (driver will push it down).
 	 */
-	if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, len)<0)
+
+	/* The last parameter of out->hard_header() needed skb->len + len.
+ 	 * Anand, ernet.
+	 */
+	if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, 
+	skb->len + len)<0)
 			skb->arp=0;
 	/*
 	 *	Read to queue for transmission.
@@ -121,18 +133,21 @@
 	 */
 
 	iph = skb->h.iph;
-	iph->ttl--;
+	if (!(is_frag&IPFWD_NOTTLDEC))
+	{
+		iph->ttl--;
 
 	/*
 	 *	Re-compute the IP header checksum.
-	 *	This is inefficient. We know what has happened to the header
-	 *	and could thus adjust the checksum as Phil Karn does in KA9Q
+	 *	This is efficient. We know what has happened to the header
+	 *	and can thus adjust the checksum as Phil Karn does in KA9Q
 	 */
 
-	iph->check = ntohs(iph->check) + 0x0100;
-	if ((iph->check & 0xFF00) == 0)
-		iph->check++;		/* carry overflow */
-	iph->check = htons(iph->check);
+		iph->check = ntohs(iph->check) + 0x0100;
+		if ((iph->check & 0xFF00) == 0)
+			iph->check++;		/* carry overflow */
+		iph->check = htons(iph->check);
+	}
 
 	if (iph->ttl <= 0)
 	{
@@ -141,8 +156,14 @@
 		return -1;
 	}
 
+	/* If IPFWD_MULTITUNNEL flag is set, then we have to perform routing
+	 * decision so as to reach the other end of the tunnel. This condition
+	 * also means that we are dealing with a unicast IP packet "in a way". 
+	 * Anand, ernet.
+	 */
+
 #ifdef CONFIG_IP_MROUTE
-	if(!(is_frag&IPFWD_MULTICASTING))
+	if(!(is_frag&IPFWD_MULTICASTING) || is_frag&IPFWD_MULTITUNNEL)
 	{
 #endif	
 		/*
@@ -205,6 +226,12 @@
 				icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
 #endif
 #ifdef CONFIG_IP_MROUTE
+
+		/* This is for ip encap. Anand, ernet.*/
+
+		if (is_frag&IPFWD_MULTITUNNEL) {
+			encap=20;
+				}
 	}
 	else
 	{
@@ -326,8 +353,21 @@
 #ifdef CONFIG_IP_MROUTE
 			if(is_frag&IPFWD_MULTITUNNEL)
 			{
-				skb_reserve(skb2,(encap+dev2->hard_header_len+15)&~15);	/* 16 byte aligned IP headers are good */
-				ip_encap(skb2,skb->len, dev2, raddr);
+				skb_reserve(skb2,(encap+dev->hard_header_len+15)&~15);	/* 16 byte aligned IP headers are good */
+
+/* We need to pass on IP information of the incoming packet to ip_encap() 
+ * to fillin ttl, and tos fields.The destination should be target_addr. 
+ *  Anand, ernet. 
+ */
+
+				skb2->ip_hdr = skb->ip_hdr; 
+
+				ip_encap(skb2,skb->len, dev2, target_addr);
+
+/*  The router address is got earlier that to take us to the remote tunnel
+ *  Anand, ernet.
+ */
+				skb2->raddr = rt->rt_gateway;
 			}
 			else
 #endif			
@@ -341,7 +381,6 @@
 			ptr = skb_put(skb2,skb->len);
 			skb2->free = 1;
 			skb2->h.raw = ptr;
-
 			/*
 			 *	Copy the packet data into the new buffer.
 			 */
@@ -517,3 +556,6 @@
 
 
 #endif
+
+
+
diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/net/ipv4/ip_fragment.c linux/net/ipv4/ip_fragment.c
--- linux.vanilla/net/ipv4/ip_fragment.c	Sun Jun  9 13:12:00 1996
+++ linux/net/ipv4/ip_fragment.c	Mon Jul 15 22:55:44 1996
@@ -706,8 +706,10 @@
 		 */
 
 		skb2->arp = skb->arp;
+#if 0		
 		if(skb->free==0)
 			printk(KERN_ERR "IP fragmenter: BUG free!=1 in fragmenter\n");
+#endif			
 		skb2->free = 1;
 		skb_put(skb2,len + hlen);
 		skb2->h.raw=(char *) skb2->data;
diff --new-file --unified --exclude-from exclude --recursive linux.vanilla/net/ipv4/ipmr.c linux/net/ipv4/ipmr.c
--- linux.vanilla/net/ipv4/ipmr.c	Sun Jun  9 13:12:00 1996
+++ linux/net/ipv4/ipmr.c	Mon Jul 15 22:51:24 1996
@@ -1,5 +1,5 @@
 /*
- *	IP multicast routing support for mrouted 3.6
+ *	IP multicast routing support for mrouted 3.6/3.8
  *
  *		(c) 1995 Alan Cox, <alan@cymru.net>
  *	  Linux Consultancy and Custom Driver Development
@@ -12,8 +12,11 @@
  *
  *	Fixes:
  *	Michael Chastain	:	Incorrect size of copying.
- *	Alan Cox		:	Added the cache manager code
+ *	Alan Cox		:	Added the cache manager code.
  *	Alan Cox		:	Fixed the clone/copy bug and device race.
+ *	Malcolm Beattie		:	Buffer handling fixes.
+ *	Alexey Kuznetsov	:	Double buffer free and other fixes.
+ *	SVR Anand		:	Fixed several multicast bugs and problems.
  *
  *	Status:
  *		Cache manager under test. Forwarding in vague test mode
@@ -736,7 +739,14 @@
 		kfree_skb(skb, FREE_WRITE);
 		return;
 	}
+
+	/*
+	 *	Without the following addition, skb->h.iph points to something
+	 *	different that is not the ip header.
+	 */
 	
+	skb->h.iph = skb->ip_hdr;  /* Anand, ernet.  */
+
 	vif_table[vif].pkt_in++;
 	vif_table[vif].bytes_in+=skb->len;
 	
@@ -909,7 +919,7 @@
  
 void ip_mr_init(void)
 {
-	printk(KERN_INFO "Linux IP multicast router 0.05.\n");
+	printk(KERN_INFO "Linux IP multicast router 0.06.\n");
 	register_netdevice_notifier(&ip_mr_notifier);
 #ifdef CONFIG_PROC_FS	
 	proc_net_register(&(struct proc_dir_entry) {


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