Changeset View
Changeset View
Standalone View
Standalone View
head/sys/netinet6/in6_pcb.c
Show First 20 Lines • Show All 862 Lines • ▼ Show 20 Lines | |||||
static struct inpcb * | static struct inpcb * | ||||
in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, | in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, | ||||
struct in6_addr *faddr, u_int fport_arg, struct in6_addr *laddr, | struct in6_addr *faddr, u_int fport_arg, struct in6_addr *laddr, | ||||
u_int lport_arg, int lookupflags, struct ifnet *ifp) | u_int lport_arg, int lookupflags, struct ifnet *ifp) | ||||
{ | { | ||||
struct inpcbhead *head; | struct inpcbhead *head; | ||||
struct inpcb *inp, *tmpinp; | struct inpcb *inp, *tmpinp; | ||||
u_short fport = fport_arg, lport = lport_arg; | u_short fport = fport_arg, lport = lport_arg; | ||||
bool locked; | |||||
/* | /* | ||||
* First look for an exact match. | * First look for an exact match. | ||||
*/ | */ | ||||
tmpinp = NULL; | tmpinp = NULL; | ||||
INP_GROUP_LOCK(pcbgroup); | INP_GROUP_LOCK(pcbgroup); | ||||
head = &pcbgroup->ipg_hashbase[INP_PCBHASH( | head = &pcbgroup->ipg_hashbase[INP_PCBHASH( | ||||
INP6_PCBHASHKEY(faddr), lport, fport, pcbgroup->ipg_hashmask)]; | INP6_PCBHASHKEY(faddr), lport, fport, pcbgroup->ipg_hashmask)]; | ||||
▲ Show 20 Lines • Show All 142 Lines • ▼ Show 20 Lines | if (inp == NULL) | ||||
inp = local_wild; | inp = local_wild; | ||||
if (inp != NULL) | if (inp != NULL) | ||||
goto found; | goto found; | ||||
} /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */ | } /* if ((lookupflags & INPLOOKUP_WILDCARD) != 0) */ | ||||
INP_GROUP_UNLOCK(pcbgroup); | INP_GROUP_UNLOCK(pcbgroup); | ||||
return (NULL); | return (NULL); | ||||
found: | found: | ||||
if (lookupflags & INPLOOKUP_WLOCKPCB) | |||||
locked = INP_TRY_WLOCK(inp); | |||||
else if (lookupflags & INPLOOKUP_RLOCKPCB) | |||||
locked = INP_TRY_RLOCK(inp); | |||||
else | |||||
panic("%s: locking buf", __func__); | |||||
if (!locked) | |||||
in_pcbref(inp); | in_pcbref(inp); | ||||
INP_GROUP_UNLOCK(pcbgroup); | INP_GROUP_UNLOCK(pcbgroup); | ||||
if (!locked) { | |||||
if (lookupflags & INPLOOKUP_WLOCKPCB) { | if (lookupflags & INPLOOKUP_WLOCKPCB) { | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
if (in_pcbrele_wlocked(inp)) | if (in_pcbrele_wlocked(inp)) | ||||
return (NULL); | return (NULL); | ||||
} else if (lookupflags & INPLOOKUP_RLOCKPCB) { | } else { | ||||
INP_RLOCK(inp); | INP_RLOCK(inp); | ||||
if (in_pcbrele_rlocked(inp)) | if (in_pcbrele_rlocked(inp)) | ||||
return (NULL); | return (NULL); | ||||
} else | } | ||||
panic("%s: locking buf", __func__); | } | ||||
#ifdef INVARIANTS | |||||
if (lookupflags & INPLOOKUP_WLOCKPCB) | |||||
INP_WLOCK_ASSERT(inp); | |||||
else | |||||
INP_RLOCK_ASSERT(inp); | |||||
#endif | |||||
return (inp); | return (inp); | ||||
} | } | ||||
#endif /* PCBGROUP */ | #endif /* PCBGROUP */ | ||||
/* | /* | ||||
* Lookup PCB in hash list. | * Lookup PCB in hash list. | ||||
*/ | */ | ||||
static struct inpcb * | static struct inpcb * | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | |||||
* INPLOOKUP_LOCKPCB). | * INPLOOKUP_LOCKPCB). | ||||
*/ | */ | ||||
static struct inpcb * | static struct inpcb * | ||||
in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, | in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, | ||||
u_int fport, struct in6_addr *laddr, u_int lport, int lookupflags, | u_int fport, struct in6_addr *laddr, u_int lport, int lookupflags, | ||||
struct ifnet *ifp) | struct ifnet *ifp) | ||||
{ | { | ||||
struct inpcb *inp; | struct inpcb *inp; | ||||
bool locked; | |||||
INP_HASH_RLOCK(pcbinfo); | INP_HASH_RLOCK(pcbinfo); | ||||
inp = in6_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport, | inp = in6_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport, | ||||
(lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp); | (lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp); | ||||
if (inp != NULL) { | if (inp != NULL) { | ||||
if (lookupflags & INPLOOKUP_WLOCKPCB) | |||||
locked = INP_TRY_WLOCK(inp); | |||||
else if (lookupflags & INPLOOKUP_RLOCKPCB) | |||||
locked = INP_TRY_RLOCK(inp); | |||||
else | |||||
panic("%s: locking bug", __func__); | |||||
if (!locked) | |||||
in_pcbref(inp); | in_pcbref(inp); | ||||
INP_HASH_RUNLOCK(pcbinfo); | INP_HASH_RUNLOCK(pcbinfo); | ||||
if (!locked) { | |||||
if (lookupflags & INPLOOKUP_WLOCKPCB) { | if (lookupflags & INPLOOKUP_WLOCKPCB) { | ||||
INP_WLOCK(inp); | INP_WLOCK(inp); | ||||
if (in_pcbrele_wlocked(inp)) | if (in_pcbrele_wlocked(inp)) | ||||
return (NULL); | return (NULL); | ||||
} else if (lookupflags & INPLOOKUP_RLOCKPCB) { | } else { | ||||
INP_RLOCK(inp); | INP_RLOCK(inp); | ||||
if (in_pcbrele_rlocked(inp)) | if (in_pcbrele_rlocked(inp)) | ||||
return (NULL); | return (NULL); | ||||
} else | } | ||||
panic("%s: locking bug", __func__); | } | ||||
#ifdef INVARIANTS | |||||
if (lookupflags & INPLOOKUP_WLOCKPCB) | |||||
INP_WLOCK_ASSERT(inp); | |||||
else | |||||
INP_RLOCK_ASSERT(inp); | |||||
#endif | |||||
} else | } else | ||||
INP_HASH_RUNLOCK(pcbinfo); | INP_HASH_RUNLOCK(pcbinfo); | ||||
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. | ||||
▲ Show 20 Lines • Show All 95 Lines • Show Last 20 Lines |