diff options
author | Christopher Pascoe <pascoe@cvs.openbsd.org> | 2005-02-07 04:14:40 +0000 |
---|---|---|
committer | Christopher Pascoe <pascoe@cvs.openbsd.org> | 2005-02-07 04:14:40 +0000 |
commit | 5116a0da2ea102908994946a1d06870f24bef7fe (patch) | |
tree | 2f73cbc9faa0ad369b00d240c79c70ced2140d1c /sys/netinet/ip_carp.c | |
parent | 20c4d970db872ba2aad8f63d030685717790dde4 (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.c | 55 |
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; |