diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -82,6 +82,7 @@ #include #include #include +#include #include @@ -451,6 +452,7 @@ void ip_input(struct mbuf *m) { + MROUTER_RLOCK_TRACKER; struct rm_priotracker in_ifa_tracker; struct ip *ip = NULL; struct in_ifaddr *ia = NULL; @@ -743,6 +745,7 @@ return; } if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { + MROUTER_RLOCK(); if (V_ip_mrouter) { /* * If we are acting as a multicast router, all @@ -753,6 +756,7 @@ * must be discarded, else it may be accepted below. */ if (ip_mforward && ip_mforward(ip, ifp, m, 0) != 0) { + MROUTER_RUNLOCK(); IPSTAT_INC(ips_cantforward); m_freem(m); return; @@ -763,10 +767,13 @@ * all multicast IGMP packets, whether or not this * host belongs to their destination groups. */ - if (ip->ip_p == IPPROTO_IGMP) + if (ip->ip_p == IPPROTO_IGMP) { + MROUTER_RUNLOCK(); goto ours; + } IPSTAT_INC(ips_forward); } + MROUTER_RUNLOCK(); /* * Assume the packet is for us, to avoid prematurely taking * a lock on the in_multi hash. Protocols must perform diff --git a/sys/netinet/ip_mroute.h b/sys/netinet/ip_mroute.h --- a/sys/netinet/ip_mroute.h +++ b/sys/netinet/ip_mroute.h @@ -355,6 +355,11 @@ extern int (*ip_mrouter_done)(void); extern int (*mrt_ioctl)(u_long, caddr_t, int); +#define MROUTER_RLOCK_TRACKER struct epoch_tracker mrouter_et +#define MROUTER_RLOCK() epoch_enter_preempt(net_epoch_preempt, &mrouter_et) +#define MROUTER_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &mrouter_et) +#define MROUTER_WAIT() epoch_wait_preempt(net_epoch_preempt) + #endif /* _KERNEL */ #endif /* _NETINET_IP_MROUTE_H_ */ diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -720,6 +720,8 @@ ip_mrouter_cnt--; V_mrt_api_config = 0; + MROUTER_WAIT(); + VIF_LOCK(); /* diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -83,6 +83,7 @@ #include #include #include +#include #include #include @@ -319,6 +320,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, struct ip_moptions *imo, struct inpcb *inp) { + MROUTER_RLOCK_TRACKER; struct rm_priotracker in_ifa_tracker; struct ip *ip; struct ifnet *ifp = NULL; /* keep compiler happy */ @@ -613,6 +615,7 @@ * above, will be forwarded by the ip_input() routine, * if necessary. */ + MROUTER_RLOCK(); if (V_ip_mrouter && (flags & IP_FORWARDING) == 0) { /* * If rsvp daemon is not running, do not @@ -624,10 +627,12 @@ imo = NULL; if (ip_mforward && ip_mforward(ip, ifp, m, imo) != 0) { + MROUTER_RUNLOCK(); m_freem(m); goto done; } } + MROUTER_RUNLOCK(); } /*