Module Name:    src
Committed By:   ozaki-r
Date:           Fri Sep  2 07:15:14 UTC 2016

Modified Files:
        src/sys/netinet6: nd6.c

Log Message:
Don't GC an NDP cache that is added just before GC

This fixes unstable test results of ndp_neighborgcthresh.


To generate a diff of this commit:
cvs rdiff -u -r1.206 -r1.207 src/sys/netinet6/nd6.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.206 src/sys/netinet6/nd6.c:1.207
--- src/sys/netinet6/nd6.c:1.206	Sat Aug  6 20:00:14 2016
+++ src/sys/netinet6/nd6.c	Fri Sep  2 07:15:14 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.206 2016/08/06 20:00:14 roy Exp $	*/
+/*	$NetBSD: nd6.c,v 1.207 2016/09/02 07:15:14 ozaki-r Exp $	*/
 /*	$KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.206 2016/08/06 20:00:14 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.207 2016/09/02 07:15:14 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -1300,10 +1300,17 @@ done:
 	return;
 }
 
+struct gc_args {
+	int gc_entries;
+	const struct in6_addr *skip_in6;
+};
+
 static int
 nd6_purge_entry(struct lltable *llt, struct llentry *ln, void *farg)
 {
-	int *n = farg;
+	struct gc_args *args = farg;
+	int *n = &args->gc_entries;
+	const struct in6_addr *skip_in6 = args->skip_in6;
 
 	if (*n <= 0)
 		return 0;
@@ -1311,6 +1318,9 @@ nd6_purge_entry(struct lltable *llt, str
 	if (ND6_LLINFO_PERMANENT(ln))
 		return 0;
 
+	if (IN6_ARE_ADDR_EQUAL(&ln->r_l3addr.addr6, skip_in6))
+		return 0;
+
 	LLE_WLOCK(ln);
 	if (ln->ln_state > ND6_LLINFO_INCOMPLETE)
 		ln->ln_state = ND6_LLINFO_STALE;
@@ -1324,17 +1334,17 @@ nd6_purge_entry(struct lltable *llt, str
 }
 
 static void
-nd6_gc_neighbors(struct lltable *llt)
+nd6_gc_neighbors(struct lltable *llt, const struct in6_addr *in6)
 {
-	int max_gc_entries = 10;
 
 	if (ip6_neighborgcthresh >= 0 &&
 	    lltable_get_entry_count(llt) >= ip6_neighborgcthresh) {
+		struct gc_args gc_args = {10, in6};
 		/*
 		 * XXX entries that are "less recently used" should be
 		 * freed first.
 		 */
-		lltable_foreach_lle(llt, nd6_purge_entry, &max_gc_entries);
+		lltable_foreach_lle(llt, nd6_purge_entry, &gc_args);
 	}
 }
 
@@ -1546,7 +1556,7 @@ nd6_rtrequest(int req, struct rtentry *r
 		 * purging for some entries.
 		 */
 		if (rt->rt_ifp != NULL)
-			nd6_gc_neighbors(LLTABLE6(rt->rt_ifp));
+			nd6_gc_neighbors(LLTABLE6(rt->rt_ifp), NULL);
 		break;
 	    }
 
@@ -2138,7 +2148,7 @@ nd6_cache_lladdr(
 	 * purging for some entries.
 	 */
 	if (is_newentry)
-		nd6_gc_neighbors(LLTABLE6(ifp));
+		nd6_gc_neighbors(LLTABLE6(ifp), &ln->r_l3addr.addr6);
 
 	/*
 	 * When the link-layer address of a router changes, select the
@@ -2381,7 +2391,7 @@ nd6_output(struct ifnet *ifp, struct ifn
 		m_freem(m);
   exit:
 	if (created)
-		nd6_gc_neighbors(LLTABLE6(ifp));
+		nd6_gc_neighbors(LLTABLE6(ifp), &dst->sin6_addr);
 
 	return error;
 #undef senderr

Reply via email to