Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153318808
D56489.id175846.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D56489.id175846.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D56489: inpcb: remove port hash and relax port "stealing" constraint
Attached
Detach File
Event Timeline
Log In to Comment