inpcb: Move inpcb matching logic into separate functions
These functions will get some additional callers in future revisions. No functional change intended. Discussed with: glebius Tested by: glebius Sponsored by: Modirum MDPay Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D38571
This commit is contained in:
parent
fdb987bebd
commit
3e98dcb3d5
@ -2180,31 +2180,63 @@ in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
|
||||
grp->il_inpcnt]);
|
||||
}
|
||||
|
||||
static bool
|
||||
in_pcblookup_exact_match(const struct inpcb *inp, struct in_addr faddr,
|
||||
u_short fport, struct in_addr laddr, u_short lport)
|
||||
{
|
||||
#ifdef INET6
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV4) == 0)
|
||||
return (false);
|
||||
#endif
|
||||
if (inp->inp_faddr.s_addr == faddr.s_addr &&
|
||||
inp->inp_laddr.s_addr == laddr.s_addr &&
|
||||
inp->inp_fport == fport &&
|
||||
inp->inp_lport == lport)
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
static struct inpcb *
|
||||
in_pcblookup_hash_exact(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
||||
u_short fport, struct in_addr laddr, u_short lport)
|
||||
{
|
||||
struct inpcbhead *head;
|
||||
struct inpcb *inp, *match;
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_HASH_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
match = NULL;
|
||||
head = &pcbinfo->ipi_hash_exact[INP_PCBHASH(&faddr, lport, fport,
|
||||
pcbinfo->ipi_hashmask)];
|
||||
CK_LIST_FOREACH(inp, head, inp_hash_exact) {
|
||||
#ifdef INET6
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
#endif
|
||||
if (inp->inp_faddr.s_addr == faddr.s_addr &&
|
||||
inp->inp_laddr.s_addr == laddr.s_addr &&
|
||||
inp->inp_fport == fport &&
|
||||
inp->inp_lport == lport)
|
||||
if (in_pcblookup_exact_match(inp, faddr, fport, laddr, lport))
|
||||
return (inp);
|
||||
}
|
||||
return (match);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
INPLOOKUP_MATCH_NONE = 0,
|
||||
INPLOOKUP_MATCH_WILD = 1,
|
||||
INPLOOKUP_MATCH_LADDR = 2,
|
||||
} inp_lookup_match_t;
|
||||
|
||||
static inp_lookup_match_t
|
||||
in_pcblookup_wild_match(const struct inpcb *inp, struct in_addr laddr,
|
||||
u_short lport)
|
||||
{
|
||||
#ifdef INET6
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV4) == 0)
|
||||
return (INPLOOKUP_MATCH_NONE);
|
||||
#endif
|
||||
if (inp->inp_faddr.s_addr != INADDR_ANY || inp->inp_lport != lport)
|
||||
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)
|
||||
return (INPLOOKUP_MATCH_LADDR);
|
||||
return (INPLOOKUP_MATCH_NONE);
|
||||
}
|
||||
|
||||
static struct inpcb *
|
||||
@ -2233,15 +2265,11 @@ in_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
||||
local_wild_mapped = NULL;
|
||||
#endif
|
||||
CK_LIST_FOREACH(inp, head, inp_hash_wild) {
|
||||
inp_lookup_match_t match;
|
||||
bool injail;
|
||||
|
||||
#ifdef INET6
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
#endif
|
||||
if (inp->inp_faddr.s_addr != INADDR_ANY ||
|
||||
inp->inp_lport != lport)
|
||||
match = in_pcblookup_wild_match(inp, laddr, lport);
|
||||
if (match == INPLOOKUP_MATCH_NONE)
|
||||
continue;
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP4) != 0;
|
||||
@ -2254,11 +2282,11 @@ in_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inp->inp_laddr.s_addr == laddr.s_addr) {
|
||||
if (match == INPLOOKUP_MATCH_LADDR) {
|
||||
if (injail)
|
||||
return (inp);
|
||||
local_exact = inp;
|
||||
} else if (inp->inp_laddr.s_addr == INADDR_ANY) {
|
||||
} else {
|
||||
#ifdef INET6
|
||||
/* XXX inp locking, NULL check */
|
||||
if (inp->inp_vflag & INP_IPV6PROTO)
|
||||
|
@ -939,32 +939,62 @@ in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo,
|
||||
grp->il_inpcnt]);
|
||||
}
|
||||
|
||||
static bool
|
||||
in6_pcblookup_exact_match(const struct inpcb *inp, const struct in6_addr *faddr,
|
||||
u_short fport, const struct in6_addr *laddr, u_short lport)
|
||||
{
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV6) == 0)
|
||||
return (false);
|
||||
if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
|
||||
IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
|
||||
inp->inp_fport == fport && inp->inp_lport == lport)
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
static struct inpcb *
|
||||
in6_pcblookup_hash_exact(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
||||
u_short fport, struct in6_addr *laddr, u_short lport)
|
||||
{
|
||||
struct inpcbhead *head;
|
||||
struct inpcb *inp, *match;
|
||||
struct inpcb *inp;
|
||||
|
||||
INP_HASH_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
/*
|
||||
* First look for an exact match.
|
||||
*/
|
||||
match = NULL;
|
||||
head = &pcbinfo->ipi_hash_exact[INP6_PCBHASH(faddr, lport, fport,
|
||||
pcbinfo->ipi_hashmask)];
|
||||
CK_LIST_FOREACH(inp, head, inp_hash_exact) {
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV6) == 0)
|
||||
continue;
|
||||
if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
|
||||
IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
|
||||
inp->inp_fport == fport &&
|
||||
inp->inp_lport == lport)
|
||||
if (in6_pcblookup_exact_match(inp, faddr, fport, laddr, lport))
|
||||
return (inp);
|
||||
}
|
||||
return (match);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
INPLOOKUP_MATCH_NONE = 0,
|
||||
INPLOOKUP_MATCH_WILD = 1,
|
||||
INPLOOKUP_MATCH_LADDR = 2,
|
||||
} inp_lookup_match_t;
|
||||
|
||||
static inp_lookup_match_t
|
||||
in6_pcblookup_wild_match(const struct inpcb *inp, const struct in6_addr *laddr,
|
||||
u_short lport)
|
||||
{
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV6) == 0)
|
||||
return (INPLOOKUP_MATCH_NONE);
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) ||
|
||||
inp->inp_lport != lport)
|
||||
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))
|
||||
return (INPLOOKUP_MATCH_LADDR);
|
||||
return (INPLOOKUP_MATCH_NONE);
|
||||
}
|
||||
|
||||
static struct inpcb *
|
||||
@ -975,6 +1005,8 @@ in6_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo,
|
||||
struct inpcbhead *head;
|
||||
struct inpcb *inp, *jail_wild, *local_exact, *local_wild;
|
||||
|
||||
INP_HASH_LOCK_ASSERT(pcbinfo);
|
||||
|
||||
/*
|
||||
* Order of socket selection - we always prefer jails.
|
||||
* 1. jailed, non-wild.
|
||||
@ -986,17 +1018,13 @@ in6_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo,
|
||||
pcbinfo->ipi_hashmask)];
|
||||
local_wild = local_exact = jail_wild = NULL;
|
||||
CK_LIST_FOREACH(inp, head, inp_hash_wild) {
|
||||
inp_lookup_match_t match;
|
||||
bool injail;
|
||||
|
||||
/* XXX inp locking */
|
||||
if ((inp->inp_vflag & INP_IPV6) == 0)
|
||||
match = in6_pcblookup_wild_match(inp, laddr, lport);
|
||||
if (match == INPLOOKUP_MATCH_NONE)
|
||||
continue;
|
||||
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) ||
|
||||
inp->inp_lport != lport) {
|
||||
continue;
|
||||
}
|
||||
|
||||
injail = prison_flag(inp->inp_cred, PR_IP6) != 0;
|
||||
if (injail) {
|
||||
if (prison_check_ip6_locked(
|
||||
@ -1007,12 +1035,12 @@ in6_pcblookup_hash_wild_locked(struct inpcbinfo *pcbinfo,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr)) {
|
||||
if (match == INPLOOKUP_MATCH_LADDR) {
|
||||
if (injail)
|
||||
return (inp);
|
||||
else
|
||||
local_exact = inp;
|
||||
} else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
|
||||
} else {
|
||||
if (injail)
|
||||
jail_wild = inp;
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user