Page MenuHomeFreeBSD

D56489.id175846.diff
No OneTemporary

D56489.id175846.diff

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
@@ -407,7 +407,6 @@
int in6p_cksum;
short in6p_hops;
};
- CK_LIST_ENTRY(inpcb) inp_portlist; /* (r:e/w:h) port list */
uint64_t inp_gencnt; /* (c) generation count */
void *spare_ptr; /* Spare pointer. */
rt_gen_t inp_rt_cookie; /* generation for route entry */
@@ -465,11 +464,6 @@
u_long ipi_hashmask; /* (c) */
u_long ipi_porthashmask; /* (h) */
- /*
- * Global hash of inpcbs, hashed by only local port number.
- */
- struct inpcbhead *ipi_porthashbase; /* (h) */
-
/*
* Load balance groups used for the SO_REUSEPORT_LB option,
* hashed by local port.
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
@@ -566,7 +566,6 @@
pcbinfo->ipi_hashmask = ha.size - 1;
ha.size = imin(porthash_nelements, IPPORT_MAX + 1);
- pcbinfo->ipi_porthashbase = hashalloc(&ha);
pcbinfo->ipi_lbgrouphashbase = hashalloc(&ha);
pcbinfo->ipi_porthashmask = ha.size - 1;
@@ -592,7 +591,6 @@
hashfree(pcbinfo->ipi_hash_exact, &ha);
hashfree(pcbinfo->ipi_hash_wild, &ha);
ha.size = pcbinfo->ipi_porthashmask + 1;
- hashfree(pcbinfo->ipi_porthashbase, &ha);
hashfree(pcbinfo->ipi_lbgrouphashbase, &ha);
mtx_destroy(&pcbinfo->ipi_hash_lock);
}
@@ -2023,18 +2021,13 @@
* Lookup a PCB based on the local address and port. Caller must hold the
* hash lock. No inpcb locks or references are acquired.
*/
-#define INP_LOOKUP_MAPPED_PCB_COST 3
struct inpcb *
in_pcblookup_local(struct inpcbinfo *pcbinfo, struct in_addr laddr,
u_short lport, int fib, int lookupflags, struct ucred *cred)
{
+ struct inpcbhead *head;
struct inpcb *inp;
-#ifdef INET6
- int matchwild = 3 + INP_LOOKUP_MAPPED_PCB_COST;
-#else
- int matchwild = 3;
-#endif
- int wildcard;
+ bool wild_okay;
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
("%s: invalid lookup flags %d", __func__, lookupflags));
@@ -2043,94 +2036,37 @@
INP_HASH_LOCK_ASSERT(pcbinfo);
- if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
- struct inpcbhead *head;
- /*
- * Look for an unconnected (wildcard foreign addr) PCB that
- * matches the local address and port we're looking for.
- */
- head = &pcbinfo->ipi_hash_wild[INP_PCBHASH_WILD(lport,
- pcbinfo->ipi_hashmask)];
- CK_LIST_FOREACH(inp, head, inp_hash_wild) {
+ /*
+ * Look for an unconnected (wildcard foreign addr) PCB that
+ * matches the local address and port we're looking for.
+ */
+ wild_okay = (lookupflags & INPLOOKUP_WILDCARD);
+ head = &pcbinfo->ipi_hash_wild[INP_PCBHASH_WILD(lport,
+ pcbinfo->ipi_hashmask)];
+ CK_LIST_FOREACH(inp, head, inp_hash_wild) {
#ifdef INET6
- /* XXX inp locking */
- if ((inp->inp_vflag & INP_IPV4) == 0)
- continue;
+ /* XXX inp locking */
+ if ((inp->inp_vflag & INP_IPV4) == 0)
+ continue;
#endif
- if (inp->inp_laddr.s_addr == laddr.s_addr &&
- inp->inp_lport == lport && (fib == RT_ALL_FIBS ||
- inp->inp_inc.inc_fibnum == fib)) {
- /*
- * Found?
- */
- if (prison_equal_ip4(cred->cr_prison,
- inp->inp_cred->cr_prison))
- return (inp);
- }
- }
- /*
- * Not found.
- */
- return (NULL);
- } else {
- struct inpcbhead *porthash;
- struct inpcb *match = NULL;
-
- /*
- * Port is in use by one or more PCBs. Look for best
- * fit.
- */
- porthash = &pcbinfo->ipi_porthashbase[INP_PCBPORTHASH(lport,
- pcbinfo->ipi_porthashmask)];
- CK_LIST_FOREACH(inp, porthash, inp_portlist) {
- if (inp->inp_lport != lport)
- continue;
- if (!prison_equal_ip4(inp->inp_cred->cr_prison,
- cred->cr_prison))
- continue;
- if (fib != RT_ALL_FIBS &&
- inp->inp_inc.inc_fibnum != fib)
- continue;
- wildcard = 0;
-#ifdef INET6
- /* XXX inp locking */
- if ((inp->inp_vflag & INP_IPV4) == 0)
- continue;
+ if (inp->inp_lport == lport &&
+ ((wild_okay &&
+ (in_nullhost(inp->inp_laddr) || in_nullhost(laddr))) ||
+ inp->inp_laddr.s_addr == laddr.s_addr) &&
+ (fib == RT_ALL_FIBS || inp->inp_inc.inc_fibnum == fib)) {
/*
- * We never select the PCB that has INP_IPV6 flag and
- * is bound to :: if we have another PCB which is bound
- * to 0.0.0.0. If a PCB has the INP_IPV6 flag, then we
- * set its cost higher than IPv4 only PCBs.
- *
- * Note that the case only happens when a socket is
- * bound to ::, under the condition that the use of the
- * mapped address is allowed.
+ * Found?
*/
- if ((inp->inp_vflag & INP_IPV6) != 0)
- wildcard += INP_LOOKUP_MAPPED_PCB_COST;
-#endif
- if (inp->inp_faddr.s_addr != INADDR_ANY)
- wildcard++;
- if (inp->inp_laddr.s_addr != INADDR_ANY) {
- if (laddr.s_addr == INADDR_ANY)
- wildcard++;
- else if (inp->inp_laddr.s_addr != laddr.s_addr)
- continue;
- } else {
- if (laddr.s_addr != INADDR_ANY)
- wildcard++;
- }
- if (wildcard < matchwild) {
- match = inp;
- matchwild = wildcard;
- if (matchwild == 0)
- break;
- }
+ if (prison_equal_ip4(cred->cr_prison,
+ inp->inp_cred->cr_prison))
+ return (inp);
}
- return (match);
}
+ /*
+ * Not found.
+ */
+ return (NULL);
}
-#undef INP_LOOKUP_MAPPED_PCB_COST
static bool
in_pcblookup_lb_match(const struct inpcblbgroup *grp, int domain, int fib)
@@ -2682,7 +2618,7 @@
int
in_pcbinshash(struct inpcb *inp)
{
- struct inpcbhead *pcbhash, *pcbporthash;
+ struct inpcbhead *pcbhash;
struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
uint32_t hash;
bool connected;
@@ -2709,9 +2645,6 @@
else
pcbhash = &pcbinfo->ipi_hash_wild[hash];
- pcbporthash = &pcbinfo->ipi_porthashbase[
- INP_PCBPORTHASH(inp->inp_lport, pcbinfo->ipi_porthashmask)];
-
/*
* Ignore SO_REUSEPORT_LB if the socket is connected. Really this case
* should be an error, but for UDP sockets it is not, and some
@@ -2747,7 +2680,6 @@
#endif
_in_pcbinshash_wild(pcbhash, inp);
}
- CK_LIST_INSERT_HEAD(pcbporthash, inp, inp_portlist);
inp->inp_flags &= ~INP_UNCONNECTED;
return (0);
@@ -2777,7 +2709,6 @@
else
CK_LIST_REMOVE(inp, inp_hash_exact);
}
- CK_LIST_REMOVE(inp, inp_portlist);
}
/*
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -2939,9 +2939,17 @@
show_inpcb = strchr(modif, 'i') != NULL;
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
- for (u_int i = 0; i <= V_tcbinfo.ipi_porthashmask; i++)
- CK_LIST_FOREACH(inp, &V_tcbinfo.ipi_porthashbase[i],
- inp_portlist) {
+ for (u_int i = 0; i <= V_tcbinfo.ipi_hashmask; i++)
+ CK_LIST_FOREACH(inp, &V_tcbinfo.ipi_hash_exact[i],
+ inp_hash_exact) {
+ db_print_tcpcb(intotcpcb(inp), "tcpcb", 0,
+ show_bblog, show_inpcb, only_locked);
+ if (db_pager_quit)
+ goto break_hash;
+ }
+ for (u_int i = 0; i <= V_tcbinfo.ipi_hashmask; i++)
+ CK_LIST_FOREACH(inp, &V_tcbinfo.ipi_hash_wild[i],
+ inp_hash_wild) {
db_print_tcpcb(intotcpcb(inp), "tcpcb", 0,
show_bblog, show_inpcb, only_locked);
if (db_pager_quit)
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
@@ -731,8 +731,9 @@
in6_pcblookup_local(struct inpcbinfo *pcbinfo, const struct in6_addr *laddr,
u_short lport, int fib, int lookupflags, struct ucred *cred)
{
+ struct inpcbhead *head;
struct inpcb *inp;
- int matchwild = 3, wildcard;
+ bool wild_okay;
KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0,
("%s: invalid lookup flags %d", __func__, lookupflags));
@@ -741,75 +742,32 @@
INP_HASH_LOCK_ASSERT(pcbinfo);
- if ((lookupflags & INPLOOKUP_WILDCARD) == 0) {
- struct inpcbhead *head;
- /*
- * Look for an unconnected (wildcard foreign addr) PCB that
- * matches the local address and port we're looking for.
- */
- head = &pcbinfo->ipi_hash_wild[INP_PCBHASH_WILD(lport,
- pcbinfo->ipi_hashmask)];
- CK_LIST_FOREACH(inp, head, inp_hash_wild) {
- /* XXX inp locking */
- if ((inp->inp_vflag & INP_IPV6) == 0)
- continue;
- if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
- inp->inp_lport == lport && (fib == RT_ALL_FIBS ||
- inp->inp_inc.inc_fibnum == fib)) {
- /* Found. */
- if (prison_equal_ip6(cred->cr_prison,
- inp->inp_cred->cr_prison))
- return (inp);
- }
- }
- /*
- * Not found.
- */
- return (NULL);
- } else {
- struct inpcbhead *porthash;
- struct inpcb *match = NULL;
-
- /*
- * Port is in use by one or more PCBs. Look for best
- * fit.
- */
- porthash = &pcbinfo->ipi_porthashbase[INP_PCBPORTHASH(lport,
- pcbinfo->ipi_porthashmask)];
- CK_LIST_FOREACH(inp, porthash, inp_portlist) {
- if (inp->inp_lport != lport)
- continue;
- if (!prison_equal_ip6(cred->cr_prison,
+ /*
+ * Look for an unconnected (wildcard foreign addr) PCB that
+ * matches the local address and port we're looking for.
+ */
+ wild_okay = (lookupflags & INPLOOKUP_WILDCARD);
+ head = &pcbinfo->ipi_hash_wild[INP_PCBHASH_WILD(lport,
+ pcbinfo->ipi_hashmask)];
+ CK_LIST_FOREACH(inp, head, inp_hash_wild) {
+ /* XXX inp locking */
+ if ((inp->inp_vflag & INP_IPV6) == 0)
+ continue;
+ if (inp->inp_lport == lport &&
+ ((wild_okay && (IN6_IS_ADDR_UNSPECIFIED(laddr) ||
+ IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))) ||
+ IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr)) &&
+ (fib == RT_ALL_FIBS || inp->inp_inc.inc_fibnum == fib)) {
+ /* Found. */
+ if (prison_equal_ip6(cred->cr_prison,
inp->inp_cred->cr_prison))
- continue;
- /* XXX inp locking */
- if ((inp->inp_vflag & INP_IPV6) == 0)
- continue;
- if (fib != RT_ALL_FIBS &&
- inp->inp_inc.inc_fibnum != fib)
- continue;
- wildcard = 0;
- if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
- wildcard++;
- if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
- if (IN6_IS_ADDR_UNSPECIFIED(laddr))
- wildcard++;
- else if (!IN6_ARE_ADDR_EQUAL(
- &inp->in6p_laddr, laddr))
- continue;
- } else {
- if (!IN6_IS_ADDR_UNSPECIFIED(laddr))
- wildcard++;
- }
- if (wildcard < matchwild) {
- match = inp;
- matchwild = wildcard;
- if (matchwild == 0)
- break;
- }
+ return (inp);
}
- return (match);
}
+ /*
+ * Not found.
+ */
+ return (NULL);
}
static bool

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 11:11 AM (4 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31906538
Default Alt Text
D56489.id175846.diff (10 KB)

Event Timeline