Diff below gets rid of the various splsoftnet() in multicast forwarding code. I've put asserts to ease review.
While here remove #ifdef PIM leftovers. ok? Index: netinet/ip_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_mroute.c,v retrieving revision 1.101 diff -u -p -r1.101 ip_mroute.c --- netinet/ip_mroute.c 22 Dec 2016 11:04:44 -0000 1.101 +++ netinet/ip_mroute.c 3 Jan 2017 11:08:50 -0000 @@ -316,20 +316,16 @@ mrt_ioctl(struct socket *so, u_long cmd, int get_sg_cnt(unsigned int rtableid, struct sioc_sg_req *req) { - int s; struct mfc *rt; - s = splsoftnet(); rt = mfc_find(rtableid, &req->src, &req->grp); if (rt == NULL) { - splx(s); req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; return (EADDRNOTAVAIL); } req->pktcnt = rt->mfc_pkt_cnt; req->bytecnt = rt->mfc_byte_cnt; req->wrong_if = rt->mfc_wrong_if; - splx(s); return (0); } @@ -478,11 +474,7 @@ ip_mrouter_init(struct socket *so, struc arc4random_buf(&mfchashkey[rtableid], sizeof(mfchashkey[rtableid])); memset(nexpire[rtableid], 0, sizeof(nexpire[rtableid])); -#ifdef PIM - pim_assert = 0; -#endif - - timeout_set(&expire_upcalls_ch[rtableid], expire_upcalls, + timeout_set_proc(&expire_upcalls_ch[rtableid], expire_upcalls, &inp->inp_rtableid); timeout_add_msec(&expire_upcalls_ch[rtableid], EXPIRE_TIMEOUT); @@ -511,10 +503,9 @@ ip_mrouter_done(struct socket *so) vifi_t vifi; struct vif *vifp; int i; - int s; unsigned int rtableid = inp->inp_rtableid; - s = splsoftnet(); + splsoftassert(IPL_SOFTNET); /* Clear out all the vifs currently in use. */ for (vifi = 0; vifi < numvifs; vifi++) { @@ -526,10 +517,6 @@ ip_mrouter_done(struct socket *so) numvifs = 0; mrt_api_config = 0; -#ifdef PIM - pim_assert = 0; -#endif - timeout_del(&expire_upcalls_ch[rtableid]); /* @@ -551,8 +538,6 @@ ip_mrouter_done(struct socket *so) ip_mrouter[rtableid] = NULL; - splx(s); - return (0); } @@ -658,7 +643,9 @@ add_vif(struct socket *so, struct mbuf * struct ifaddr *ifa; struct ifnet *ifp; struct ifreq ifr; - int error, s; + int error; + + splsoftassert(IPL_SOFTNET); if (m == NULL || m->m_len < sizeof(struct vifctl)) return (EINVAL); @@ -702,8 +689,6 @@ add_vif(struct socket *so, struct mbuf * return (error); } - s = splsoftnet(); - vifp->v_flags = vifcp->vifc_flags; vifp->v_threshold = vifcp->vifc_threshold; vifp->v_lcl_addr = vifcp->vifc_lcl_addr; @@ -715,8 +700,6 @@ add_vif(struct socket *so, struct mbuf * vifp->v_bytes_in = 0; vifp->v_bytes_out = 0; - splx(s); - /* Adjust numvifs up if the vifi is higher than numvifs. */ if (numvifs <= vifcp->vifc_vifi) numvifs = vifcp->vifc_vifi + 1; @@ -750,7 +733,8 @@ del_vif(struct mbuf *m) vifi_t *vifip; struct vif *vifp; vifi_t vifi; - int s; + + splsoftassert(IPL_SOFTNET); if (m == NULL || m->m_len < sizeof(vifi_t)) return (EINVAL); @@ -763,8 +747,6 @@ del_vif(struct mbuf *m) if (in_nullhost(vifp->v_lcl_addr)) return (EADDRNOTAVAIL); - s = splsoftnet(); - reset_vif(vifp); /* Adjust numvifs down */ @@ -773,8 +755,6 @@ del_vif(struct mbuf *m) break; numvifs = vifi; - splx(s); - return (0); } @@ -881,10 +861,11 @@ add_mfc(struct socket *so, struct mbuf * u_int32_t hash = 0; struct rtdetq *rte, *nrte; u_short nstl; - int s; int mfcctl_size = sizeof(struct mfcctl); unsigned int rtableid = inp->inp_rtableid; + splsoftassert(IPL_SOFTNET); + if (mrt_api_config & MRT_API_FLAGS_ALL) mfcctl_size = sizeof(struct mfcctl2); @@ -905,19 +886,15 @@ add_mfc(struct socket *so, struct mbuf * } mfccp = &mfcctl2; - s = splsoftnet(); /* No hash table allocated for this. */ - if (mfchashtbl[rtableid] == NULL) { - splx(s); + if (mfchashtbl[rtableid] == NULL) return (0); - } rt = mfc_find(rtableid, &mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); /* If an entry already exists, just update the fields */ if (rt) { update_mfc_params(rt, mfccp); - splx(s); return (0); } @@ -977,10 +954,8 @@ add_mfc(struct socket *so, struct mbuf * } if (rt == NULL) { /* no upcall, so make a new entry */ rt = malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT); - if (rt == NULL) { - splx(s); + if (rt == NULL) return (ENOBUFS); - } init_mfc_params(rt, mfccp); rt->mfc_expire = 0; @@ -991,7 +966,6 @@ add_mfc(struct socket *so, struct mbuf * } } - splx(s); return (0); } @@ -1005,11 +979,12 @@ del_mfc(struct socket *so, struct mbuf * struct mfcctl2 mfcctl2; struct mfcctl2 *mfccp; struct mfc *rt; - int s; int mfcctl_size = sizeof(struct mfcctl); struct mfcctl *mp = mtod(m, struct mfcctl *); unsigned int rtableid = inp->inp_rtableid; + splsoftassert(IPL_SOFTNET); + /* * XXX: for deleting MFC entries the information in entries * of size "struct mfcctl" is sufficient. @@ -1024,18 +999,13 @@ del_mfc(struct socket *so, struct mbuf * mfccp = &mfcctl2; - s = splsoftnet(); - rt = mfc_find(rtableid, &mfccp->mfcc_origin, &mfccp->mfcc_mcastgrp); - if (rt == NULL) { - splx(s); + if (rt == NULL) return (EADDRNOTAVAIL); - } LIST_REMOVE(rt, mfc_hash); free(rt, M_MRTABLE, 0); - splx(s); return (0); } @@ -1105,13 +1075,11 @@ ip_mforward(struct mbuf *m, struct ifnet /* * Determine forwarding vifs from the forwarding cache table */ - s = splsoftnet(); ++mrtstat.mrts_mfc_lookups; rt = mfc_find(rtableid, &ip->ip_src, &ip->ip_dst); /* Entry exists, so forward if necessary */ if (rt != NULL) { - splx(s); return (ip_mdq(m, ifp, rt)); } else { /* @@ -1133,15 +1101,12 @@ ip_mforward(struct mbuf *m, struct ifnet * that other people can't step on it. */ rte = malloc(sizeof(*rte), M_MRTABLE, M_NOWAIT); - if (rte == NULL) { - splx(s); + if (rte == NULL) return (ENOBUFS); - } mb0 = m_copym(m, 0, M_COPYALL, M_NOWAIT); M_PULLUP(mb0, hlen); if (mb0 == NULL) { free(rte, M_MRTABLE, 0); - splx(s); return (ENOBUFS); } @@ -1245,7 +1210,6 @@ ip_mforward(struct mbuf *m, struct ifnet non_fatal: free(rte, M_MRTABLE, 0); m_freem(mb0); - splx(s); return (0); } @@ -1257,8 +1221,6 @@ ip_mforward(struct mbuf *m, struct ifnet rte->m = mb0; rte->ifp = ifp; - splx(s); - return (0); } } @@ -1268,12 +1230,11 @@ ip_mforward(struct mbuf *m, struct ifnet void expire_upcalls(void *v) { - int i; - int s; unsigned int rtableid = *(unsigned int *)v; + int i, s; - s = splsoftnet(); + NET_LOCK(s); for (i = 0; i < MFCTBLSIZ; i++) { struct mfc *rt, *nrt; @@ -1291,9 +1252,8 @@ expire_upcalls(void *v) expire_mfc(rt); } } - - splx(s); timeout_add_msec(&expire_upcalls_ch[rtableid], EXPIRE_TIMEOUT); + NET_UNLOCK(s); } /* @@ -1369,7 +1329,8 @@ void send_packet(struct vif *vifp, struct mbuf *m) { struct ip_moptions imo; - int s; + + splsoftassert(IPL_SOFTNET); /* * if physical interface option, extract the options @@ -1379,7 +1340,5 @@ send_packet(struct vif *vifp, struct mbu imo.imo_ttl = mtod(m, struct ip *)->ip_ttl - IPTTLDEC; imo.imo_loop = 1; - s = splsoftnet(); ip_output(m, NULL, NULL, IP_FORWARDING, &imo, NULL, 0); - splx(s); } Index: netinet6/ip6_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.106 diff -u -p -r1.106 ip6_mroute.c --- netinet6/ip6_mroute.c 22 Dec 2016 11:04:44 -0000 1.106 +++ netinet6/ip6_mroute.c 3 Jan 2017 11:09:08 -0000 @@ -282,11 +282,8 @@ int get_sg6_cnt(struct sioc_sg_req6 *req) { struct mf6c *rt; - int s; - s = splsoftnet(); MF6CFIND(req->src.sin6_addr, req->grp.sin6_addr, rt); - splx(s); if (rt != NULL) { req->pktcnt = rt->mf6c_pkt_cnt; req->bytecnt = rt->mf6c_byte_cnt; @@ -437,7 +434,7 @@ ip6_mrouter_init(struct socket *so, int arc4random_buf(&mf6chashkey, sizeof(mf6chashkey)); bzero((caddr_t)n6expire, sizeof(n6expire)); - timeout_set(&expire_upcalls6_ch, expire_upcalls6, NULL); + timeout_set_proc(&expire_upcalls6_ch, expire_upcalls6, NULL); timeout_add(&expire_upcalls6_ch, EXPIRE_TIMEOUT); return 0; @@ -455,9 +452,8 @@ ip6_mrouter_done(void) struct in6_ifreq ifr; struct mf6c *rt; struct rtdetq *rte; - int s; - s = splsoftnet(); + splsoftassert(IPL_SOFTNET); /* * For each phyint in use, disable promiscuous reception of all IPv6 @@ -515,8 +511,6 @@ ip6_mrouter_done(void) ip6_mrouter = NULL; ip6_mrouter_ver = 0; - splx(s); - return 0; } @@ -560,7 +554,9 @@ add_m6if(struct mif6ctl *mifcp) struct mif6 *mifp; struct ifnet *ifp; struct in6_ifreq ifr; - int error, s; + int error; + + splsoftassert(IPL_SOFTNET); if (mifcp->mif6c_mifi >= MAXMIFS) return EINVAL; @@ -579,8 +575,6 @@ add_m6if(struct mif6ctl *mifcp) return EOPNOTSUPP; } - s = splsoftnet(); - /* * Enable promiscuous reception of all IPv6 multicasts * from the interface. @@ -590,15 +584,12 @@ add_m6if(struct mif6ctl *mifcp) ifr.ifr_addr.sin6_addr = in6addr_any; error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr); - splx(s); if (error) { if_put(ifp); return error; } } - s = splsoftnet(); - mifp->m6_flags = mifcp->mif6c_flags; mifp->m6_ifp = ifp; #ifdef notyet @@ -610,7 +601,6 @@ add_m6if(struct mif6ctl *mifcp) mifp->m6_pkt_out = 0; mifp->m6_bytes_in = 0; mifp->m6_bytes_out = 0; - splx(s); /* Adjust nummifs up if the mifi is higher than nummifs */ if (nummifs <= mifcp->mif6c_mifi) @@ -631,7 +621,8 @@ del_m6if(mifi_t *mifip) mifi_t mifi; struct ifnet *ifp; struct in6_ifreq ifr; - int s; + + splsoftassert(IPL_SOFTNET); if (*mifip >= nummifs) return EINVAL; @@ -640,7 +631,6 @@ del_m6if(mifi_t *mifip) ifp = mifp->m6_ifp; - s = splsoftnet(); if (!(mifp->m6_flags & MIFF_REGISTER)) { /* * XXX: what if there is yet IPv4 multicast daemon @@ -667,8 +657,6 @@ del_m6if(mifi_t *mifip) break; nummifs = mifi; - splx(s); - return 0; } @@ -683,25 +671,22 @@ add_m6fc(struct mf6cctl *mfccp) struct rtdetq *rte; u_short nstl; char orig[INET6_ADDRSTRLEN], mcast[INET6_ADDRSTRLEN]; - int s; + + splsoftassert(IPL_SOFTNET); MF6CFIND(mfccp->mf6cc_origin.sin6_addr, mfccp->mf6cc_mcastgrp.sin6_addr, rt); /* If an entry already exists, just update the fields */ if (rt) { - s = splsoftnet(); rt->mf6c_parent = mfccp->mf6cc_parent; rt->mf6c_ifset = mfccp->mf6cc_ifset; - splx(s); return 0; } /* * Find the entry for which the upcall was made and update */ - s = splsoftnet(); - hash = MF6CHASH(mfccp->mf6cc_origin.sin6_addr, mfccp->mf6cc_mcastgrp.sin6_addr); for (rt = mf6ctable[hash], nstl = 0; rt; rt = rt->mf6c_next) { @@ -778,10 +763,8 @@ add_m6fc(struct mf6cctl *mfccp) if (rt == NULL) { /* no upcall, so make a new entry */ rt = malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT); - if (rt == NULL) { - splx(s); + if (rt == NULL) return ENOBUFS; - } /* insert new entry at head of hash chain */ rt->mf6c_origin = mfccp->mf6cc_origin; @@ -800,7 +783,6 @@ add_m6fc(struct mf6cctl *mfccp) mf6ctable[hash] = rt; } } - splx(s); return 0; } @@ -815,14 +797,13 @@ del_m6fc(struct mf6cctl *mfccp) struct mf6c *rt; struct mf6c **nptr; u_long hash; - int s; + + splsoftassert(IPL_SOFTNET); origin = mfccp->mf6cc_origin; mcastgrp = mfccp->mf6cc_mcastgrp; hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr); - s = splsoftnet(); - nptr = &mf6ctable[hash]; while ((rt = *nptr) != NULL) { if (IN6_ARE_ADDR_EQUAL(&origin.sin6_addr, @@ -834,16 +815,12 @@ del_m6fc(struct mf6cctl *mfccp) nptr = &rt->mf6c_next; } - if (rt == NULL) { - splx(s); + if (rt == NULL) return EADDRNOTAVAIL; - } *nptr = rt->mf6c_next; free(rt, M_MRTABLE, sizeof(*rt)); - splx(s); - return 0; } @@ -876,10 +853,11 @@ ip6_mforward(struct ip6_hdr *ip6, struct struct mf6c *rt; struct mif6 *mifp; struct mbuf *mm; - int s; mifi_t mifi; struct sockaddr_in6 sin6; + splsoftassert(IPL_SOFTNET); + /* * Don't forward a packet with Hop limit of zero or one, * or a packet destined to a local-only group. @@ -915,12 +893,10 @@ ip6_mforward(struct ip6_hdr *ip6, struct /* * Determine forwarding mifs from the forwarding cache table */ - s = splsoftnet(); MF6CFIND(ip6->ip6_src, ip6->ip6_dst, rt); /* Entry exists, so forward if necessary */ if (rt) { - splx(s); return (ip6_mdq(m, ifp, rt)); } else { /* @@ -940,10 +916,8 @@ ip6_mforward(struct ip6_hdr *ip6, struct * are just going to fail anyway. */ rte = malloc(sizeof(*rte), M_MRTABLE, M_NOWAIT); - if (rte == NULL) { - splx(s); + if (rte == NULL) return ENOBUFS; - } mb0 = m_copym(m, 0, M_COPYALL, M_NOWAIT); /* * Pullup packet header if needed before storing it, @@ -954,7 +928,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct mb0 = m_pullup(mb0, sizeof(struct ip6_hdr)); if (mb0 == NULL) { free(rte, M_MRTABLE, sizeof(*rte)); - splx(s); return ENOBUFS; } @@ -977,7 +950,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct if (rt == NULL) { free(rte, M_MRTABLE, sizeof(*rte)); m_freem(mb0); - splx(s); return ENOBUFS; } /* @@ -990,7 +962,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct free(rte, M_MRTABLE, sizeof(*rte)); m_freem(mb0); free(rt, M_MRTABLE, sizeof(*rt)); - splx(s); return ENOBUFS; } @@ -1013,7 +984,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct free(rte, M_MRTABLE, sizeof(*rte)); m_freem(mb0); free(rt, M_MRTABLE, sizeof(*rt)); - splx(s); return EINVAL; } @@ -1036,7 +1006,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct free(rte, M_MRTABLE, sizeof(*rte)); m_freem(mb0); free(rt, M_MRTABLE, sizeof(*rt)); - splx(s); return ENOBUFS; } @@ -1069,7 +1038,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct mrt6stat.mrt6s_upq_ovflw++; free(rte, M_MRTABLE, sizeof(*rte)); m_freem(mb0); - splx(s); return 0; } @@ -1080,7 +1048,6 @@ ip6_mforward(struct ip6_hdr *ip6, struct rte->next = NULL; rte->m = mb0; rte->ifp = ifp; - splx(s); return 0; } @@ -1095,11 +1062,9 @@ expire_upcalls6(void *unused) { struct rtdetq *rte; struct mf6c *mfc, **nptr; - int i; - int s; - - s = splsoftnet(); + int i, s; + NET_LOCK(s); for (i = 0; i < MF6CTBLSIZ; i++) { if (n6expire[i] == 0) continue; @@ -1134,9 +1099,8 @@ expire_upcalls6(void *unused) } } } - splx(s); - timeout_set(&expire_upcalls6_ch, expire_upcalls6, NULL); timeout_add(&expire_upcalls6_ch, EXPIRE_TIMEOUT); + NET_UNLOCK(s); } /* @@ -1214,9 +1178,9 @@ phyint_send6(struct ip6_hdr *ip6, struct struct mbuf *mb_copy; struct ifnet *ifp = mifp->m6_ifp; struct sockaddr_in6 *dst6, sin6; - int s, error = 0; + int error = 0; - s = splsoftnet(); + splsoftassert(IPL_SOFTNET); /* * Make a new reference to the packet; make sure that @@ -1227,10 +1191,8 @@ phyint_send6(struct ip6_hdr *ip6, struct if (mb_copy && (M_READONLY(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr))) mb_copy = m_pullup(mb_copy, sizeof(struct ip6_hdr)); - if (mb_copy == NULL) { - splx(s); + if (mb_copy == NULL) return; - } /* set MCAST flag to the outgoing packet */ mb_copy->m_flags |= M_MCAST; @@ -1250,7 +1212,6 @@ phyint_send6(struct ip6_hdr *ip6, struct im6o.im6o_loop = 1; error = ip6_output(mb_copy, NULL, NULL, IPV6_FORWARDING, &im6o, NULL); - splx(s); return; } @@ -1283,8 +1244,6 @@ phyint_send6(struct ip6_hdr *ip6, struct m_freem(mb_copy); /* simply discard the packet */ } } - - splx(s); } u_int32_t