aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2026-04-12 18:33:30 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2026-04-12 18:33:30 +0000
commit2c48736c55c2154327f7e9219d4d69224181ab72 (patch)
treef0e80af62b4f83152f64b42f67c5b6ed921385cc /sys/netinet
parent8b4d0bec43116f5d4d1fba89d1b81f1d05805147 (diff)
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_pcb.c17
-rw-r--r--sys/netinet/tcp_syncache.c4
-rw-r--r--sys/netinet/tcp_usrreq.c4
-rw-r--r--sys/netinet/udp_usrreq.c4
4 files changed, 12 insertions, 17 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 6c5b7869d945..69974d931e44 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1096,8 +1096,8 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred)
int error;
bool anonport;
+ NET_EPOCH_ASSERT();
INP_WLOCK_ASSERT(inp);
- INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
KASSERT(in_nullhost(inp->inp_faddr),
("%s: inp is already connected", __func__));
KASSERT(sin->sin_family == AF_INET,
@@ -1134,10 +1134,13 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred)
} else
faddr = sin->sin_addr;
+ INP_HASH_WLOCK(inp->inp_pcbinfo);
if (in_nullhost(inp->inp_laddr)) {
error = in_pcbladdr(inp, &faddr, &laddr, cred);
- if (error)
+ if (__predict_false(error)) {
+ INP_HASH_WUNLOCK(inp->inp_pcbinfo);
return (error);
+ }
} else
laddr = inp->inp_laddr;
@@ -1154,13 +1157,16 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred)
error = in_pcb_lport_dest(inp, (struct sockaddr *)&lsin,
&lport, (struct sockaddr *)&fsin, sin->sin_port, cred,
INPLOOKUP_WILDCARD);
- if (error)
+ if (__predict_false(error)) {
+ INP_HASH_WUNLOCK(inp->inp_pcbinfo);
return (error);
+ }
} else if (in_pcblookup_hash_locked(inp->inp_pcbinfo, faddr,
sin->sin_port, laddr, inp->inp_lport, 0, M_NODOM, RT_ALL_FIBS) !=
- NULL)
+ NULL) {
+ INP_HASH_WUNLOCK(inp->inp_pcbinfo);
return (EADDRINUSE);
- else
+ } else
lport = inp->inp_lport;
MPASS(!in_nullhost(inp->inp_laddr) || inp->inp_lport != 0 ||
@@ -1176,6 +1182,7 @@ in_pcbconnect(struct inpcb *inp, struct sockaddr_in *sin, struct ucred *cred)
MPASS(error == 0);
} else
in_pcbrehash(inp);
+ INP_HASH_WUNLOCK(inp->inp_pcbinfo);
if (V_fib_hash_outbound) {
uint32_t hash_val, hash_type;
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 1d628bce0d80..22f260db9805 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -846,9 +846,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
sin6.sin6_addr = sc->sc_inc.inc6_faddr;
sin6.sin6_port = sc->sc_inc.inc_fport;
sin6.sin6_flowinfo = sin6.sin6_scope_id = 0;
- INP_HASH_WLOCK(&V_tcbinfo);
error = in6_pcbconnect(inp, &sin6, thread0.td_ucred, false);
- INP_HASH_WUNLOCK(&V_tcbinfo);
if (error != 0)
goto abort;
/* Override flowlabel from in6_pcbconnect. */
@@ -875,9 +873,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
sin.sin_addr = sc->sc_inc.inc_faddr;
sin.sin_port = sc->sc_inc.inc_fport;
bzero((caddr_t)sin.sin_zero, sizeof(sin.sin_zero));
- INP_HASH_WLOCK(&V_tcbinfo);
error = in_pcbconnect(inp, &sin, thread0.td_ucred);
- INP_HASH_WUNLOCK(&V_tcbinfo);
if (error != 0)
goto abort;
}
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 72100a0fb9d9..277f8fa2af36 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1424,9 +1424,7 @@ tcp_connect(struct tcpcb *tp, struct sockaddr_in *sin, struct thread *td)
if (__predict_false((so->so_options & SO_REUSEPORT_LB) != 0))
return (EOPNOTSUPP);
- INP_HASH_WLOCK(&V_tcbinfo);
error = in_pcbconnect(inp, sin, td->td_ucred);
- INP_HASH_WUNLOCK(&V_tcbinfo);
if (error != 0)
return (error);
@@ -1473,9 +1471,7 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr_in6 *sin6, struct thread *td)
if (__predict_false((so->so_options & SO_REUSEPORT_LB) != 0))
return (EOPNOTSUPP);
- INP_HASH_WLOCK(&V_tcbinfo);
error = in6_pcbconnect(inp, sin6, td->td_ucred, true);
- INP_HASH_WUNLOCK(&V_tcbinfo);
if (error != 0)
return (error);
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 3e8011542753..a94e1ec813c4 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1644,11 +1644,9 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct epoch_tracker et;
struct inpcb *inp;
- struct inpcbinfo *pcbinfo;
struct sockaddr_in *sin;
int error;
- pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp_connect: inp == NULL"));
@@ -1669,9 +1667,7 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
return (error);
}
NET_EPOCH_ENTER(et);
- INP_HASH_WLOCK(pcbinfo);
error = in_pcbconnect(inp, sin, td->td_ucred);
- INP_HASH_WUNLOCK(pcbinfo);
NET_EPOCH_EXIT(et);
if (error == 0)
soisconnected(so);