Module Name: src Committed By: roy Date: Sun Sep 1 19:26:22 UTC 2019
Modified Files: src/sys/netinet6: nd6.c nd6.h Log Message: inet6: Re-introduce ND6_LLINFO_WAITDELETE so we can return EHOSTDOWN Once we've sent nd6_mmaxtries NS messages, send RTM_MISS and move to the ND6_LLINFO_WAITDELETE state rather than freeing the llentry right away. Wait for a probe cycle and then free the llentry. If a connection attempts to re-use the llentry during ND6_LLINFO_WAITDELETE, return EHOSTDOWN (or EHOSTUNREACH if a gateway) to match inet behaviour. Continue to ND6_LLINFO_INCOMPLETE and send another NS probe in hope of a reply. Rinse and repeat. This reverts part of nd6.c r1.14 - an 18 year old commit! To generate a diff of this commit: cvs rdiff -u -r1.262 -r1.263 src/sys/netinet6/nd6.c cvs rdiff -u -r1.86 -r1.87 src/sys/netinet6/nd6.h 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.262 src/sys/netinet6/nd6.c:1.263 --- src/sys/netinet6/nd6.c:1.262 Sun Sep 1 18:54:38 2019 +++ src/sys/netinet6/nd6.c Sun Sep 1 19:26:21 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.c,v 1.262 2019/09/01 18:54:38 roy Exp $ */ +/* $NetBSD: nd6.c,v 1.263 2019/09/01 19:26:21 roy 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.262 2019/09/01 18:54:38 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.263 2019/09/01 19:26:21 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -480,9 +480,14 @@ nd6_llinfo_timer(void *arg) ndi = ND_IFINFO(ifp); switch (ln->ln_state) { + case ND6_LLINFO_WAITDELETE: + LLE_REMREF(ln); + nd6_free(ln, 0); + ln = NULL; + break; + case ND6_LLINFO_INCOMPLETE: - if (ln->ln_asked < nd6_mmaxtries) { - ln->ln_asked++; + if (ln->ln_asked++ < nd6_mmaxtries) { send_ns = true; break; } @@ -506,9 +511,17 @@ nd6_llinfo_timer(void *arg) sockaddr_in6_init(&sin6, taddr6, 0, 0, 0); rt_clonedmsg(RTM_MISS, sin6tosa(&sin6), NULL, ifp); - LLE_REMREF(ln); - nd6_free(ln, 0); - ln = NULL; + /* + * Move to the ND6_LLINFO_WAITDELETE state for another + * interval at which point the llentry will be freed + * unless it's attempted to be used again and we'll + * resend NS again, rinse and repeat. + */ + ln->ln_state = ND6_LLINFO_WAITDELETE; + if (ln->ln_asked == nd6_mmaxtries) + nd6_llinfo_settimer(ln, ndi->retrans * hz / 1000); + else + send_ns = true; break; case ND6_LLINFO_REACHABLE: @@ -2312,6 +2325,7 @@ nd6_resolve(struct ifnet *ifp, const str struct llentry *ln = NULL; bool created = false; const struct sockaddr_in6 *dst = satocsin6(_dst); + int error; /* discard the packet if IPv6 operation is disabled on the interface */ if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) { @@ -2406,7 +2420,8 @@ nd6_resolve(struct ifnet *ifp, const str * does not exceed nd6_maxqueuelen. When it exceeds nd6_maxqueuelen, * the oldest packet in the queue will be removed. */ - if (ln->ln_state == ND6_LLINFO_NOSTATE) + if (ln->ln_state == ND6_LLINFO_NOSTATE || + ln->ln_state == ND6_LLINFO_WAITDELETE) ln->ln_state = ND6_LLINFO_INCOMPLETE; if (ln->ln_hold) { struct mbuf *m_hold; @@ -2430,6 +2445,12 @@ nd6_resolve(struct ifnet *ifp, const str ln->ln_hold = m; } + if (ln->ln_asked >= nd6_mmaxtries) + error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ? + EHOSTUNREACH : EHOSTDOWN; + else + error = EWOULDBLOCK; + /* * If there has been no NS for the neighbor after entering the * INCOMPLETE state, send the first solicitation. @@ -2448,7 +2469,7 @@ nd6_resolve(struct ifnet *ifp, const str if (created) nd6_gc_neighbors(LLTABLE6(ifp), &dst->sin6_addr); - return EWOULDBLOCK; + return error; } int Index: src/sys/netinet6/nd6.h diff -u src/sys/netinet6/nd6.h:1.86 src/sys/netinet6/nd6.h:1.87 --- src/sys/netinet6/nd6.h:1.86 Tue Mar 6 10:57:00 2018 +++ src/sys/netinet6/nd6.h Sun Sep 1 19:26:21 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.h,v 1.86 2018/03/06 10:57:00 roy Exp $ */ +/* $NetBSD: nd6.h,v 1.87 2019/09/01 19:26:21 roy Exp $ */ /* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */ /* @@ -38,14 +38,7 @@ #define ND6_LLINFO_PURGE -3 #define ND6_LLINFO_NOSTATE -2 -/* - * We don't need the WAITDELETE state any more, but we keep the definition - * in a comment line instead of removing it. This is necessary to avoid - * unintentionally reusing the value for another purpose, which might - * affect backward compatibility with old applications. - * (20000711 jin...@kame.net) - */ -/* #define ND6_LLINFO_WAITDELETE -1 */ +#define ND6_LLINFO_WAITDELETE -1 #define ND6_LLINFO_INCOMPLETE 0 #define ND6_LLINFO_REACHABLE 1 #define ND6_LLINFO_STALE 2