Page MenuHomeFreeBSD

D38571.diff
No OneTemporary

D38571.diff

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
@@ -2180,31 +2180,63 @@
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 @@
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 @@
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)
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
@@ -939,32 +939,62 @@
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 @@
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 @@
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 @@
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

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 28, 4:05 AM (10 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16246289
Default Alt Text
D38571.diff (6 KB)

Event Timeline