The branch stable/14 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=685d1d78bf9cd367d1a73a303c1559a3720733af

commit 685d1d78bf9cd367d1a73a303c1559a3720733af
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2025-02-06 14:14:39 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2025-02-21 01:04:50 +0000

    inpcb: Add FIB-aware inpcb lookup
    
    Allow protocol layers to look up an inpcb belonging to a particular FIB.
    This is indicated by setting INPLOOKUP_FIB; if it is set, the FIB to be
    used is obtained from the specificed mbuf or ifnet.
    
    No functional change intended.
    
    Reviewed by:    glebius, melifaro
    MFC after:      2 weeks
    Sponsored by:   Klara, Inc.
    Sponsored by:   Stormshield
    Differential Revision:  https://reviews.freebsd.org/D48662
    
    (cherry picked from commit da806e8db685eead02bc67888b16ebac6badb6b6)
---
 sys/netinet/in_pcb.c   | 74 ++++++++++++++++++++++++++++----------------------
 sys/netinet/in_pcb.h   |  3 +-
 sys/netinet6/in6_pcb.c | 71 ++++++++++++++++++++++++++++--------------------
 sys/netinet6/in6_pcb.h |  2 +-
 4 files changed, 87 insertions(+), 63 deletions(-)

diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 25b1d51e4a79..89000a521bff 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -141,7 +141,7 @@ VNET_DEFINE(int, ipport_randomized) = 1;
 static struct inpcb    *in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo,
                            struct in_addr faddr, u_int fport_arg,
                            struct in_addr laddr, u_int lport_arg,
-                           int lookupflags, uint8_t numa_domain);
+                           int lookupflags, uint8_t numa_domain, int fib);
 
 #define RANGECHK(var, min, max) \
        if ((var) < (min)) { (var) = (min); } \
@@ -812,14 +812,14 @@ in_pcb_lport_dest(struct inpcb *inp, struct sockaddr 
*lsa, u_short *lportp,
                        if (lsa->sa_family == AF_INET) {
                                tmpinp = in_pcblookup_hash_locked(pcbinfo,
                                    faddr, fport, laddr, lport, lookupflags,
-                                   M_NODOM);
+                                   M_NODOM, RT_ALL_FIBS);
                        }
 #endif
 #ifdef INET6
                        if (lsa->sa_family == AF_INET6) {
                                tmpinp = in6_pcblookup_hash_locked(pcbinfo,
                                    faddr6, fport, laddr6, lport, lookupflags,
-                                   M_NODOM);
+                                   M_NODOM, RT_ALL_FIBS);
                        }
 #endif
                } else {
@@ -1412,7 +1412,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr_in 
*sin,
 
        if (lport != 0) {
                if (in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr,
-                   fport, laddr, lport, 0, M_NODOM) != NULL)
+                   fport, laddr, lport, 0, M_NODOM, RT_ALL_FIBS) != NULL)
                        return (EADDRINUSE);
        } else {
                struct sockaddr_in lsin, fsin;
@@ -2127,15 +2127,16 @@ in_pcblookup_local(struct inpcbinfo *pcbinfo, struct 
in_addr laddr,
 #undef INP_LOOKUP_MAPPED_PCB_COST
 
 static bool
-in_pcblookup_lb_numa_match(const struct inpcblbgroup *grp, int domain)
+in_pcblookup_lb_match(const struct inpcblbgroup *grp, int domain, int fib)
 {
-       return (domain == M_NODOM || domain == grp->il_numa_domain);
+       return ((domain == M_NODOM || domain == grp->il_numa_domain) &&
+           (fib == RT_ALL_FIBS || fib == grp->il_fibnum));
 }
 
 static struct inpcb *
 in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
     const struct in_addr *faddr, uint16_t fport, const struct in_addr *laddr,
-    uint16_t lport, int domain)
+    uint16_t lport, int domain, int fib)
 {
        const struct inpcblbgrouphead *hdr;
        struct inpcblbgroup *grp;
@@ -2174,20 +2175,20 @@ in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
                if (grp->il_laddr.s_addr == laddr->s_addr) {
                        if (injail) {
                                jail_exact = grp;
-                               if (in_pcblookup_lb_numa_match(grp, domain))
+                               if (in_pcblookup_lb_match(grp, domain, fib))
                                        /* This is a perfect match. */
                                        goto out;
                        } else if (local_exact == NULL ||
-                           in_pcblookup_lb_numa_match(grp, domain)) {
+                           in_pcblookup_lb_match(grp, domain, fib)) {
                                local_exact = grp;
                        }
                } else if (grp->il_laddr.s_addr == INADDR_ANY) {
                        if (injail) {
                                if (jail_wild == NULL ||
-                                   in_pcblookup_lb_numa_match(grp, domain))
+                                   in_pcblookup_lb_match(grp, domain, fib))
                                        jail_wild = grp;
                        } else if (local_wild == NULL ||
-                           in_pcblookup_lb_numa_match(grp, domain)) {
+                           in_pcblookup_lb_match(grp, domain, fib)) {
                                local_wild = grp;
                        }
                }
