(usagi-users 03599) [PATCH] bug in neighbour.c ?

Olivier MATZ <[email protected]>
Newsgroups gmane.linux.ipv6.usagi.users
Message-ID <[email protected]>
Hi,

I think there is a bug in net/core/neighbour.c, if we dump the neighbour
table using 'ip neigh show', I think it will loop infinitely if there is
some neighbours in the tables.

Can you please have a look at my patch ?

Regards,
Olivier
net_core_neighbour__don_t_loop.diff (text/plain, 1.8 KB)
Index: neighbour.c
===================================================================
RCS file: /usr/cvs/USAGI26/net/core/neighbour.c,v
retrieving revision 1.3
diff -u -r1.3 neighbour.c
--- neighbour.c	24 Nov 2005 15:12:52 -0000	1.3
+++ neighbour.c	6 Feb 2006 11:00:08 -0000
@@ -2124,6 +2124,8 @@
 	}
 
 	rc = skb->len;
+	h = 0;
+	idx = 0;
 out:
 	cb->args[1] = h;
 	cb->args[2] = idx;
@@ -2158,6 +2160,8 @@
 		read_unlock_bh(&tbl->lock);
 	}
 	rc = skb->len;
+	h = 0;
+	idx = 0;
 out:
 	cb->args[1] = h;
 	cb->args[2] = idx;
@@ -2168,44 +2172,34 @@
 {
 	struct neigh_table *tbl;
 	int t, family, s_t;
-	long a1, a2, pa1, pa2;
+	long is_pneigh = 0;
 
 	read_lock(&neigh_tbl_lock);
 	family = ((struct rtgenmsg *)NLMSG_DATA(cb->nlh))->rtgen_family;
 	s_t = cb->args[0];
-	a1 = cb->args[1];
-	a2 = cb->args[2];
-	pa1 = cb->args[1];
-	pa2 = cb->args[2];
-
+	
 	for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) {
 		if (t < s_t || (family && tbl->family != family))
 			continue;
 		if (t > s_t)
-			memset(&cb->args[1], 0, sizeof(cb->args) -
-						sizeof(cb->args[0]));
-		cb->args[1] = a1;
-		cb->args[2] = a2;
-		if (neigh_dump_table(tbl, skb, cb) < 0)
-			break;
-		a1 = cb->args[1];
-		a2 = cb->args[2];
-
-		cb->args[1] = pa1;
-		cb->args[2] = pa2;
-		if (pneigh_dump_table(tbl, skb, cb) < 0)
-			break;
-		pa1 = cb->args[1];
-		pa2 = cb->args[2];
+			cb->args[3] = 0;
+
+		for ( is_pneigh =  cb->args[3]; is_pneigh < 2 ; is_pneigh++ ) {
+			if ( !is_pneigh && neigh_dump_table(tbl, skb, cb) < 0 )
+				goto out;
+			
+			else if ( is_pneigh && pneigh_dump_table(tbl, skb, cb) < 0 )
+				goto out;
+		}
 	}
-	read_unlock(&neigh_tbl_lock);
 
+ out:
 	cb->args[0] = t;
+	cb->args[3] = is_pneigh;
 	/*
 	 * XXX: Fix me! currently only neigh's status is reported.
 	 */
-	cb->args[1] = a1;
-	cb->args[2] = a2;
+	read_unlock(&neigh_tbl_lock);
 	return skb->len;
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.