On 28/05/17(Sun) 01:39, Alexander Bluhm wrote:
> Hi Martin,
> 
> /usr/src/regress/sys/netinet/carp triggers splassert:
> 
> splassert: in_delmulti: want 1 have 0
> Starting stack trace...
> in_delmulti(ffff8000003bc2c0,0,0,0,33ac6118316b76b7,ffffffff8135a994) at 
> in_delmulti+0x54
> carp_multicast_cleanup(ffff8000003bd000,0,ffffffff8194c4a0,ffff8000003bd000,ffff8000003bd000,24)
>  at carp_multicast_cleanup+0x44
> carpdetach(ffff8000003bd000,ffffffff817a81c8,ffffff0003969c58,ffff800003ab9d60,ffffffff8194c4a0,ffff8000003bd000)
>  at carpdetach+0x76
> carp_clone_destroy(ffff8000003bd000,0,ffff8000003bd000,5,5,ffff800003ab9d60) 
> at carp_clone_destroy+0x22
> if_clone_destroy(ffff800003ab9d60,0,0,8020697a,80206979,ffff800003ab9d60) at 
> if_clone_destroy+0xb6
> ifioctl(ffffff0003969c58,80206979,ffff800003ab9d60,ffff800003a31888,ffff800003a31888,ffff800003ab9d60)
>  at ifioctl+0x212
> soo_ioctl(ffffff00038f6030,80206979,ffff800003ab9d60,ffff800003a31888,ffff800003a31888,ffff800003ab9e60)
>  at soo_ioctl+0x208
> sys_ioctl(ffff800003a31888,ffff800003ab9e60,ffff800003ab9eb0,0,ffffffff81945ca0,36)
>  at sys_ioctl+0x1c1
> syscall() at syscall+0x19d
> --- syscall (number 54) ---

Diff below fixes the problem in two parts.

- if_deactivate() needs the NET_LOCK() for carp_ifdetach().  splnet() is
  not need here since if_deactivate() deals with pseudo-interface hooks.
 
- carp_clone_destroy() needs to grab the NET_LOCK().

In both cases we want to protect the list of joined IP multicast groups.
This list is accessed in the packet processing path.

ok?

Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.497
diff -u -p -r1.497 if.c
--- net/if.c    16 May 2017 12:24:01 -0000      1.497
+++ net/if.c    28 May 2017 09:02:21 -0000
@@ -977,8 +977,7 @@ if_deactivate(struct ifnet *ifp)
 {
        int s;
 
-       s = splnet();
-
+       NET_LOCK(s);
        /*
         * Call detach hooks from head to tail.  To make sure detach
         * hooks are executed in the reverse order they were added, all
@@ -991,8 +990,7 @@ if_deactivate(struct ifnet *ifp)
        if (ifp->if_carp && ifp->if_type != IFT_CARP)
                carp_ifdetach(ifp);
 #endif
-
-       splx(s);
+       NET_UNLOCK(s);
 }
 
 /*
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.310
diff -u -p -r1.310 ip_carp.c
--- netinet/ip_carp.c   27 May 2017 21:55:52 -0000      1.310
+++ netinet/ip_carp.c   28 May 2017 09:05:47 -0000
@@ -870,8 +870,12 @@ int
 carp_clone_destroy(struct ifnet *ifp)
 {
        struct carp_softc *sc = ifp->if_softc;
+       int s;
 
+       NET_LOCK(s);
        carpdetach(sc);
+       NET_UNLOCK(s);
+
        ether_ifdetach(ifp);
        if_detach(ifp);
        carp_destroy_vhosts(ifp->if_softc);

Reply via email to