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;