summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_carp.c
diff options
context:
space:
mode:
authorChristopher Pascoe <pascoe@cvs.openbsd.org>2005-02-07 04:14:40 +0000
committerChristopher Pascoe <pascoe@cvs.openbsd.org>2005-02-07 04:14:40 +0000
commit5116a0da2ea102908994946a1d06870f24bef7fe (patch)
tree2f73cbc9faa0ad369b00d240c79c70ced2140d1c /sys/netinet/ip_carp.c
parent20c4d970db872ba2aad8f63d030685717790dde4 (diff)
There is no SIOCDIFADDR call into interfaces on address deletion, so
use our carp_addr_updated callback to detect deletion and reconfigure appropriately. ok mcbride@
Diffstat (limited to 'sys/netinet/ip_carp.c')
-rw-r--r--sys/netinet/ip_carp.c55
1 files changed, 35 insertions, 20 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index bfa608cf9d8..e94cf1bf4f8 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.95 2005/01/29 10:06:16 mcbride Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.96 2005/02/07 04:14:39 pascoe Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -1540,6 +1540,40 @@ void
carp_addr_updated(void *v)
{
struct carp_softc *sc = (struct carp_softc *) v;
+ struct ifaddr *ifa;
+ int new_naddrs = 0, new_naddrs6 = 0;
+
+ TAILQ_FOREACH(ifa, &sc->sc_if.if_addrlist, ifa_list) {
+ if (ifa->ifa_addr->sa_family == AF_INET)
+ new_naddrs++;
+ else if (ifa->ifa_addr->sa_family == AF_INET6)
+ new_naddrs6++;
+ }
+
+ /* Handle a callback after SIOCDIFADDR */
+ if (new_naddrs < sc->sc_naddrs || new_naddrs6 < sc->sc_naddrs6) {
+ struct in_addr mc_addr;
+ struct in_multi *inm;
+
+ sc->sc_naddrs = new_naddrs;
+ sc->sc_naddrs6 = new_naddrs6;
+
+ /* Re-establish multicast membership removed by in_control */
+ mc_addr.s_addr = INADDR_CARP_GROUP;
+ IN_LOOKUP_MULTI(mc_addr, &sc->sc_if, inm);
+ if (inm == NULL) {
+ bzero(&sc->sc_imo, sizeof(sc->sc_imo));
+
+ if (sc->sc_carpdev != NULL && sc->sc_naddrs > 0)
+ carp_join_multicast(sc);
+ }
+
+ if (sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) {
+ sc->sc_if.if_flags &= ~IFF_UP;
+ carp_set_state(sc, INIT);
+ } else
+ carp_hmac_prepare(sc);
+ }
carp_setrun(sc, 0);
}
@@ -1814,25 +1848,6 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
}
break;
- case SIOCDIFADDR:
- sc->sc_if.if_flags &= ~IFF_UP;
- switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
- case AF_INET:
- sc->sc_naddrs--;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- sc->sc_naddrs6--;
- break;
-#endif /* INET6 */
- default:
- error = EAFNOSUPPORT;
- break;
- }
- break;
-
case SIOCSIFFLAGS:
if (sc->sc_state != INIT && !(ifr->ifr_flags & IFF_UP)) {
sc->sc_if.if_flags &= ~IFF_UP;