Make ip6_output() and ip_output() require network epoch.

All callers that before may called into these functions
without network epoch now must enter it.
This commit is contained in:
Gleb Smirnoff 2020-01-22 05:51:22 +00:00
parent a7f12fce22
commit b955545386
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356974
12 changed files with 33 additions and 6 deletions

View File

@ -904,6 +904,7 @@ carp_send_ad_locked(struct carp_softc *sc)
{
struct carp_header ch;
struct timeval tv;
struct epoch_tracker et;
struct ifaddr *ifa;
struct carp_header *ch_ptr;
struct mbuf *m;
@ -972,8 +973,10 @@ carp_send_ad_locked(struct carp_softc *sc)
CARPSTATS_INC(carps_opackets);
NET_EPOCH_ENTER(et);
carp_send_ad_error(sc, ip_output(m, NULL, NULL, IP_RAWOUTPUT,
&sc->sc_carpdev->if_carp->cif_imo, NULL));
NET_EPOCH_EXIT(et);
}
#endif /* INET */
#ifdef INET6
@ -1031,8 +1034,10 @@ carp_send_ad_locked(struct carp_softc *sc)
CARPSTATS_INC(carps_opackets6);
NET_EPOCH_ENTER(et);
carp_send_ad_error(sc, ip6_output(m, NULL, NULL, 0,
&sc->sc_carpdev->if_carp->cif_im6o, NULL, NULL));
NET_EPOCH_EXIT(et);
}
#endif /* INET6 */

View File

