Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/in_pcb.c
Show First 20 Lines • Show All 2,512 Lines • ▼ Show 20 Lines | |||||
static struct inpcb * | static struct inpcb * | ||||
in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr, | in_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in_addr faddr, | ||||
u_int fport, struct in_addr laddr, u_int lport, int lookupflags, | u_int fport, struct in_addr laddr, u_int lport, int lookupflags, | ||||
struct ifnet *ifp, uint8_t numa_domain) | struct ifnet *ifp, uint8_t numa_domain) | ||||
{ | { | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
inp = in_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport, | inp = in_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport, | ||||
(lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp, | lookupflags & INPLOOKUP_WILDCARD, ifp, numa_domain); | ||||
numa_domain); | |||||
if (inp != NULL) { | if (inp != NULL) { | ||||
if (lookupflags & INPLOOKUP_WLOCKPCB) { | if (lookupflags & INPLOOKUP_WLOCKPCB) { | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
if (__predict_false(inp->inp_flags2 & INP_FREED)) { | |||||
INP_WUNLOCK(inp); | |||||
inp = NULL; | |||||
} | |||||
} else if (lookupflags & INPLOOKUP_RLOCKPCB) { | } else if (lookupflags & INPLOOKUP_RLOCKPCB) { | ||||
INP_RLOCK(inp); | INP_RLOCK(inp); | ||||
} else if (lookupflags & INPLOOKUP_RLOCKLISTEN) { | |||||
if (inp->inp_socket != NULL && | |||||
SOLISTENING(inp->inp_socket)) | |||||
INP_RLOCK(inp); | |||||
else | |||||
INP_WLOCK(inp); | |||||
} else | |||||
panic("%s: locking bug", __func__); | |||||
if (__predict_false(inp->inp_flags2 & INP_FREED)) { | if (__predict_false(inp->inp_flags2 & INP_FREED)) { | ||||
INP_RUNLOCK(inp); | INP_UNLOCK(inp); | ||||
inp = NULL; | inp = NULL; | ||||
} | } | ||||
} else | |||||
panic("%s: locking bug", __func__); | |||||
#ifdef INVARIANTS | |||||
if (inp != NULL) { | |||||
if (lookupflags & INPLOOKUP_WLOCKPCB) | |||||
INP_WLOCK_ASSERT(inp); | |||||
else | |||||
INP_RLOCK_ASSERT(inp); | |||||
} | } | ||||
#endif | |||||
} | |||||
return (inp); | return (inp); | ||||
} | } | ||||
/* | /* | ||||
* Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf | * Public inpcb lookup routines, accepting a 4-tuple, and optionally, an mbuf | ||||
* from which a pre-calculated hash value may be extracted. | * from which a pre-calculated hash value may be extracted. | ||||
* | * | ||||
* Possibly more of this logic should be in in_pcbgroup.c. | * Possibly more of this logic should be in in_pcbgroup.c. | ||||
*/ | */ | ||||
struct inpcb * | struct inpcb * | ||||
in_pcblookup(struct inpcbinfo *pcbinfo, struct in_addr faddr, u_int fport, | in_pcblookup(struct inpcbinfo *pcbinfo, struct in_addr faddr, u_int fport, | ||||
struct in_addr laddr, u_int lport, int lookupflags, struct ifnet *ifp) | struct in_addr laddr, u_int lport, int lookupflags, struct ifnet *ifp) | ||||
{ | { | ||||
#if defined(PCBGROUP) && !defined(RSS) | #if defined(PCBGROUP) && !defined(RSS) | ||||
struct inpcbgroup *pcbgroup; | struct inpcbgroup *pcbgroup; | ||||
#endif | #endif | ||||
KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0, | KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0, | ||||
("%s: invalid lookup flags %d", __func__, lookupflags)); | ("%s: invalid lookup flags %d", __func__, lookupflags)); | ||||
KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0, | KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB | | ||||
("%s: LOCKPCB not set", __func__)); | INPLOOKUP_RLOCKLISTEN)) != 0, ("%s: LOCKPCB not set", __func__)); | ||||
/* | /* | ||||
* When not using RSS, use connection groups in preference to the | * When not using RSS, use connection groups in preference to the | ||||
* reservation table when looking up 4-tuples. When using RSS, just | * reservation table when looking up 4-tuples. When using RSS, just | ||||
* use the reservation table, due to the cost of the Toeplitz hash | * use the reservation table, due to the cost of the Toeplitz hash | ||||
* in software. | * in software. | ||||
* | * | ||||
* XXXRW: This policy belongs in the pcbgroup code, as in principle | * XXXRW: This policy belongs in the pcbgroup code, as in principle | ||||
Show All 18 Lines | in_pcblookup_mbuf(struct inpcbinfo *pcbinfo, struct in_addr faddr, | ||||
struct ifnet *ifp, struct mbuf *m) | struct ifnet *ifp, struct mbuf *m) | ||||
{ | { | ||||
#ifdef PCBGROUP | #ifdef PCBGROUP | ||||
struct inpcbgroup *pcbgroup; | struct inpcbgroup *pcbgroup; | ||||
#endif | #endif | ||||
KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0, | KASSERT((lookupflags & ~INPLOOKUP_MASK) == 0, | ||||
("%s: invalid lookup flags %d", __func__, lookupflags)); | ("%s: invalid lookup flags %d", __func__, lookupflags)); | ||||
KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)) != 0, | KASSERT((lookupflags & (INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB | | ||||
("%s: LOCKPCB not set", __func__)); | INPLOOKUP_RLOCKLISTEN)) != 0, ("%s: LOCKPCB not set", __func__)); | ||||
#ifdef PCBGROUP | #ifdef PCBGROUP | ||||
/* | /* | ||||
* If we can use a hardware-generated hash to look up the connection | * If we can use a hardware-generated hash to look up the connection | ||||
* group, use that connection group to find the inpcb. Otherwise | * group, use that connection group to find the inpcb. Otherwise | ||||
* fall back on a software hash -- or the reservation table if we're | * fall back on a software hash -- or the reservation table if we're | ||||
* using RSS. | * using RSS. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 998 Lines • Show Last 20 Lines |