@@ -2259,7 +2260,7 @@ typedef enum {
 
 static inp_lookup_match_t
 in_pcblookup_wild_match(const struct inpcb *inp, struct in_addr laddr,
-    u_short lport)
+    u_short lport, int fib)
 {
 #ifdef INET6
        /* XXX inp locking */
@@ -2268,6 +2269,8 @@ in_pcblookup_wild_match(const struct inpcb *inp, struct 
in_addr laddr,
 #endif
        if (inp->inp_faddr.s_addr != INADDR_ANY || inp->inp_lport != lport)
                return (INPLOOKUP_MATCH_NONE);
+       if (fib != RT_ALL_FIBS && inp->inp_inc.inc_fibnum != fib)
+               return (INPLOOKUP_MATCH_NONE);
        if (inp->inp_laddr.s_addr == INADDR_ANY)
                return (INPLOOKUP_MATCH_WILD);
        if (inp->inp_laddr.s_addr == laddr.s_addr)
@@ -2279,7 +2282,7 @@ in_pcblookup_wild_match(const struct inpcb *inp, struct 
in_addr laddr,
 
 static struct inpcb *
 in_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo, struct in_addr laddr,
-    u_short lport, const inp_lookup_t lockflags)
+    u_short lport, int fib, const inp_lookup_t lockflags)
 {
        struct inpcbhead *head;
        struct inpcb *inp;
@@ -2292,12 +2295,12 @@ in_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo, 
struct in_addr laddr,
        CK_LIST_FOREACH(inp, head, inp_hash_wild) {
                inp_lookup_match_t match;
 
-               match = in_pcblookup_wild_match(inp, laddr, lport);
+               match = in_pcblookup_wild_match(inp, laddr, lport, fib);
                if (match == INPLOOKUP_MATCH_NONE)
                        continue;
 
                if (__predict_true(inp_smr_lock(inp, lockflags))) {
-                       match = in_pcblookup_wild_match(inp, laddr, lport);
+                       match = in_pcblookup_wild_match(inp, laddr, lport, fib);
                        if (match != INPLOOKUP_MATCH_NONE &&
                            prison_check_ip4_locked(inp->inp_cred->cr_prison,
                            &laddr) == 0)
@@ -2316,7 +2319,7 @@ in_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo, 
struct in_addr laddr,
 
 static struct inpcb *
 in_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo, struct in_addr laddr,
-    u_short lport)
+    u_short lport, int fib)
 {
        struct inpcbhead *head;
        struct inpcb *inp, *local_wild, *local_exact, *jail_wild;
@@ -2343,7 +2346,7 @@ in_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo, 
struct in_addr laddr,
                inp_lookup_match_t match;
                bool injail;
 
-               match = in_pcblookup_wild_match(inp, laddr, lport);
+               match = in_pcblookup_wild_match(inp, laddr, lport, fib);
                if (match == INPLOOKUP_MATCH_NONE)
                        continue;
 
@@ -2396,12 +2399,12 @@ in_pcblookup_hash_wild_locked(struct inpcbinfo 
*pcbinfo, struct in_addr laddr,
 static struct inpcb *
 in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
     u_int fport_arg, struct in_addr laddr, u_int lport_arg, int lookupflags,
-    uint8_t numa_domain)
+    uint8_t numa_domain, int fib)
 {
        struct inpcb *inp;
        const u_short fport = fport_arg, lport = lport_arg;
 
-       KASSERT((lookupflags & ~INPLOOKUP_WILDCARD) == 0,
+       KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD | INPLOOKUP_FIB)) == 0,
            ("%s: invalid lookup flags %d", __func__, lookupflags));
        KASSERT(faddr.s_addr != INADDR_ANY,
            ("%s: invalid foreign address", __func__));
@@ -2415,10 +2418,10 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, 
struct in_addr faddr,
 
        if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
                inp = in_pcblookup_lbgroup(pcbinfo, &faddr, fport,
-                   &laddr, lport, numa_domain);
+                   &laddr, lport, numa_domain, fib);
                if (inp == NULL) {
                        inp = in_pcblookup_hash_wild_locked(pcbinfo, laddr,
-                           lport);
+                           lport, fib);
                }
        }
 
