CVS commit: src/sys

"Ryota Ozaki" <[email protected]>
Newsgroups gmane.os.netbsd.devel.cvs
Message-ID <[email protected]>
Module Name:	src
Committed By:	ozaki-r
Date:		Thu Mar 26 04:35:17 UTC 2026

Modified Files:
	src/sys/net: if_llatbl.h nd.c
	src/sys/netinet: if_arp.c
	src/sys/netinet6: nd6.c

Log Message:
commit 27c3de6c8063a7850ef0efbea0d83f314e541ce8
Author: Ryota Ozaki <[email protected]>
Date:   Thu Mar 12 12:42:03 2026 +0900

    nd: reset ln_asked on state reset

    Even if a userland program such as ping continuously sends packets
    to a (temporarily) unreachable host, the ND resolver only sends
    request packets up to nd_mmaxtries times. This change allows ND
    request packets to continue being sent while the userland process
    is still sending packets.

    Additionally, introduce LLE_UNRESOLVED to fix another issue.
    nd_resolve may incorrectly return an error immediately after sending
    the last ND request packet. For example, if nd_mmaxtries = 1 and two
    packets arrive simultaneously, nd_resolve returns an error for the
    second packet. This occurs because ln_asked is used to determine
    whether the ND resolution is still in progress.

    Instead, use the new LLE_UNRESOLVED state. It is set when the state
    transitions to WAITDELETE, i.e., one second after the last request
    is sent without successful address resolution.

    PR kern/60071

diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h
index a83f31cac70..31a3ebef30b 100644
--- a/sys/net/if_llatbl.h
+++ b/sys/net/if_llatbl.h
@@ -249,6 +249,7 @@ MALLOC_DECLARE(M_LLTABLE);
 #define	LLE_VALID	0x0008	/* ll_addr is valid */
 #define	LLE_PUB		0x0020	/* publish entry ??? */
 #define	LLE_LINKED	0x0040	/* linked to lookup structure */
+#define	LLE_UNRESOLVED	0x0080	/* address unresolved */
 /* LLE request flags */
 #define	LLE_EXCLUSIVE	0x2000	/* return lle xlocked  */

diff --git a/sys/net/nd.c b/sys/net/nd.c
index 8ebc5fe5338..8d12c1d7b58 100644
--- a/sys/net/nd.c
+++ b/sys/net/nd.c
@@ -113,6 +113,7 @@ nd_timer(void *arg)

 		missed = ND_LLINFO_INCOMPLETE;
 		ln->ln_state = ND_LLINFO_WAITDELETE;
+		ln->la_flags |= LLE_UNRESOLVED;
 		break;

 	case ND_LLINFO_REACHABLE:
@@ -360,8 +361,10 @@ nd_resolve(struct llentry *ln, const struct rtentry *rt, struct mbuf *m,
 	 * the oldest packet in the queue will be removed.
 	 */
 	if (ln->ln_state == ND_LLINFO_NOSTATE ||
-	    ln->ln_state == ND_LLINFO_WAITDELETE)
+	    ln->ln_state == ND_LLINFO_WAITDELETE) {
+		ln->ln_asked = 0;
 		ln->ln_state = ND_LLINFO_INCOMPLETE;
+	}

 #ifdef MBUFTRACE
 	m_claimm(m, ln->lle_tbl->llt_mowner);
@@ -398,7 +401,7 @@ nd_resolve(struct llentry *ln, const struct rtentry *rt, struct mbuf *m,
 	    ln->la_numheld, nd->nd_maxqueuelen);
 	ln->la_numheld++;

-	if (ln->ln_asked >= nd->nd_mmaxtries)
+	if ((ln->la_flags & LLE_UNRESOLVED) != 0)
 		error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ?
 		    EHOSTUNREACH : EHOSTDOWN;
 	else
diff --git a/sys/netinet/if_arp.c b/sys/netinet/if_arp.c
index 2934534efb1..fc4d0252a74 100644
--- a/sys/netinet/if_arp.c
+++ b/sys/netinet/if_arp.c
@@ -1056,6 +1056,7 @@ again:
 	KASSERT(sizeof(la->ll_addr) >= ifp->if_addrlen);
 	memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
 	la->la_flags |= LLE_VALID;
+	la->la_flags &= ~LLE_UNRESOLVED;
 	la->ln_asked = 0;
 	if (new_state != 0) {
 		la->ln_state = new_state;
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index aeaef609a79..1920759ecbc 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1400,6 +1400,7 @@ nd6_cache_lladdr(
 		 */
 		memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
 		ln->la_flags |= LLE_VALID;
+		ln->la_flags &= ~LLE_UNRESOLVED;
 	}

 	if (!is_newentry) {


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/net/if_llatbl.h
cvs rdiff -u -r1.9 -r1.10 src/sys/net/nd.c
cvs rdiff -u -r1.318 -r1.319 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.285 -r1.286 src/sys/netinet6/nd6.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.