Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111025298
D48662.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D48662.diff
View Options
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -621,10 +621,11 @@
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/netinet/in_pcb.c b/sys/netinet/in_pcb.c
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -139,7 +139,7 @@
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); } \
@@ -846,14 +846,14 @@
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 {
@@ -1445,7 +1445,7 @@
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;
@@ -2136,15 +2136,16 @@
#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;
@@ -2183,20 +2184,20 @@
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;
}
}
@@ -2268,7 +2269,7 @@
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 */
@@ -2277,6 +2278,8 @@
#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)
@@ -2288,7 +2291,7 @@
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;
@@ -2301,12 +2304,12 @@
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)
@@ -2325,7 +2328,7 @@
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;
@@ -2352,7 +2355,7 @@
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;
@@ -2405,12 +2408,12 @@
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__));
@@ -2424,10 +2427,10 @@
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);
}
}
@@ -2437,7 +2440,7 @@
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;
@@ -2447,7 +2450,7 @@
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);
@@ -2464,7 +2467,7 @@
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;
@@ -2494,27 +2497,27 @@
* 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));
}
}
@@ -2531,10 +2534,13 @@
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 *
@@ -2542,8 +2548,12 @@
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/netinet6/in6_pcb.h b/sys/netinet6/in6_pcb.h
--- a/sys/netinet6/in6_pcb.h
+++ b/sys/netinet6/in6_pcb.h
@@ -79,7 +79,7 @@
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 *,
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c
--- a/sys/netinet6/in6_pcb.c
+++ b/sys/netinet6/in6_pcb.c
@@ -499,7 +499,7 @@
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) {
@@ -899,15 +899,16 @@
}
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;
@@ -916,6 +917,7 @@
u_int count;
INP_HASH_LOCK_ASSERT(pcbinfo);
+ NET_EPOCH_ASSERT();
hdr = &pcbinfo->ipi_lbgrouphashbase[
INP_PCBPORTHASH(lport, pcbinfo->ipi_lbgrouphashmask)];
@@ -945,20 +947,20 @@
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;
}
}
@@ -1030,7 +1032,7 @@
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)
@@ -1038,6 +1040,8 @@
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))
@@ -1049,7 +1053,8 @@
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;
@@ -1062,12 +1067,13 @@
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)
@@ -1086,7 +1092,7 @@
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;
@@ -1107,7 +1113,7 @@
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;
@@ -1147,12 +1153,12 @@
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__));
@@ -1166,10 +1172,10 @@
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);
@@ -1178,7 +1184,7 @@
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;
@@ -1188,7 +1194,7 @@
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);
@@ -1205,7 +1211,7 @@
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;
@@ -1230,27 +1236,27 @@
* 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));
}
}
@@ -1267,10 +1273,13 @@
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 *
@@ -1278,8 +1287,12 @@
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
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 27, 9:21 AM (19 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16862389
Default Alt Text
D48662.diff (17 KB)
Attached To
Mode
D48662: inpcb: Add FIB-aware inpcb lookup
Attached
Detach File
Event Timeline
Log In to Comment