@@ -2428,7 +2431,7 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, 
struct in_addr faddr,
 static struct inpcb *
 in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr,
     u_int fport, struct in_addr laddr, u_int lport, int lookupflags,
-    uint8_t numa_domain)
+    uint8_t numa_domain, int fib)
 {
        struct inpcb *inp;
        const inp_lookup_t lockflags = lookupflags & INPLOOKUP_LOCKMASK;
@@ -2438,7 +2441,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct 
in_addr faddr,
 
        INP_HASH_WLOCK(pcbinfo);
        inp = in_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport,
-           lookupflags & ~INPLOOKUP_LOCKMASK, numa_domain);
+           lookupflags & ~INPLOOKUP_LOCKMASK, numa_domain, fib);
        if (inp != NULL && !inp_trylock(inp, lockflags)) {
                in_pcbref(inp);
                INP_HASH_WUNLOCK(pcbinfo);
@@ -2455,7 +2458,7 @@ in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct 
in_addr faddr,
 static struct inpcb *
 in_pcblookup_hash_smr(struct inpcbinfo *pcbinfo, struct in_addr faddr,
     u_int fport_arg, struct in_addr laddr, u_int lport_arg, int lookupflags,
-    uint8_t numa_domain)
+    uint8_t numa_domain, int fib)
 {
        struct inpcb *inp;
        const inp_lookup_t lockflags = lookupflags & INPLOOKUP_LOCKMASK;
@@ -2485,27 +2488,27 @@ in_pcblookup_hash_smr(struct inpcbinfo *pcbinfo, struct 
in_addr faddr,
                 * out from under us.  Fall back to a precise search.
                 */
                return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
-                   lookupflags, numa_domain));
+                   lookupflags, numa_domain, fib));
        }
 
        if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
                inp = in_pcblookup_lbgroup(pcbinfo, &faddr, fport,
-                   &laddr, lport, numa_domain);
+                   &laddr, lport, numa_domain, fib);
                if (inp != NULL) {
                        if (__predict_true(inp_smr_lock(inp, lockflags))) {
                                if (__predict_true(in_pcblookup_wild_match(inp,
-                                   laddr, lport) != INPLOOKUP_MATCH_NONE))
+                                   laddr, lport, fib) != INPLOOKUP_MATCH_NONE))
                                        return (inp);
                                inp_unlock(inp, lockflags);
                        }
                        inp = INP_LOOKUP_AGAIN;
                } else {
                        inp = in_pcblookup_hash_wild_smr(pcbinfo, laddr, lport,
-                           lockflags);
+                           fib, lockflags);
                }
                if (inp == INP_LOOKUP_AGAIN) {
                        return (in_pcblookup_hash(pcbinfo, faddr, fport, laddr,
-                           lport, lookupflags, numa_domain));
+                           lport, lookupflags, numa_domain, fib));
                }
        }
 
