Make in_pcbladdr() require network epoch entered by its callers. Together
with this widen network epoch coverage up to tcp_connect() and udp_connect(). Revisions from r356974 and up to this revision cover D23187. Differential Revision: https://reviews.freebsd.org/D23187
This commit is contained in:
parent
e2636f0a78
commit
c1604fe4d2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356983
@ -1028,9 +1028,9 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
struct sockaddr *sa;
|
||||
struct sockaddr_in *sin;
|
||||
struct route sro;
|
||||
struct epoch_tracker et;
|
||||
int error;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
KASSERT(laddr != NULL, ("%s: laddr NULL", __func__));
|
||||
/*
|
||||
* Bypass source address selection and use the primary jail IP
|
||||
@ -1064,7 +1064,6 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
* network and try to find a corresponding interface to take
|
||||
* the source address from.
|
||||
*/
|
||||
NET_EPOCH_ENTER(et);
|
||||
if (sro.ro_rt == NULL || sro.ro_rt->rt_ifp == NULL) {
|
||||
struct in_ifaddr *ia;
|
||||
struct ifnet *ifp;
|
||||
@ -1228,7 +1227,6 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr,
|
||||
}
|
||||
|
||||
done:
|
||||
NET_EPOCH_EXIT(et);
|
||||
if (sro.ro_rt != NULL)
|
||||
RTFREE(sro.ro_rt);
|
||||
return (error);
|
||||
@ -1266,6 +1264,7 @@ in_pcbconnect_setup(struct inpcb *inp, struct sockaddr *nam,
|
||||
* Because a global state change doesn't actually occur here, a read
|
||||
* lock is sufficient.
|
||||
*/
|
||||
NET_EPOCH_ASSERT();
|
||||
INP_LOCK_ASSERT(inp);
|
||||
INP_HASH_LOCK_ASSERT(inp->inp_pcbinfo);
|
||||
|
||||
|
@ -491,8 +491,10 @@ rip_output(struct mbuf *m, struct socket *so, ...)
|
||||
* want to see from jails.
|
||||
*/
|
||||
if (ip->ip_src.s_addr == INADDR_ANY) {
|
||||
error = in_pcbladdr(inp, &ip->ip_dst, &ip->ip_src,
|
||||
inp->inp_cred);
|
||||
NET_EPOCH_ENTER(et);
|
||||
error = in_pcbladdr(inp, &ip->ip_dst,
|
||||
&ip->ip_src, inp->inp_cred);
|
||||
NET_EPOCH_EXIT(et);
|
||||
} else {
|
||||
error = prison_local_ip4(inp->inp_cred,
|
||||
&ip->ip_src);
|
||||
|
@ -557,17 +557,18 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
}
|
||||
tp = intotcpcb(inp);
|
||||
TCPDEBUG1();
|
||||
NET_EPOCH_ENTER(et);
|
||||
if ((error = tcp_connect(tp, nam, td)) != 0)
|
||||
goto out;
|
||||
goto out_in_epoch;
|
||||
#ifdef TCP_OFFLOAD
|
||||
if (registered_toedevs > 0 &&
|
||||
(so->so_options & SO_NO_OFFLOAD) == 0 &&
|
||||
(error = tcp_offload_connect(so, nam)) == 0)
|
||||
goto out;
|
||||
goto out_in_epoch;
|
||||
#endif
|
||||
tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
|
||||
NET_EPOCH_ENTER(et);
|
||||
error = tp->t_fb->tfb_tcp_output(tp);
|
||||
out_in_epoch:
|
||||
NET_EPOCH_EXIT(et);
|
||||
out:
|
||||
TCPDEBUG2(PRU_CONNECT);
|
||||
@ -644,18 +645,17 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
goto out;
|
||||
inp->inp_vflag |= INP_IPV4;
|
||||
inp->inp_vflag &= ~INP_IPV6;
|
||||
NET_EPOCH_ENTER(et);
|
||||
if ((error = tcp_connect(tp, (struct sockaddr *)&sin, td)) != 0)
|
||||
goto out;
|
||||
goto out_in_epoch;
|
||||
#ifdef TCP_OFFLOAD
|
||||
if (registered_toedevs > 0 &&
|
||||
(so->so_options & SO_NO_OFFLOAD) == 0 &&
|
||||
(error = tcp_offload_connect(so, nam)) == 0)
|
||||
goto out;
|
||||
goto out_in_epoch;
|
||||
#endif
|
||||
NET_EPOCH_ENTER(et);
|
||||
error = tp->t_fb->tfb_tcp_output(tp);
|
||||
NET_EPOCH_EXIT(et);
|
||||
goto out;
|
||||
goto out_in_epoch;
|
||||
} else {
|
||||
if ((inp->inp_vflag & INP_IPV6) == 0) {
|
||||
error = EAFNOSUPPORT;
|
||||
@ -679,6 +679,7 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
|
||||
NET_EPOCH_ENTER(et);
|
||||
error = tp->t_fb->tfb_tcp_output(tp);
|
||||
out_in_epoch:
|
||||
NET_EPOCH_EXIT(et);
|
||||
out:
|
||||
/*
|
||||
@ -1468,6 +1469,7 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td)
|
||||
u_short lport;
|
||||
int error;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
INP_WLOCK_ASSERT(inp);
|
||||
INP_HASH_WLOCK(&V_tcbinfo);
|
||||
|
||||
|
@ -1606,6 +1606,7 @@ udp_close(struct socket *so)
|
||||
static int
|
||||
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;
|
||||
@ -1625,9 +1626,11 @@ udp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
INP_WUNLOCK(inp);
|
||||
return (error);
|
||||
}
|
||||
NET_EPOCH_ENTER(et);
|
||||
INP_HASH_WLOCK(pcbinfo);
|
||||
error = in_pcbconnect(inp, nam, td->td_ucred);
|
||||
INP_HASH_WUNLOCK(pcbinfo);
|
||||
NET_EPOCH_EXIT(et);
|
||||
if (error == 0)
|
||||
soisconnected(so);
|
||||
INP_WUNLOCK(inp);
|
||||
|
Loading…
Reference in New Issue
Block a user