diff options
author | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2004-04-28 00:28:44 +0000 |
---|---|---|
committer | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2004-04-28 00:28:44 +0000 |
commit | 6f8c06f8ef514939747639afb8d5cbd5b1b553e6 (patch) | |
tree | 5f8a5509b44e88d1267c482bcf63e9e37a1b2d0a /sys/netinet | |
parent | 75b55077f740c68d8b550e2c7ab6eb3ef8970d16 (diff) |
Make carp(4) aware of its physical interface:
- If the physical interface goes down or the link goes down,
the carp interface goes down as well.
- We treat this like the preemption holdoff with pfsync.
So if one of the carp interfaces is known to be bad (because the
physical interface it's associated with is bad), all the other carp
interfaces back off: they won't preempt, and their advskew goes to 240.
ok cedric@
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_carp.c | 75 | ||||
-rw-r--r-- | sys/netinet/ip_carp.h | 3 |
2 files changed, 52 insertions, 26 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 898adbb6945..f9806c00a3f 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.44 2004/03/26 17:47:20 markus Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.45 2004/04/28 00:28:43 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -85,11 +85,6 @@ #include <net/if_dl.h> #endif -#include "pfsync.h" -#if NPFSYNC > 0 -extern int pfsync_sync_ok; -#endif - #include "bpfilter.h" #if NBPFILTER > 0 #include <net/bpf.h> @@ -111,6 +106,8 @@ struct carp_softc { enum { INIT = 0, BACKUP, MASTER } sc_state; + int sc_flags_backup; + int sc_suppress; int sc_vhid; int sc_advskew; int sc_naddrs; @@ -131,6 +128,7 @@ struct carp_softc { }; +int carp_suppress_preempt = 0; int carp_opts[CARPCTL_MAXID] = { 0, 1, 0, 0, 0 }; /* XXX for now */ struct carpstats carpstats; @@ -539,10 +537,7 @@ carp_input_c(struct mbuf *m, struct carp_header *ch, sa_family_t af) * If we're pre-empting masters who advertise slower than us, * and this one claims to be slower, treat him as down. */ - if (carp_opts[CARPCTL_PREEMPT] -#if NPFSYNC > 0 - && pfsync_sync_ok -#endif /* NPFSYNC > 0 */ + if (carp_opts[CARPCTL_PREEMPT] && !carp_suppress_preempt && timercmp(&sc_tv, &ch_tv, <)) { carp_master_down(sc); break; @@ -610,6 +605,8 @@ carp_clone_create(ifc, unit) return (ENOMEM); bzero(sc, sizeof(*sc)); + sc->sc_flags_backup = 0; + sc->sc_suppress = 0; sc->sc_advbase = CARP_DFLTINTV; sc->sc_vhid = -1; /* required setting */ sc->sc_advskew = 0; @@ -728,7 +725,7 @@ carp_send_ad(void *v) advskew = 255; } else { advbase = sc->sc_advbase; - if (pfsync_sync_ok) + if (!carp_suppress_preempt) advskew = sc->sc_advskew; else { if (sc->sc_advskew < 240) @@ -1102,11 +1099,7 @@ carp_setrun(struct carp_softc *sc, sa_family_t af) switch (sc->sc_state) { case INIT: - if (carp_opts[CARPCTL_PREEMPT] -#if NPFSYNC > 0 - && pfsync_sync_ok -#endif /* NPFSYNC > 0 */ - ) { + if (carp_opts[CARPCTL_PREEMPT] && !carp_suppress_preempt) { carp_send_ad(sc); carp_send_arp(sc); #ifdef INET6 @@ -1500,7 +1493,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: - sc->if_flags |= IFF_UP; + sc->sc_ac.ac_if.if_flags |= IFF_UP; bcopy(ifa->ifa_addr, ifa->ifa_dstaddr, sizeof(struct sockaddr)); error = carp_set_addr(sc, satosin(ifa->ifa_addr)); @@ -1508,7 +1501,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) #endif /* INET */ #ifdef INET6 case AF_INET6: - sc->if_flags |= IFF_UP; + sc->sc_ac.ac_if.if_flags|= IFF_UP; error = carp_set_addr6(sc, satosin6(ifa->ifa_addr)); break; #endif /* INET6 */ @@ -1522,7 +1515,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: - sc->if_flags |= IFF_UP; + sc->sc_ac.ac_if.if_flags |= IFF_UP; bcopy(ifa->ifa_addr, ifa->ifa_dstaddr, sizeof(struct sockaddr)); error = carp_set_addr(sc, satosin(&ifra->ifra_addr)); @@ -1530,7 +1523,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) #endif /* INET */ #ifdef INET6 case AF_INET6: - sc->if_flags |= IFF_UP; + sc->sc_ac.ac_if.if_flags |= IFF_UP; error = carp_set_addr6(sc, satosin6(&ifra->ifra_addr)); break; #endif /* INET6 */ @@ -1541,7 +1534,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) break; case SIOCDIFADDR: - sc->if_flags &= ~IFF_UP; + sc->sc_ac.ac_if.if_flags &= ~IFF_UP; switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: @@ -1560,8 +1553,9 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) break; case SIOCSIFFLAGS: - if (sc->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { - sc->if_flags &= ~IFF_UP; + if (sc->sc_ac.ac_if.if_flags & IFF_UP && + (ifr->ifr_flags & IFF_UP) == 0) { + sc->sc_ac.ac_if.if_flags &= ~IFF_UP; timeout_del(&sc->sc_ad_tmo); timeout_del(&sc->sc_md_tmo); timeout_del(&sc->sc_md6_tmo); @@ -1570,8 +1564,9 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) carp_set_state(sc, INIT); carp_setrun(sc, 0); } - if (ifr->ifr_flags & IFF_UP && (sc->if_flags & IFF_UP) == 0) { - sc->if_flags |= IFF_UP; + if (ifr->ifr_flags & IFF_UP && + (sc->sc_ac.ac_if.if_flags & IFF_UP) == 0) { + sc->sc_ac.ac_if.if_flags |= IFF_UP; carp_set_state(sc, INIT); carp_setrun(sc, 0); } @@ -1776,3 +1771,33 @@ carp_set_state(struct carp_softc *sc, int state) } rt_ifmsg(&sc->sc_ac.ac_if); } + +void +carp_carpdev_state(void *v) +{ + struct carp_if *cif = v; + struct carp_softc *sc; + + TAILQ_FOREACH(sc, &cif->vhif_vrs, sc_list) { + if (sc->sc_ifp->if_link_state == LINK_STATE_DOWN || + !(sc->sc_ifp->if_flags & IFF_UP)) { + sc->sc_flags_backup = sc->sc_ac.ac_if.if_flags; + sc->sc_ac.ac_if.if_flags &= ~(IFF_UP|IFF_RUNNING); + timeout_del(&sc->sc_ad_tmo); + timeout_del(&sc->sc_md_tmo); + timeout_del(&sc->sc_md6_tmo); + carp_set_state(sc, INIT); + carp_setrun(sc, 0); + if (!sc->sc_suppress) + carp_suppress_preempt++; + sc->sc_suppress = 1; + } else { + sc->sc_ac.ac_if.if_flags |= sc->sc_flags_backup; + carp_set_state(sc, INIT); + carp_setrun(sc, 0); + if (sc->sc_suppress) + carp_suppress_preempt--; + sc->sc_suppress = 0; + } + } +} diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h index 057699b9d26..8bcae90c68c 100644 --- a/sys/netinet/ip_carp.h +++ b/sys/netinet/ip_carp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.h,v 1.4 2003/11/16 20:30:07 avsm Exp $ */ +/* $OpenBSD: ip_carp.h,v 1.5 2004/04/28 00:28:43 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -118,6 +118,7 @@ struct carpreq { #ifdef _KERNEL void carp_ifdetach (struct ifnet *); void carp_input (struct mbuf *, ...); +void carp_carpdev_state(void *); int carp6_input (struct mbuf **, int *, int); int carp_output (struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); |