@@ -2522,10 +2525,13 @@ in_pcblookup_hash_smr(struct inpcbinfo *pcbinfo, struct 
in_addr faddr,
 struct inpcb *
 in_pcblookup(struct inpcbinfo *pcbinfo, struct in_addr faddr, u_int fport,
     struct in_addr laddr, u_int lport, int lookupflags,
-    struct ifnet *ifp __unused)
+    struct ifnet *ifp)
 {
+       int fib;
+
+       fib = (lookupflags & INPLOOKUP_FIB) ? if_getfib(ifp) : RT_ALL_FIBS;
        return (in_pcblookup_hash_smr(pcbinfo, faddr, fport, laddr, lport,
-           lookupflags, M_NODOM));
+           lookupflags, M_NODOM, fib));
 }
 
 struct inpcb *
@@ -2533,8 +2539,12 @@ in_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct 
in_addr faddr,
     u_int fport, struct in_addr laddr, u_int lport, int lookupflags,
     struct ifnet *ifp __unused, struct mbuf *m)
 {
+       int fib;
+
+       M_ASSERTPKTHDR(m);
+       fib = (lookupflags & INPLOOKUP_FIB) ? M_GETFIB(m) : RT_ALL_FIBS;
        return (in_pcblookup_hash_smr(pcbinfo, faddr, fport, laddr, lport,
-           lookupflags, m->m_pkthdr.numa_domain));
+           lookupflags, m->m_pkthdr.numa_domain, fib));
 }
 #endif /* INET */
 
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index edc05322d211..6ea99b58f246 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -624,10 +624,11 @@ typedef   enum {
        INPLOOKUP_WILDCARD = 0x00000001,        /* Allow wildcard sockets. */
        INPLOOKUP_RLOCKPCB = 0x00000002,        /* Return inpcb read-locked. */
        INPLOOKUP_WLOCKPCB = 0x00000004,        /* Return inpcb write-locked. */
+       INPLOOKUP_FIB = 0x00000008,             /* inp must be from same FIB. */
 } inp_lookup_t;
 
 #define        INPLOOKUP_MASK  (INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB | \
-           INPLOOKUP_WLOCKPCB)
+           INPLOOKUP_WLOCKPCB | INPLOOKUP_FIB)
 #define        INPLOOKUP_LOCKMASK      (INPLOOKUP_RLOCKPCB | 
INPLOOKUP_WLOCKPCB)
 
 #define        sotoinpcb(so)   ((struct inpcb *)(so)->so_pcb)
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
index e692ab755c25..fc7504a5bc34 100644
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -501,7 +501,7 @@ in6_pcbconnect(struct inpcb *inp, struct sockaddr_in6 
*sin6, struct ucred *cred,
        if (in6_pcblookup_hash_locked(pcbinfo, &sin6->sin6_addr,
            sin6->sin6_port, IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) ?
            &laddr6.sin6_addr : &inp->in6p_laddr, inp->inp_lport, 0,
-           M_NODOM) != NULL)
+           M_NODOM, RT_ALL_FIBS) != NULL)
                return (EADDRINUSE);
        if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
                if (inp->inp_lport == 0) {
@@ -930,15 +930,16 @@ in6_rtchange(struct inpcb *inp, int errno __unused)
 }
 
 static bool
-in6_pcblookup_lb_numa_match(const struct inpcblbgroup *grp, int domain)
+in6_pcblookup_lb_match(const struct inpcblbgroup *grp, int domain, int fib)
 {
-       return (domain == M_NODOM || domain == grp->il_numa_domain);
+       return ((domain == M_NODOM || domain == grp->il_numa_domain) &&
+           (fib == RT_ALL_FIBS || fib == grp->il_fibnum));
 }
 
 static struct inpcb *
 in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
     const struct in6_addr *faddr, uint16_t fport, const struct in6_addr *laddr,
