Index: sys/netinet/in_pcb.c =================================================================== --- sys/netinet/in_pcb.c +++ sys/netinet/in_pcb.c @@ -512,14 +512,6 @@ struct inpcb *inp; int error; -#ifdef INVARIANTS - if (pcbinfo == &V_tcbinfo) { - NET_EPOCH_ASSERT(); - } else { - INP_INFO_WLOCK_ASSERT(pcbinfo); - } -#endif - error = 0; inp = uma_zalloc(pcbinfo->ipi_zone, M_NOWAIT); if (inp == NULL) @@ -1036,9 +1028,9 @@ 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 @@ -1072,7 +1064,6 @@ * 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; @@ -1236,7 +1227,6 @@ } done: - NET_EPOCH_EXIT(et); if (sro.ro_rt != NULL) RTFREE(sro.ro_rt); return (error); @@ -1274,6 +1264,7 @@ * 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); @@ -1647,13 +1638,6 @@ return; } -#ifdef INVARIANTS - if (pcbinfo == &V_tcbinfo) { - INP_INFO_LOCK_ASSERT(pcbinfo); - } else { - INP_INFO_WLOCK_ASSERT(pcbinfo); - } -#endif INP_WLOCK_ASSERT(inp); INP_LIST_WLOCK(pcbinfo); in_pcbremlists(inp); @@ -2649,14 +2633,6 @@ { struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; -#ifdef INVARIANTS - if (pcbinfo == &V_tcbinfo) { - NET_EPOCH_ASSERT(); - } else { - INP_INFO_WLOCK_ASSERT(pcbinfo); - } -#endif - INP_WLOCK_ASSERT(inp); INP_LIST_WLOCK_ASSERT(pcbinfo); Index: sys/netinet/ip_carp.c =================================================================== --- sys/netinet/ip_carp.c +++ sys/netinet/ip_carp.c @@ -904,6 +904,7 @@ { 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 @@ 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 @@ 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 */ Index: sys/netinet/ip_divert.c =================================================================== --- sys/netinet/ip_divert.c +++ sys/netinet/ip_divert.c @@ -307,6 +307,7 @@ 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 @@ } INP_RUNLOCK(inp); + NET_EPOCH_ENTER(et); switch (ip->ip_v) { case IPVERSION: error = ip_output(m, options, NULL, @@ -452,6 +454,7 @@ break; #endif } + NET_EPOCH_EXIT(et); if (options != NULL) m_freem(options); } else { Index: sys/netinet/ip_output.c =================================================================== --- sys/netinet/ip_output.c +++ sys/netinet/ip_output.c @@ -304,7 +304,6 @@ 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 @@ #endif M_ASSERTPKTHDR(m); + NET_EPOCH_ASSERT(); if (inp != NULL) { INP_LOCK_ASSERT(inp); @@ -375,7 +375,6 @@ dst->sin_addr = ip->ip_dst; } gw = dst; - NET_EPOCH_ENTER(et); again: /* * Validate route against routing table additions; @@ -837,7 +836,6 @@ IPSTAT_INC(ips_fragmented); done: - NET_EPOCH_EXIT(et); return (error); bad: m_freem(m); Index: sys/netinet/raw_ip.c =================================================================== --- sys/netinet/raw_ip.c +++ sys/netinet/raw_ip.c @@ -445,6 +445,7 @@ int rip_output(struct mbuf *m, struct socket *so, ...) { + struct epoch_tracker et; struct ip *ip; int error; struct inpcb *inp = sotoinpcb(so); @@ -490,8 +491,10 @@ * 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); @@ -584,8 +587,10 @@ 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); } Index: sys/netinet/tcp_output.c =================================================================== --- sys/netinet/tcp_output.c +++ sys/netinet/tcp_output.c @@ -232,6 +232,7 @@ const bool hw_tls = false; #endif + NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(tp->t_inpcb); #ifdef TCP_OFFLOAD Index: sys/netinet/tcp_stacks/bbr.c =================================================================== --- sys/netinet/tcp_stacks/bbr.c +++ sys/netinet/tcp_stacks/bbr.c @@ -14462,6 +14462,8 @@ struct timeval tv; struct tcp_bbr *bbr; + NET_EPOCH_ASSERT(); + bbr = (struct tcp_bbr *)tp->t_fb_ptr; INP_WLOCK_ASSERT(tp->t_inpcb); (void)tcp_get_usecs(&tv); Index: sys/netinet/tcp_stacks/rack.c =================================================================== --- sys/netinet/tcp_stacks/rack.c +++ sys/netinet/tcp_stacks/rack.c @@ -8154,8 +8154,10 @@ #ifdef KERN_TLS hw_tls = (so->so_snd.sb_flags & SB_TLS_IFNET) != 0; #endif - + + NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); + #ifdef TCP_OFFLOAD if (tp->t_flags & TF_TOE) return (tcp_offload_output(tp)); Index: sys/netinet/tcp_syncache.c =================================================================== --- sys/netinet/tcp_syncache.c +++ sys/netinet/tcp_syncache.c @@ -467,6 +467,7 @@ { 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 @@ 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); } Index: sys/netinet/tcp_timer.c =================================================================== --- sys/netinet/tcp_timer.c +++ sys/netinet/tcp_timer.c @@ -251,6 +251,7 @@ void tcp_timer_delack(void *xtp) { + struct epoch_tracker et; struct tcpcb *tp = xtp; struct inpcb *inp; CURVNET_SET(tp->t_vnet); @@ -272,8 +273,10 @@ } tp->t_flags |= TF_ACKNOW; TCPSTAT_INC(tcps_delack); + NET_EPOCH_ENTER(et); (void) tp->t_fb->tfb_tcp_output(tp); INP_WUNLOCK(inp); + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); } @@ -452,9 +455,11 @@ 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), @@ -568,7 +573,9 @@ } tcp_setpersist(tp); tp->t_flags |= TF_FORCEDATA; + NET_EPOCH_ENTER(et); (void) tp->t_fb->tfb_tcp_output(tp); + NET_EPOCH_EXIT(et); tp->t_flags &= ~TF_FORCEDATA; #ifdef TCPDEBUG @@ -822,9 +829,9 @@ tp->t_rtttime = 0; cc_cong_signal(tp, NULL, CC_RTO); - + NET_EPOCH_ENTER(et); (void) tp->t_fb->tfb_tcp_output(tp); - + NET_EPOCH_EXIT(et); #ifdef TCPDEBUG if (tp != NULL && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, Index: sys/netinet/tcp_usrreq.c =================================================================== --- sys/netinet/tcp_usrreq.c +++ sys/netinet/tcp_usrreq.c @@ -121,7 +121,6 @@ /* * TCP protocol interface to socket abstraction. */ -static int tcp_attach(struct socket *); #ifdef INET static int tcp_connect(struct tcpcb *, struct sockaddr *, struct thread *td); @@ -161,40 +160,63 @@ KASSERT(inp == NULL, ("tcp_usr_attach: inp != NULL")); TCPDEBUG1(); - error = tcp_attach(so); + if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { + error = soreserve(so, V_tcp_sendspace, V_tcp_recvspace); + if (error) + goto out; + } + + so->so_rcv.sb_flags |= SB_AUTOSIZE; + so->so_snd.sb_flags |= SB_AUTOSIZE; + error = in_pcballoc(so, &V_tcbinfo); if (error) goto out; - + inp = sotoinpcb(so); +#ifdef INET6 + if (inp->inp_vflag & INP_IPV6PROTO) { + inp->inp_vflag |= INP_IPV6; + if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) + inp->inp_vflag |= INP_IPV4; + inp->in6p_hops = -1; /* use kernel default */ + } + else +#endif + inp->inp_vflag |= INP_IPV4; + tp = tcp_newtcpcb(inp); + if (tp == NULL) { + error = ENOBUFS; + in_pcbdetach(inp); + in_pcbfree(inp); + goto out; + } + tp->t_state = TCPS_CLOSED; + INP_WUNLOCK(inp); + TCPSTATES_INC(TCPS_CLOSED); if ((so->so_options & SO_LINGER) && so->so_linger == 0) so->so_linger = TCP_LINGERTIME; - - inp = sotoinpcb(so); - tp = intotcpcb(inp); out: TCPDEBUG2(PRU_ATTACH); TCP_PROBE2(debug__user, tp, PRU_ATTACH); - return error; + return (error); } /* - * tcp_detach is called when the socket layer loses its final reference + * tcp_usr_detach is called when the socket layer loses its final reference * to the socket, be it a file descriptor reference, a reference from TCP, * etc. At this point, there is only one case in which we will keep around * inpcb state: time wait. - * - * This function can probably be re-absorbed back into tcp_usr_detach() now - * that there is a single detach path. */ static void -tcp_detach(struct socket *so, struct inpcb *inp) +tcp_usr_detach(struct socket *so) { + struct inpcb *inp; struct tcpcb *tp; - INP_INFO_LOCK_ASSERT(&V_tcbinfo); - INP_WLOCK_ASSERT(inp); - - KASSERT(so->so_pcb == inp, ("tcp_detach: so_pcb != inp")); - KASSERT(inp->inp_socket == so, ("tcp_detach: inp_socket != so")); + inp = sotoinpcb(so); + KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); + INP_WLOCK(inp); + KASSERT(so->so_pcb == inp && inp->inp_socket == so, + ("%s: socket %p inp %p mismatch", __func__, so, inp)); tp = intotcpcb(inp); @@ -214,16 +236,16 @@ * Astute question indeed, from twtcp perspective there are * four cases to consider: * - * #1 tcp_detach is called at tcptw creation time by + * #1 tcp_usr_detach is called at tcptw creation time by * tcp_twstart, then do not discard the newly created tcptw * and leave inpcb present until timewait ends - * #2 tcp_detach is called at tcptw creation time by + * #2 tcp_usr_detach is called at tcptw creation time by * tcp_twstart, but connection is local and tw will be * discarded immediately - * #3 tcp_detach is called at timewait end (or reuse) by + * #3 tcp_usr_detach is called at timewait end (or reuse) by * tcp_twclose, then the tcptw has already been discarded * (or reused) and inpcb is freed here - * #4 tcp_detach is called() after timewait ends (or reuse) + * #4 tcp_usr_detach is called() after timewait ends (or reuse) * (e.g. by soclose), then tcptw has already been discarded * (or reused) and inpcb is freed here * @@ -276,34 +298,6 @@ } } -/* - * pru_detach() detaches the TCP protocol from the socket. - * If the protocol state is non-embryonic, then can't - * do this directly: have to initiate a pru_disconnect(), - * which may finish later; embryonic TCB's can just - * be discarded here. - */ -static void -tcp_usr_detach(struct socket *so) -{ - struct inpcb *inp; - int rlock = 0; - struct epoch_tracker et; - - inp = sotoinpcb(so); - KASSERT(inp != NULL, ("tcp_usr_detach: inp == NULL")); - if (!INP_INFO_WLOCKED(&V_tcbinfo)) { - NET_EPOCH_ENTER(et); - rlock = 1; - } - INP_WLOCK(inp); - KASSERT(inp->inp_socket != NULL, - ("tcp_usr_detach: inp_socket == NULL")); - tcp_detach(so, inp); - if (rlock) - NET_EPOCH_EXIT(et); -} - #ifdef INET /* * Give the socket an address. @@ -531,6 +525,7 @@ static int tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) { + struct epoch_tracker et; int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; @@ -562,16 +557,19 @@ } 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)); error = tp->t_fb->tfb_tcp_output(tp); +out_in_epoch: + NET_EPOCH_EXIT(et); out: TCPDEBUG2(PRU_CONNECT); TCP_PROBE2(debug__user, tp, PRU_CONNECT); @@ -584,6 +582,7 @@ static int tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td) { + struct epoch_tracker et; int error = 0; struct inpcb *inp; struct tcpcb *tp = NULL; @@ -646,16 +645,17 @@ 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 error = tp->t_fb->tfb_tcp_output(tp); - goto out; + goto out_in_epoch; } else { if ((inp->inp_vflag & INP_IPV6) == 0) { error = EAFNOSUPPORT; @@ -677,8 +677,10 @@ goto out; #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: /* * If the implicit bind in the connect call fails, restore @@ -882,6 +884,7 @@ static int tcp_usr_rcvd(struct socket *so, int flags) { + struct epoch_tracker et; struct inpcb *inp; struct tcpcb *tp = NULL; int error = 0; @@ -911,8 +914,9 @@ tcp_offload_rcvd(tp); else #endif + NET_EPOCH_ENTER(et); tp->t_fb->tfb_tcp_output(tp); - + NET_EPOCH_EXIT(et); out: TCPDEBUG2(PRU_RCVD); TCP_PROBE2(debug__user, tp, PRU_RCVD); @@ -953,8 +957,7 @@ * We require the pcbinfo "read lock" if we will close the socket * as part of this call. */ - if (flags & PRUS_EOF) - NET_EPOCH_ENTER(et); + NET_EPOCH_ENTER(et); inp = sotoinpcb(so); KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL")); INP_WLOCK(inp); @@ -1145,7 +1148,6 @@ * Close the send side of the connection after * the data is sent. */ - NET_EPOCH_ASSERT(); socantsendmore(so); tcp_usrclosed(tp); } @@ -1240,14 +1242,14 @@ TCP_PROBE2(debug__user, tp, (flags & PRUS_OOB) ? PRU_SENDOOB : ((flags & PRUS_EOF) ? PRU_SEND_EOF : PRU_SEND)); INP_WUNLOCK(inp); - if (flags & PRUS_EOF) - NET_EPOCH_EXIT(et); + NET_EPOCH_EXIT(et); return (error); } static int tcp_usr_ready(struct socket *so, struct mbuf *m, int count) { + struct epoch_tracker et; struct inpcb *inp; struct tcpcb *tp; int error; @@ -1264,8 +1266,11 @@ SOCKBUF_LOCK(&so->so_snd); error = sbready(&so->so_snd, m, count); SOCKBUF_UNLOCK(&so->so_snd); - if (error == 0) + if (error == 0) { + NET_EPOCH_ENTER(et); error = tp->t_fb->tfb_tcp_output(tp); + NET_EPOCH_EXIT(et); + } INP_WUNLOCK(inp); return (error); @@ -1464,6 +1469,7 @@ u_short lport; int error; + NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); INP_HASH_WLOCK(&V_tcbinfo); @@ -1921,8 +1927,13 @@ tp->t_flags |= TF_NOPUSH; else if (tp->t_flags & TF_NOPUSH) { tp->t_flags &= ~TF_NOPUSH; - if (TCPS_HAVEESTABLISHED(tp->t_state)) + if (TCPS_HAVEESTABLISHED(tp->t_state)) { + struct epoch_tracker et; + + NET_EPOCH_ENTER(et); error = tp->t_fb->tfb_tcp_output(tp); + NET_EPOCH_EXIT(et); + } } goto unlock_and_done; @@ -2388,57 +2399,6 @@ #undef INP_WLOCK_RECHECK #undef INP_WLOCK_RECHECK_CLEANUP -/* - * Attach TCP protocol to socket, allocating - * internet protocol control block, tcp control block, - * bufer space, and entering LISTEN state if to accept connections. - */ -static int -tcp_attach(struct socket *so) -{ - struct tcpcb *tp; - struct inpcb *inp; - struct epoch_tracker et; - int error; - - if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { - error = soreserve(so, V_tcp_sendspace, V_tcp_recvspace); - if (error) - return (error); - } - so->so_rcv.sb_flags |= SB_AUTOSIZE; - so->so_snd.sb_flags |= SB_AUTOSIZE; - NET_EPOCH_ENTER(et); - error = in_pcballoc(so, &V_tcbinfo); - if (error) { - NET_EPOCH_EXIT(et); - return (error); - } - inp = sotoinpcb(so); -#ifdef INET6 - if (inp->inp_vflag & INP_IPV6PROTO) { - inp->inp_vflag |= INP_IPV6; - if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) - inp->inp_vflag |= INP_IPV4; - inp->in6p_hops = -1; /* use kernel default */ - } - else -#endif - inp->inp_vflag |= INP_IPV4; - tp = tcp_newtcpcb(inp); - if (tp == NULL) { - in_pcbdetach(inp); - in_pcbfree(inp); - NET_EPOCH_EXIT(et); - return (ENOBUFS); - } - tp->t_state = TCPS_CLOSED; - INP_WUNLOCK(inp); - NET_EPOCH_EXIT(et); - TCPSTATES_INC(TCPS_CLOSED); - return (0); -} - /* * Initiate (or continue) disconnect. * If embryonic state, just send reset (once). Index: sys/netinet/toecore.c =================================================================== --- sys/netinet/toecore.c +++ sys/netinet/toecore.c @@ -503,6 +503,7 @@ toe_connect_failed(struct toedev *tod, struct inpcb *inp, int err) { + NET_EPOCH_ASSERT(); INP_WLOCK_ASSERT(inp); if (!(inp->inp_flags & INP_DROPPED)) { @@ -527,7 +528,6 @@ (void) tp->t_fb->tfb_tcp_output(tp); } else { - NET_EPOCH_ASSERT(); tp = tcp_drop(tp, err); if (tp == NULL) INP_WLOCK(inp); /* re-acquire */ Index: sys/netinet/udp_usrreq.c =================================================================== --- sys/netinet/udp_usrreq.c +++ sys/netinet/udp_usrreq.c @@ -1606,6 +1606,7 @@ 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 @@ 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); Index: sys/netinet6/ip6_mroute.c =================================================================== --- sys/netinet6/ip6_mroute.c +++ sys/netinet6/ip6_mroute.c @@ -1559,13 +1559,16 @@ */ 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); Index: sys/netinet6/ip6_output.c =================================================================== --- sys/netinet6/ip6_output.c +++ sys/netinet6/ip6_output.c @@ -384,7 +384,6 @@ 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 @@ 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 @@ IP6STAT_INC(ip6s_fragmented); done: - NET_EPOCH_EXIT(et); if (ro == &ip6route) RO_RTFREE(ro); return (error); Index: sys/netinet6/raw_ip6.c =================================================================== --- sys/netinet6/raw_ip6.c +++ sys/netinet6/raw_ip6.c @@ -389,6 +389,7 @@ 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 @@ } } + 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);