@ -307,6 +307,7 @@ static int
div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
struct mbuf *control)
{
struct epoch_tracker et;
struct ip *const ip = mtod(m, struct ip *);
struct m_tag *mtag;
struct ipfw_rule_ref *dt;
@ -440,6 +441,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
}
INP_RUNLOCK(inp);
NET_EPOCH_ENTER(et);
switch (ip->ip_v) {
case IPVERSION:
error = ip_output(m, options, NULL,
@ -452,6 +454,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin,
break;
#endif
}
NET_EPOCH_EXIT(et);
if (options != NULL)
m_freem(options);
} else {

View File

@ -304,7 +304,6 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
struct ip_moptions *imo, struct inpcb *inp)
{
struct rm_priotracker in_ifa_tracker;
struct epoch_tracker et;
struct ip *ip;
struct ifnet *ifp = NULL; /* keep compiler happy */
struct mbuf *m0;
@ -323,6 +322,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
#endif
M_ASSERTPKTHDR(m);
NET_EPOCH_ASSERT();
if (inp != NULL) {
INP_LOCK_ASSERT(inp);
@ -375,7 +375,6 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
dst->sin_addr = ip->ip_dst;
}
gw = dst;
NET_EPOCH_ENTER(et);
again:
/*
* Validate route against routing table additions;
@ -837,7 +836,6 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
IPSTAT_INC(ips_fragmented);
done:
NET_EPOCH_EXIT(et);
return (error);
bad:
m_freem(m);

View File

@ -445,6 +445,7 @@ rip_input(struct mbuf **mp, int *offp, int proto)
int
rip_output(struct mbuf *m, struct socket *so, ...)
{
struct epoch_tracker et;
struct ip *ip;
int error;
struct inpcb *inp = sotoinpcb(so);
@ -584,8 +585,10 @@ rip_output(struct mbuf *m, struct socket *so, ...)
mac_inpcb_create_mbuf(inp, m);
#endif
NET_EPOCH_ENTER(et);
error = ip_output(m, inp->inp_options, NULL, flags,
inp->inp_moptions, inp);
NET_EPOCH_EXIT(et);
INP_RUNLOCK(inp);
return (error);
}

View File

@ -193,6 +193,7 @@ cc_after_idle(struct tcpcb *tp)
int
tcp_output(struct tcpcb *tp)
{
struct epoch_tracker et;
struct socket *so = tp->t_inpcb->inp_socket;
int32_t len;
uint32_t recwin, sendwin;
@ -1371,6 +1372,7 @@ tcp_output(struct tcpcb *tp)
* m->m_pkthdr.len should have been set before checksum calculation,
* because in6_cksum() need it.
*/
NET_EPOCH_ENTER(et);
#ifdef INET6
if (isipv6) {
/*
@ -1456,6 +1458,7 @@ tcp_output(struct tcpcb *tp)
mtu = tp->t_inpcb->inp_route.ro_rt->rt_mtu;
}
#endif /* INET */
NET_EPOCH_EXIT(et);
out:
/*

View File

@ -12091,6 +12091,7 @@ bbr_window_update_needed(struct tcpcb *tp, struct socket *so, uint32_t recwin, i
static int
bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv)
{
struct epoch_tracker et;
struct socket *so;
int32_t len;
uint32_t cts;
@ -13937,6 +13938,7 @@ bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv)
* m->m_pkthdr.len should have been set before cksum calcuration,
* because in6_cksum() need it.
*/
NET_EPOCH_ENTER(et);
#ifdef INET6
if (isipv6) {
/*
@ -14014,6 +14016,7 @@ bbr_output_wtime(struct tcpcb *tp, const struct timeval *tv)
mtu = inp->inp_route.ro_rt->rt_mtu;
}
#endif /* INET */
NET_EPOCH_EXIT(et);
out:
if (lgb) {

View File

@ -8091,6 +8091,7 @@ rack_get_pacing_delay(struct tcp_rack *rack, struct tcpcb *tp, uint32_t len)
static int
rack_output(struct tcpcb *tp)
{
struct epoch_tracker et;
struct socket *so;
uint32_t recwin, sendwin;
uint32_t sb_offset;
@ -9733,6 +9734,7 @@ rack_output(struct tcpcb *tp)
* m->m_pkthdr.len should have been set before cksum calcuration,
* because in6_cksum() need it.
*/
NET_EPOCH_ENTER(et);
#ifdef INET6
if (isipv6) {
/*
@ -9810,6 +9812,7 @@ rack_output(struct tcpcb *tp)
mtu = inp->inp_route.ro_rt->rt_mtu;
}
#endif /* INET */
NET_EPOCH_EXIT(et);
out:
if (lgb) {

View File

@ -467,6 +467,7 @@ syncache_timer(void *xsch)
{
struct syncache_head *sch = (struct syncache_head *)xsch;
struct syncache *sc, *nsc;
struct epoch_tracker et;
int tick = ticks;
char *s;
bool paused;
@ -526,7 +527,9 @@ syncache_timer(void *xsch)
free(s, M_TCPLOG);
}
NET_EPOCH_ENTER(et);
syncache_respond(sc, NULL, TH_SYN|TH_ACK);
NET_EPOCH_EXIT(et);
TCPSTAT_INC(tcps_sc_retransmitted);
syncache_timeout(sc, sch, 0);
}

View File

@ -452,9 +452,11 @@ tcp_timer_keep(void *xtp)
TCPSTAT_INC(tcps_keepprobe);
t_template = tcpip_maketemplate(inp);
if (t_template) {
NET_EPOCH_ENTER(et);
tcp_respond(tp, t_template->tt_ipgen,
&t_template->tt_t, (struct mbuf *)NULL,
tp->rcv_nxt, tp->snd_una - 1, 0);
NET_EPOCH_EXIT(et);
free(t_template, M_TEMP);
}
callout_reset(&tp->t_timers->tt_keep, TP_KEEPINTVL(tp),

View File

@ -1559,13 +1559,16 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m)
*/
if (m->m_pkthdr.rcvif == NULL) {
struct ip6_moptions im6o;
struct epoch_tracker et;
im6o.im6o_multicast_ifp = ifp;
/* XXX: ip6_output will override ip6->ip6_hlim */
im6o.im6o_multicast_hlim = ip6->ip6_hlim;
im6o.im6o_multicast_loop = 1;
NET_EPOCH_ENTER(et);
error = ip6_output(mb_copy, NULL, NULL, IPV6_FORWARDING, &im6o,
NULL, NULL);
NET_EPOCH_EXIT(et);
MRT6_DLOG(DEBUG_XMIT, "mif %u err %d",
(uint16_t)(mifp - mif6table), error);

View File

@ -384,7 +384,6 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
struct mbuf *m = m0;
struct mbuf *mprev = NULL;
int hlen, tlen, len;
struct epoch_tracker et;
struct route_in6 ip6route;
struct rtentry *rt = NULL;
struct sockaddr_in6 *dst, src_sa, dst_sa;
@ -405,7 +404,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
struct m_tag *fwd_tag = NULL;
uint32_t id;
NET_EPOCH_ENTER(et);
NET_EPOCH_ASSERT();
if (inp != NULL) {
INP_LOCK_ASSERT(inp);
@ -1189,7 +1188,6 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
IP6STAT_INC(ip6s_fragmented);
done:
NET_EPOCH_EXIT(et);
if (ro == &ip6route)
RO_RTFREE(ro);
return (error);

View File

@ -389,6 +389,7 @@ rip6_ctlinput(int cmd, struct sockaddr *sa, void *d)
int
rip6_output(struct mbuf *m, struct socket *so, ...)
{
struct epoch_tracker et;
struct mbuf *control;
struct m_tag *mtag;
struct sockaddr_in6 *dstsock;
@ -536,7 +537,9 @@ rip6_output(struct mbuf *m, struct socket *so, ...)
}
}
NET_EPOCH_ENTER(et);
error = ip6_output(m, optp, NULL, 0, inp->in6p_moptions, &oifp, inp);
NET_EPOCH_EXIT(et);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
icmp6_ifoutstat_inc(oifp, type, code);