-    uint16_t lport, uint8_t domain)
+    uint16_t lport, uint8_t domain, int fib)
 {
        const struct inpcblbgrouphead *hdr;
        struct inpcblbgroup *grp;
@@ -947,6 +948,7 @@ in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
        u_int count;
 
        INP_HASH_LOCK_ASSERT(pcbinfo);
+       NET_EPOCH_ASSERT();
 
        hdr = &pcbinfo->ipi_lbgrouphashbase[
            INP_PCBPORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)];
@@ -976,20 +978,20 @@ in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
                if (IN6_ARE_ADDR_EQUAL(&grp->il6_laddr, laddr)) {
                        if (injail) {
                                jail_exact = grp;
-                               if (in6_pcblookup_lb_numa_match(grp, domain))
+                               if (in6_pcblookup_lb_match(grp, domain, fib))
                                        /* This is a perfect match. */
                                        goto out;
                        } else if (local_exact == NULL ||
-                           in6_pcblookup_lb_numa_match(grp, domain)) {
+                           in6_pcblookup_lb_match(grp, domain, fib)) {
                                local_exact = grp;
                        }
                } else if (IN6_IS_ADDR_UNSPECIFIED(&grp->il6_laddr)) {
                        if (injail) {
                                if (jail_wild == NULL ||
-                                   in6_pcblookup_lb_numa_match(grp, domain))
+                                   in6_pcblookup_lb_match(grp, domain, fib))
                                        jail_wild = grp;
                        } else if (local_wild == NULL ||
-                           in6_pcblookup_lb_numa_match(grp, domain)) {
+                           in6_pcblookup_lb_match(grp, domain, fib)) {
                                local_wild = grp;
                        }
                }
@@ -1061,7 +1063,7 @@ typedef enum {
 
 static inp_lookup_match_t
 in6_pcblookup_wild_match(const struct inpcb *inp, const struct in6_addr *laddr,
-    u_short lport)
+    u_short lport, int fib)
 {
        /* XXX inp locking */
        if ((inp->inp_vflag & INP_IPV6) == 0)
@@ -1069,6 +1071,8 @@ in6_pcblookup_wild_match(const struct inpcb *inp, const 
struct in6_addr *laddr,
        if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) ||
            inp->inp_lport != lport)
                return (INPLOOKUP_MATCH_NONE);
+       if (fib != RT_ALL_FIBS && inp->inp_inc.inc_fibnum != fib)
+               return (INPLOOKUP_MATCH_NONE);
        if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
                return (INPLOOKUP_MATCH_WILD);
        if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr))
