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);