Drivers that need a splnet() protection inside their SIOCSIFADDR
generally raise the spl level themselves, so we should not need
to do that in in{6,}_ifinit(). One exception to this rule is,
as always, carp(4)...
So the diff below moves the spl dance inside carp's SIOCSIFADDR
handler, it's a baby step, so we can take care of carp_set_addr{6,}
later.
ok?
Index: netinet/in.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.c,v
retrieving revision 1.103
diff -u -p -r1.103 in.c
--- netinet/in.c 3 Sep 2014 08:59:06 -0000 1.103
+++ netinet/in.c 3 Sep 2014 13:08:43 -0000
@@ -612,7 +612,7 @@ in_ifinit(struct ifnet *ifp, struct in_i
{
u_int32_t i = sin->sin_addr.s_addr;
struct sockaddr_in oldaddr;
- int s, error = 0;
+ int error = 0;
splsoftassert(IPL_SOFTNET);
@@ -627,7 +627,6 @@ in_ifinit(struct ifnet *ifp, struct in_i
rt_ifa_delloop(&ia->ia_ifa);
ifa_del(ifp, &ia->ia_ifa);
}
- s = splnet();
oldaddr = ia->ia_addr;
ia->ia_addr = *sin;
@@ -639,10 +638,8 @@ in_ifinit(struct ifnet *ifp, struct in_i
if (ifp->if_ioctl &&
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
ia->ia_addr = oldaddr;
- splx(s);
goto out;
}
- splx(s);
if (ia->ia_netmask == 0) {
if (IN_CLASSA(i))
Index: netinet/ip_carp.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.233
diff -u -p -r1.233 ip_carp.c
--- netinet/ip_carp.c 22 Jul 2014 11:06:10 -0000 1.233
+++ netinet/ip_carp.c 3 Sep 2014 13:08:43 -0000
@@ -2060,10 +2060,11 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
struct ifaddr *ifa = (struct ifaddr *)addr;
struct ifreq *ifr = (struct ifreq *)addr;
struct ifnet *cdev = NULL;
- int i, error = 0;
+ int s, i, error = 0;
switch (cmd) {
case SIOCSIFADDR:
+ s = splnet();
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
@@ -2088,6 +2089,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd
break;
}
break;
+ splx(s);
case SIOCSIFFLAGS:
vhe = LIST_FIRST(&sc->carp_vhosts);
Index: netinet6/in6.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/in6.c,v
retrieving revision 1.140
diff -u -p -r1.140 in6.c
--- netinet6/in6.c 26 Aug 2014 21:44:29 -0000 1.140
+++ netinet6/in6.c 3 Sep 2014 13:08:43 -0000
@@ -1078,7 +1078,7 @@ in6_purgeaddr(struct ifaddr *ifa)
void
in6_unlink_ifa(struct in6_ifaddr *ia6, struct ifnet *ifp)
{
- int s = splnet();
+ splsoftassert(IPL_SOFTNET);
ifa_del(ifp, &ia6->ia_ifa);
@@ -1107,8 +1107,6 @@ in6_unlink_ifa(struct in6_ifaddr *ia6, s
* Note that we should decrement the refcnt at least once for all *BSD.
*/
ifafree(&ia6->ia_ifa);
-
- splx(s);
}
/*
@@ -1355,9 +1353,10 @@ int
in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia6, int newhost)
{
int error = 0, plen, ifacount = 0;
- int s = splnet();
struct ifaddr *ifa;
+ splsoftassert(IPL_SOFTNET);
+
/*
* Give the interface a chance to initialize
* if this is its first address (or it is a CARP interface)
@@ -1374,10 +1373,8 @@ in6_ifinit(struct ifnet *ifp, struct in6
if ((ifacount <= 1 || ifp->if_type == IFT_CARP ||
(ifp->if_flags & IFF_POINTOPOINT)) && ifp->if_ioctl &&
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia6))) {
- splx(s);
return (error);
}
- splx(s);
ia6->ia_ifa.ifa_metric = ifp->if_metric;