Source-Changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
CVS commit: src/sys
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 <ozaki-r%iij.ad.jp@localhost>
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.
Home |
Main Index |
Thread Index |
Old Index