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

Reply via email to