diff options
author | 2005-02-07 04:14:39 +0000 | |
---|---|---|
committer | 2005-02-07 04:14:39 +0000 | |
commit | ed2b99d7ae7c606dfa5d79cc82d4e404c134bbb3 (patch) | |
tree | f2e8c86047d7bed91f433dd67ea60e8b2adf07ea | |
parent | zap sp64elf.h, get the only config part really used (PREFERRED_DEBUGGING_TYPE) (diff) | |
download | wireguard-openbsd-ed2b99d7ae7c606dfa5d79cc82d4e404c134bbb3.tar.xz wireguard-openbsd-ed2b99d7ae7c606dfa5d79cc82d4e404c134bbb3.zip |
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@
-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; |