@@ -1080,7 +1084,8 @@ in6_pcblookup_wild_match(const struct inpcb *inp, const 
struct in6_addr *laddr,
 
 static struct inpcb *
 in6_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo,
-    const struct in6_addr *laddr, u_short lport, const inp_lookup_t lockflags)
+    const struct in6_addr *laddr, u_short lport, int fib,
+    const inp_lookup_t lockflags)
 {
        struct inpcbhead *head;
        struct inpcb *inp;
@@ -1093,12 +1098,13 @@ in6_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo,
        CK_LIST_FOREACH(inp, head, inp_hash_wild) {
                inp_lookup_match_t match;
 
-               match = in6_pcblookup_wild_match(inp, laddr, lport);
+               match = in6_pcblookup_wild_match(inp, laddr, lport, fib);
                if (match == INPLOOKUP_MATCH_NONE)
                        continue;
 
                if (__predict_true(inp_smr_lock(inp, lockflags))) {
-                       match = in6_pcblookup_wild_match(inp, laddr, lport);
+                       match = in6_pcblookup_wild_match(inp, laddr, lport,
+                           fib);
                        if (match != INPLOOKUP_MATCH_NONE &&
                            prison_check_ip6_locked(inp->inp_cred->cr_prison,
                            laddr) == 0)
@@ -1117,7 +1123,7 @@ in6_pcblookup_hash_wild_smr(struct inpcbinfo *pcbinfo,
 
 static struct inpcb *
 in6_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo,
-    const struct in6_addr *laddr, u_short lport)
+    const struct in6_addr *laddr, u_short lport, int fib)
 {
        struct inpcbhead *head;
        struct inpcb *inp, *jail_wild, *local_exact, *local_wild;
@@ -1138,7 +1144,7 @@ in6_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo,
                inp_lookup_match_t match;
                bool injail;
 
-               match = in6_pcblookup_wild_match(inp, laddr, lport);
+               match = in6_pcblookup_wild_match(inp, laddr, lport, fib);
                if (match == INPLOOKUP_MATCH_NONE)
                        continue;
 
@@ -1178,12 +1184,12 @@ struct inpcb *
 in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo,
     const struct in6_addr *faddr, u_int fport_arg,
     const struct in6_addr *laddr, u_int lport_arg,
-    int lookupflags, uint8_t numa_domain)
+    int lookupflags, uint8_t numa_domain, int fib)
 {
        struct inpcb *inp;
        u_short fport = fport_arg, lport = lport_arg;
 
-       KASSERT((lookupflags & ~INPLOOKUP_WILDCARD) == 0,
+       KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD | INPLOOKUP_FIB)) == 0,
            ("%s: invalid lookup flags %d", __func__, lookupflags));
        KASSERT(!IN6_IS_ADDR_UNSPECIFIED(faddr),
            ("%s: invalid foreign address", __func__));
@@ -1197,10 +1203,10 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo,
 
        if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
                inp = in6_pcblookup_lbgroup(pcbinfo, faddr, fport, laddr,
-                   lport, numa_domain);
+                   lport, numa_domain, fib);
                if (inp == NULL) {
                        inp = in6_pcblookup_hash_wild_locked(pcbinfo,
-                           laddr, lport);
+                           laddr, lport, fib);
                }
        }
        return (inp);
@@ -1209,7 +1215,7 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo,
 static struct inpcb *
 in6_pcblookup_hash(struct inpcbinfo *pcbinfo, const struct in6_addr *faddr,
     u_int fport, const struct in6_addr *laddr, u_int lport, int lookupflags,
-    uint8_t numa_domain)
+    uint8_t numa_domain, int fib)
 {
        struct inpcb *inp;
        const inp_lookup_t lockflags = lookupflags & INPLOOKUP_LOCKMASK;
@@ -1219,7 +1225,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, const 
struct in6_addr *faddr,
 
        INP_HASH_WLOCK(pcbinfo);
        inp = in6_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport,
-           lookupflags & ~INPLOOKUP_LOCKMASK, numa_domain);
+           lookupflags & ~INPLOOKUP_LOCKMASK, numa_domain, fib);
        if (inp != NULL && !inp_trylock(inp, lockflags)) {
                in_pcbref(inp);
                INP_HASH_WUNLOCK(pcbinfo);
@@ -1236,7 +1242,7 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, const 
struct in6_addr *faddr,
 static struct inpcb *
 in6_pcblookup_hash_smr(struct inpcbinfo *pcbinfo, const struct in6_addr *faddr,
     u_int fport_arg, const struct in6_addr *laddr, u_int lport_arg,
-    int lookupflags, uint8_t numa_domain)
+    int lookupflags, uint8_t numa_domain, int fib)
 {
        struct inpcb *inp;
        const inp_lookup_t lockflags = lookupflags & INPLOOKUP_LOCKMASK;
@@ -1261,27 +1267,27 @@ in6_pcblookup_hash_smr(struct inpcbinfo *pcbinfo, const 
struct in6_addr *faddr,
                 * out from under us.  Fall back to a precise search.
                 */
                return (in6_pcblookup_hash(pcbinfo, faddr, fport, laddr, lport,
-                   lookupflags, numa_domain));
+                   lookupflags, numa_domain, fib));
        }
 
        if ((lookupflags & INPLOOKUP_WILDCARD) != 0) {
                inp = in6_pcblookup_lbgroup(pcbinfo, faddr, fport,
-                   laddr, lport, numa_domain);
+                   laddr, lport, numa_domain, fib);
                if (inp != NULL) {
                        if (__predict_true(inp_smr_lock(inp, lockflags))) {
                                if (__predict_true(in6_pcblookup_wild_match(inp,
-                                   laddr, lport) != INPLOOKUP_MATCH_NONE))
+                                   laddr, lport, fib) != INPLOOKUP_MATCH_NONE))
                                        return (inp);
                                inp_unlock(inp, lockflags);
                        }
                        inp = INP_LOOKUP_AGAIN;
                } else {
                        inp = in6_pcblookup_hash_wild_smr(pcbinfo, laddr, lport,
-                           lockflags);
+                           fib, lockflags);
                }
                if (inp == INP_LOOKUP_AGAIN) {
                        return (in6_pcblookup_hash(pcbinfo, faddr, fport, laddr,
-                           lport, lookupflags, numa_domain));
+                           lport, lookupflags, numa_domain, fib));
                }
        }
 
