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