On 03/09/14(Wed) 15:25, Martin Pieuchot wrote:
> 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.

mikeb@ pointed out that a spl dance was missing from the SIOCDIFADDR_IN6
ioctl, updated diff below also fixes that.

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:52:41 -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:52:41 -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:52:41 -0000
@@ -172,7 +172,7 @@ in6_control(struct socket *so, u_long cm
        struct  in6_ifaddr *ia6 = NULL;
        struct  in6_aliasreq *ifra = (struct in6_aliasreq *)data;
        struct sockaddr_in6 *sa6;
-       int privileged;
+       int s, privileged;
 
        privileged = 0;
        if ((so->so_state & SS_PRIV) != 0)
@@ -463,7 +463,6 @@ in6_control(struct socket *so, u_long cm
        {
                int i, error = 0;
                struct nd_prefix pr0, *pr;
-               int s;
 
                /* reject read-only flags */
                if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 ||
@@ -561,8 +560,10 @@ in6_control(struct socket *so, u_long cm
        }
 
        case SIOCDIFADDR_IN6:
+               s = splsoftnet();
                in6_purgeaddr(&ia6->ia_ifa);
                dohooks(ifp->if_addrhooks, 0);
+               splx(s);
                break;
 
        default:
@@ -1078,7 +1079,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 +1108,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 +1354,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 +1374,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;
 

Reply via email to