patch-2.1.90 linux/net/core/neighbour.c

Next file: linux/net/core/sock.c
Previous file: linux/net/core/iovec.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.89/linux/net/core/neighbour.c linux/net/core/neighbour.c
@@ -153,12 +153,14 @@
 static struct neighbour *neigh_alloc(struct neigh_table *tbl, int creat)
 {
 	struct neighbour *n;
+	unsigned long now = jiffies;
 
 	if (tbl->entries > tbl->gc_thresh1) {
 		if (creat < 0)
 			return NULL;
-		if (tbl->entries > tbl->gc_thresh2 ||
-		    jiffies - tbl->last_flush > 5*HZ) {
+		if (tbl->entries > tbl->gc_thresh3 ||
+		    (tbl->entries > tbl->gc_thresh2 &&
+		     now - tbl->last_flush > 5*HZ)) {
 			if (neigh_forced_gc(tbl) == 0 &&
 			    tbl->entries > tbl->gc_thresh3)
 				return NULL;
@@ -172,7 +174,7 @@
 	memset(n, 0, tbl->entry_size);
 
 	skb_queue_head_init(&n->arp_queue);
-	n->updated = n->used = jiffies;
+	n->updated = n->used = now;
 	n->nud_state = NUD_NONE;
 	n->output = neigh_blackhole;
 	n->parms = &tbl->parms;
@@ -666,8 +668,18 @@
 		neigh_suspect(neigh);
 	if (!(old&NUD_VALID)) {
 		struct sk_buff *skb;
-		while ((skb=__skb_dequeue(&neigh->arp_queue)) != NULL)
-			neigh->output(skb);
+
+		/* Again: avoid dead loop if something went wrong */
+
+		while (neigh->nud_state&NUD_VALID &&
+		       (skb=__skb_dequeue(&neigh->arp_queue)) != NULL) {
+			struct neighbour *n1 = neigh;
+			/* On shaper/eql skb->dst->neighbour != neigh :( */
+			if (skb->dst && skb->dst->neighbour)
+				n1 = skb->dst->neighbour;
+			n1->output(skb);
+		}
+		skb_queue_purge(&neigh->arp_queue);
 	}
 	return 0;
 }
@@ -1228,7 +1240,7 @@
          &proc_dointvec},
 	 {0}},
 
-	{{1, "default", NULL, 0, 0555, NULL},{0}},
+	{{NET_PROTO_CONF_DEFAULT, "default", NULL, 0, 0555, NULL},{0}},
 	{{0, "neigh", NULL, 0, 0555, NULL},{0}},
 	{{0, NULL, NULL, 0, 0555, NULL},{0}},
 	{{CTL_NET, "net", NULL, 0, 0555, NULL},{0}}
@@ -1243,10 +1255,11 @@
 	if (t == NULL)
 		return -ENOBUFS;
 	memcpy(t, &neigh_sysctl_template, sizeof(*t));
+	t->neigh_vars[0].data = &p->mcast_probes;
 	t->neigh_vars[1].data = &p->ucast_probes;
 	t->neigh_vars[2].data = &p->app_probes;
 	t->neigh_vars[3].data = &p->retrans_time;
-	t->neigh_vars[4].data = &p->reachable_time;
+	t->neigh_vars[4].data = &p->base_reachable_time;
 	t->neigh_vars[5].data = &p->delay_probe_time;
 	t->neigh_vars[6].data = &p->gc_staletime;
 	t->neigh_vars[7].data = &p->queue_len;
@@ -1256,7 +1269,7 @@
 	t->neigh_vars[11].data = &p->locktime;
 	if (dev) {
 		t->neigh_dev[0].procname = dev->name;
-		t->neigh_dev[0].ctl_name = dev->ifindex+1;
+		t->neigh_dev[0].ctl_name = dev->ifindex;
 		memset(&t->neigh_vars[12], 0, sizeof(ctl_table));
 	} else {
 		t->neigh_vars[12].data = (&p->locktime) + 1;

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