Destroying a carp interface does not restore the demote count of the 
carp group.

Reason is that the interface is removed from the carp group by 
if_clone_destroy() before carp_clone_destroy() is run.  The second reason 
is a simple bug introduced in ip_carp.c, rev 1.175.

The diff removes if_delgroup() from if_clone_destroy().  This is possible 
because if_detach() that is run later on removes the interface from all 
the groups as well.  This seems to work fine.  I cannot deduce from the 
CVS history why it was added to if_clone_destroy...  can anyone 
remember?  (Henning?)

After the diff (fxp1 has no carrier on purpose):

camield@rifraf $ ifconfig fxp1
fxp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:d0:b7:47:3c:07
        priority: 0
        media: Ethernet autoselect (none)
        status: no carrier
        inet 10.38.38.10 netmask 0xffffff00 broadcast 10.38.38.255
        inet6 fe80::2d0:b7ff:fe47:3c07%fxp1 prefixlen 64 scopeid 0x3
camield@rifraf $ sudo ifconfig carp11 vhid 11 carpdev fxp1
camield@rifraf $ ifconfig carp11
carp11: flags=8803<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500
        lladdr 00:00:5e:00:01:0b
        priority: 0
        carp: INIT carpdev fxp1 vhid 11 advbase 1 advskew 0
        groups: carp
        inet6 fe80::200:5eff:fe00:10b%carp11 prefixlen 64 scopeid 0x6
camield@rifraf $ ifconfig -g carp
carp: carp demote count 1
camield@rifraf $ sudo ifconfig carp11 destroy
camield@rifraf $ ifconfig -g carp             
carp: carp demote count 0
camield@rifraf $ tail -2 /var/log/messages                                      
                                                                
Oct 21 13:48:25 rifraf /bsd: carp: carp11 demoted group carp by 1 to 1 
(carpdev)
Oct 21 13:48:33 rifraf /bsd: carp: carp11 demoted group carp by -1 to 0 
(detach)


Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.239
diff -u -p -r1.239 if.c
--- net/if.c    9 Jul 2011 00:47:18 -0000       1.239
+++ net/if.c    21 Oct 2011 08:23:04 -0000
@@ -712,7 +712,7 @@ if_clone_destroy(const char *name)
 {
        struct if_clone *ifc;
        struct ifnet *ifp;
-       int s, ret;
+       int s;
 
        ifc = if_clone_lookup(name, NULL);
        if (ifc == NULL)
@@ -731,12 +731,7 @@ if_clone_destroy(const char *name)
                splx(s);
        }
 
-       if_delgroup(ifp, ifc->ifc_name);
-
-       if ((ret = (*ifc->ifc_destroy)(ifp)) != 0)
-               if_addgroup(ifp, ifc->ifc_name);
-
-       return (ret);
+       return ((*ifc->ifc_destroy)(ifp));
 }
 
 /*
Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.191
diff -u -p -r1.191 ip_carp.c
--- netinet/ip_carp.c   16 Oct 2011 21:07:19 -0000      1.191
+++ netinet/ip_carp.c   21 Oct 2011 08:23:04 -0000
@@ -980,7 +980,7 @@ carpdetach(struct carp_softc *sc)
        carp_del_all_timeouts(sc);
 
        if (sc->sc_demote_cnt)
-               carp_group_demote_adj(&sc->sc_if, sc->sc_demote_cnt, "detach");
+               carp_group_demote_adj(&sc->sc_if, -sc->sc_demote_cnt, "detach");
        sc->sc_suppress = 0;
        sc->sc_sendad_errors = 0;

Reply via email to