@@ -1298,10 +1304,13 @@ in6_pcblookup_hash_smr(struct inpcbinfo *pcbinfo, const 
struct in6_addr *faddr,
 struct inpcb *
 in6_pcblookup(struct inpcbinfo *pcbinfo, const struct in6_addr *faddr,
     u_int fport, const struct in6_addr *laddr, u_int lport, int lookupflags,
-    struct ifnet *ifp __unused)
+    struct ifnet *ifp)
 {
+       int fib;
+
+       fib = (lookupflags & INPLOOKUP_FIB) ? if_getfib(ifp) : RT_ALL_FIBS;
        return (in6_pcblookup_hash_smr(pcbinfo, faddr, fport, laddr, lport,
-           lookupflags, M_NODOM));
+           lookupflags, M_NODOM, fib));
 }
 
 struct inpcb *
@@ -1309,8 +1318,12 @@ in6_pcblookup_mbuf(struct inpcbinfo *pcbinfo, const 
struct in6_addr *faddr,
     u_int fport, const struct in6_addr *laddr, u_int lport, int lookupflags,
     struct ifnet *ifp __unused, struct mbuf *m)
 {
+       int fib;
+
+       M_ASSERTPKTHDR(m);
+       fib = (lookupflags & INPLOOKUP_FIB) ? M_GETFIB(m) : RT_ALL_FIBS;
        return (in6_pcblookup_hash_smr(pcbinfo, faddr, fport, laddr, lport,
-           lookupflags, m->m_pkthdr.numa_domain));
+           lookupflags, m->m_pkthdr.numa_domain, fib));
 }
 
 void
diff --git a/sys/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h
index 5a24d1398b47..d578c6a66241 100644
--- a/sys/netinet6/in6_pcb.h
+++ b/sys/netinet6/in6_pcb.h
@@ -81,7 +81,7 @@ struct inpcb *in6_pcblookup_local(struct inpcbinfo *, const 
struct in6_addr *,
 struct inpcb *in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo,
            const struct in6_addr *faddr, u_int fport_arg,
            const struct in6_addr *laddr, u_int lport_arg,
-           int lookupflags, uint8_t);
+           int lookupflags, uint8_t numa_domain, int fib);
 struct inpcb *in6_pcblookup(struct inpcbinfo *, const struct in6_addr *, u_int,
            const struct in6_addr *, u_int, int, struct ifnet *);
 struct inpcb *in6_pcblookup_mbuf(struct inpcbinfo *, const struct in6_addr *,

Reply via email to