Hi,
Implement the list of nd6 llinfo entries with a TAILQ.
ok?
bluhm
Index: netinet6/nd6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.169
diff -u -p -r1.169 nd6.c
--- netinet6/nd6.c 1 Nov 2015 22:53:34 -0000 1.169
+++ netinet6/nd6.c 2 Nov 2015 00:34:46 -0000
@@ -83,10 +83,10 @@ int nd6_debug = 1;
int nd6_debug = 0;
#endif
+TAILQ_HEAD(llinfo_nd6_head, llinfo_nd6) nd6_list;
struct pool nd6_pool; /* pool for llinfo_nd6 structures */
-static int nd6_inuse, nd6_allocated;
+int nd6_inuse, nd6_allocated;
-struct llinfo_nd6 llinfo_nd6 = {&llinfo_nd6, &llinfo_nd6};
struct nd_drhead nd_defrouter;
struct nd_prhead nd_prefix = { 0 };
@@ -104,17 +104,6 @@ void nd6_timer_work(void *);
int fill_drlist(void *, size_t *, size_t);
int fill_prlist(void *, size_t *, size_t);
-#define LN_DEQUEUE(ln) do { \
- (ln)->ln_next->ln_prev = (ln)->ln_prev; \
- (ln)->ln_prev->ln_next = (ln)->ln_next; \
- } while (0)
-#define LN_INSERTHEAD(ln) do { \
- (ln)->ln_next = llinfo_nd6.ln_next; \
- llinfo_nd6.ln_next = (ln); \
- (ln)->ln_prev = &llinfo_nd6; \
- (ln)->ln_next->ln_prev = (ln); \
- } while (0)
-
void
nd6_init(void)
{
@@ -125,6 +114,7 @@ nd6_init(void)
return;
}
+ TAILQ_INIT(&nd6_list);
pool_init(&nd6_pool, sizeof(struct llinfo_nd6), 0, 0, 0, "nd6", NULL);
/* initialization of the default router list */
@@ -570,20 +560,17 @@ nd6_purge(struct ifnet *ifp)
/*
* Nuke neighbor cache entries for the ifp.
*/
- ln = llinfo_nd6.ln_next;
- while (ln && ln != &llinfo_nd6) {
+ TAILQ_FOREACH_SAFE(ln, &nd6_list, ln_list, nln) {
struct rtentry *rt;
struct sockaddr_dl *sdl;
- nln = ln->ln_next;
rt = ln->ln_rt;
- if (rt && rt->rt_gateway &&
+ if (rt != NULL && rt->rt_gateway != NULL &&
rt->rt_gateway->sa_family == AF_LINK) {
sdl = satosdl(rt->rt_gateway);
if (sdl->sdl_index == ifp->if_index)
nln = nd6_free(rt, 0);
}
- ln = nln;
}
}
@@ -787,7 +774,7 @@ nd6_free(struct rtentry *rt, int gc)
} else
nd6_llinfo_settimer(ln, (long)nd6_gctimer * hz);
splx(s);
- return (ln->ln_next);
+ return (TAILQ_NEXT(ln, ln_list));
}
if (ln->ln_router || dr) {
@@ -836,7 +823,7 @@ nd6_free(struct rtentry *rt, int gc)
* might have freed other entries (particularly the old next entry) as
* a side effect (XXX).
*/
- next = ln->ln_next;
+ next = TAILQ_NEXT(ln, ln_list);
/*
* Detach the route from the routing tree and the list of neighbor
@@ -1028,10 +1015,7 @@ nd6_rtrequest(struct ifnet *ifp, int req
nd6_llinfo_settimer(ln, 0);
}
rt->rt_flags |= RTF_LLINFO;
- ln->ln_next = llinfo_nd6.ln_next;
- llinfo_nd6.ln_next = ln;
- ln->ln_prev = &llinfo_nd6;
- ln->ln_next->ln_prev = ln;
+ TAILQ_INSERT_HEAD(&nd6_list, ln, ln_list);
/*
* If we have too many cache entries, initiate immediate
@@ -1044,12 +1028,16 @@ nd6_rtrequest(struct ifnet *ifp, int req
nd6_inuse >= ip6_neighborgcthresh) {
int i;
- for (i = 0; i < 10 && llinfo_nd6.ln_prev != ln; i++) {
- struct llinfo_nd6 *ln_end = llinfo_nd6.ln_prev;
+ for (i = 0; i < 10; i++) {
+ struct llinfo_nd6 *ln_end;
+
+ ln_end = TAILQ_LAST(&nd6_list, llinfo_nd6_head);
+ if (ln_end == ln)
+ break;
/* Move this entry to the head */
- LN_DEQUEUE(ln_end);
- LN_INSERTHEAD(ln_end);
+ TAILQ_REMOVE(&nd6_list, ln_end, ln_list);
+ TAILQ_INSERT_HEAD(&nd6_list, ln_end, ln_list);
if (ND6_LLINFO_PERMANENT(ln_end))
continue;
@@ -1123,9 +1111,7 @@ nd6_rtrequest(struct ifnet *ifp, int req
in6_delmulti(in6m);
}
nd6_inuse--;
- ln->ln_next->ln_prev = ln->ln_prev;
- ln->ln_prev->ln_next = ln->ln_next;
- ln->ln_prev = NULL;
+ TAILQ_REMOVE(&nd6_list, ln, ln_list);
nd6_llinfo_settimer(ln, -1);
rt->rt_llinfo = NULL;
rt->rt_flags &= ~RTF_LLINFO;
@@ -1604,8 +1590,8 @@ nd6_output(struct ifnet *ifp, struct mbu
* for this entry to be a target of forced garbage collection (see
* nd6_rtrequest()).
*/
- LN_DEQUEUE(ln);
- LN_INSERTHEAD(ln);
+ TAILQ_REMOVE(&nd6_list, ln, ln_list);
+ TAILQ_INSERT_HEAD(&nd6_list, ln, ln_list);
/* We don't have to do link-layer address resolution on a p2p link. */
if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
Index: netinet6/nd6.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/nd6.h,v
retrieving revision 1.52
diff -u -p -r1.52 nd6.h
--- netinet6/nd6.h 28 Oct 2015 12:14:25 -0000 1.52
+++ netinet6/nd6.h 1 Nov 2015 22:56:16 -0000
@@ -135,8 +135,7 @@ struct in6_ndifreq {
((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->rs_lhcookie
struct llinfo_nd6 {
- struct llinfo_nd6 *ln_next;
- struct llinfo_nd6 *ln_prev;
+ TAILQ_ENTRY(llinfo_nd6) ln_list;
struct rtentry *ln_rt;
struct mbuf *ln_hold; /* last packet until resolved/timeout */
time_t ln_expire; /* lifetime for NDP state transition */
@@ -214,7 +213,6 @@ extern int nd6_umaxtries;
extern int nd6_mmaxtries;
extern int nd6_maxnudhint;
extern int nd6_gctimer;
-extern struct llinfo_nd6 llinfo_nd6;
extern struct nd_drhead nd_defrouter;
extern struct nd_prhead nd_prefix;
extern int nd6_debug;