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