mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
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 da806e8db6)
This commit is contained in:
parent
ff45a1ca2e
commit
685d1d78bf
4 changed files with 87 additions and 63 deletions
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 *,
|
||||
|
|
|
|||
Loading…
Reference in a new issue