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