inpcb: immediately return matching pcb on lookup
This saves a lot of CPU cycles if you got large connection table.
The code removed originates from 413628a7e3, a very large changeset.
Discussed that with Bjoern, Jamie we can't recover why would we ever
have identical 4-tuples in the hash, even in the presence of jails.
Bjoern did a test that confirms that it is impossible to allocate an
identical connection from a jail to a host. Code review also confirms
that system shouldn't allow for such connections to exist.
With a lack of proper test suite we decided to take a risk and go
forward with removing that code.
Reviewed by: gallatin, bz, markj
Differential Revision: https://reviews.freebsd.org/D38015
This commit is contained in:
+3
-15
@@ -2225,7 +2225,7 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
|||||||
struct ifnet *ifp, uint8_t numa_domain)
|
struct ifnet *ifp, uint8_t numa_domain)
|
||||||
{
|
{
|
||||||
struct inpcbhead *head;
|
struct inpcbhead *head;
|
||||||
struct inpcb *inp, *tmpinp;
|
struct inpcb *inp;
|
||||||
u_short fport = fport_arg, lport = lport_arg;
|
u_short fport = fport_arg, lport = lport_arg;
|
||||||
|
|
||||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||||
@@ -2239,7 +2239,6 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
|||||||
/*
|
/*
|
||||||
* First look for an exact match.
|
* First look for an exact match.
|
||||||
*/
|
*/
|
||||||
tmpinp = NULL;
|
|
||||||
head = &pcbinfo->ipi_hashbase[INP_PCBHASH(&faddr, lport, fport,
|
head = &pcbinfo->ipi_hashbase[INP_PCBHASH(&faddr, lport, fport,
|
||||||
pcbinfo->ipi_hashmask)];
|
pcbinfo->ipi_hashmask)];
|
||||||
CK_LIST_FOREACH(inp, head, inp_hash) {
|
CK_LIST_FOREACH(inp, head, inp_hash) {
|
||||||
@@ -2251,20 +2250,9 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr,
|
|||||||
if (inp->inp_faddr.s_addr == faddr.s_addr &&
|
if (inp->inp_faddr.s_addr == faddr.s_addr &&
|
||||||
inp->inp_laddr.s_addr == laddr.s_addr &&
|
inp->inp_laddr.s_addr == laddr.s_addr &&
|
||||||
inp->inp_fport == fport &&
|
inp->inp_fport == fport &&
|
||||||
inp->inp_lport == lport) {
|
inp->inp_lport == lport)
|
||||||
/*
|
return (inp);
|
||||||
* XXX We should be able to directly return
|
|
||||||
* the inp here, without any checks.
|
|
||||||
* Well unless both bound with SO_REUSEPORT?
|
|
||||||
*/
|
|
||||||
if (prison_flag(inp->inp_cred, PR_IP4))
|
|
||||||
return (inp);
|
|
||||||
if (tmpinp == NULL)
|
|
||||||
tmpinp = inp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (tmpinp != NULL)
|
|
||||||
return (tmpinp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Then look for a wildcard match, if requested.
|
* Then look for a wildcard match, if requested.
|
||||||
|
|||||||
+3
-15
@@ -966,7 +966,7 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
|||||||
int lookupflags, struct ifnet *ifp, uint8_t numa_domain)
|
int lookupflags, struct ifnet *ifp, uint8_t numa_domain)
|
||||||
{
|
{
|
||||||
struct inpcbhead *head;
|
struct inpcbhead *head;
|
||||||
struct inpcb *inp, *tmpinp;
|
struct inpcb *inp;
|
||||||
u_short fport = fport_arg, lport = lport_arg;
|
u_short fport = fport_arg, lport = lport_arg;
|
||||||
|
|
||||||
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
|
||||||
@@ -981,7 +981,6 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
|||||||
/*
|
/*
|
||||||
* First look for an exact match.
|
* First look for an exact match.
|
||||||
*/
|
*/
|
||||||
tmpinp = NULL;
|
|
||||||
head = &pcbinfo->ipi_hashbase[INP6_PCBHASH(faddr, lport, fport,
|
head = &pcbinfo->ipi_hashbase[INP6_PCBHASH(faddr, lport, fport,
|
||||||
pcbinfo->ipi_hashmask)];
|
pcbinfo->ipi_hashmask)];
|
||||||
CK_LIST_FOREACH(inp, head, inp_hash) {
|
CK_LIST_FOREACH(inp, head, inp_hash) {
|
||||||
@@ -991,20 +990,9 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr,
|
|||||||
if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
|
if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
|
||||||
IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
|
IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
|
||||||
inp->inp_fport == fport &&
|
inp->inp_fport == fport &&
|
||||||
inp->inp_lport == lport) {
|
inp->inp_lport == lport)
|
||||||
/*
|
return (inp);
|
||||||
* XXX We should be able to directly return
|
|
||||||
* the inp here, without any checks.
|
|
||||||
* Well unless both bound with SO_REUSEPORT?
|
|
||||||
*/
|
|
||||||
if (prison_flag(inp->inp_cred, PR_IP6))
|
|
||||||
return (inp);
|
|
||||||
if (tmpinp == NULL)
|
|
||||||
tmpinp = inp;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (tmpinp != NULL)
|
|
||||||
return (tmpinp);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Then look for a wildcard match, if requested.
|
* Then look for a wildcard match, if requested.
|
||||||
|
|||||||
Reference in New Issue
Block a user