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 | |
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')
-rw-r--r-- | sys/dev/mii/mii_physubr.c | 13 | ||||
-rw-r--r-- | sys/net/if.c | 10 | ||||
-rw-r--r-- | sys/net/if_pfsync.c | 15 | ||||
-rw-r--r-- | sys/netinet/ip_carp.c | 75 | ||||
-rw-r--r-- | sys/netinet/ip_carp.h | 3 |
5 files changed, 86 insertions, 30 deletions
diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c index 7864194fd99..309dc3d73f5 100644 --- a/sys/dev/mii/mii_physubr.c +++ b/sys/dev/mii/mii_physubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mii_physubr.c,v 1.15 2003/03/11 18:28:45 jason Exp $ */ +/* $OpenBSD: mii_physubr.c,v 1.16 2004/04/28 00:28:43 mcbride Exp $ */ /* $NetBSD: mii_physubr.c,v 1.20 2001/04/13 23:30:09 thorpej Exp $ */ /*- @@ -57,6 +57,13 @@ #include <dev/mii/mii.h> #include <dev/mii/miivar.h> +#include "carp.h" +#if NCARP > 0 +#include <netinet/in.h> +#include <netinet/in_var.h> +#include <netinet/ip_carp.h> +#endif + /* * Media to register setting conversion table. Order matters. * XXX 802.3 doesn't specify ANAR or ANLPAR bits for 1000base. @@ -332,6 +339,10 @@ mii_phy_statusmsg(sc) s = splnet(); rt_ifmsg(ifp); splx(s); +#if NCARP > 0 + if (ifp->if_carp) + carp_carpdev_state(ifp->if_carp); +#endif } } diff --git a/sys/net/if.c b/sys/net/if.c index 0524b3fabf4..b6ae2fce723 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.85 2004/04/17 00:09:01 henning Exp $ */ +/* $OpenBSD: if.c,v 1.86 2004/04/28 00:28:43 mcbride Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -1007,6 +1007,10 @@ if_down(struct ifnet *ifp) pfctlinput(PRC_IFDOWN, ifa->ifa_addr); } IFQ_PURGE(&ifp->if_snd); +#if NCARP > 0 + if (ifp->if_carp) + carp_carpdev_state(ifp->if_carp); +#endif rt_ifmsg(ifp); } @@ -1032,6 +1036,10 @@ if_up(struct ifnet *ifp) pfctlinput(PRC_IFUP, ifa->ifa_addr); } #endif +#if NCARP > 0 + if (ifp->if_carp) + carp_carpdev_state(ifp->if_carp); +#endif rt_ifmsg(ifp); #ifdef INET6 in6_if_up(ifp); diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c index a8b741c727e..7309230521d 100644 --- a/sys/net/if_pfsync.c +++ b/sys/net/if_pfsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.30 2004/04/28 00:20:47 pb Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.31 2004/04/28 00:28:43 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -60,6 +60,11 @@ #include <netinet6/nd6.h> #endif /* INET6 */ +#include "carp.h" +#if NCARP > 0 +extern int carp_suppress_preempt; +#endif + #include <net/pfvar.h> #include <net/if_pfsync.h> @@ -74,7 +79,6 @@ int pfsyncdebug; #endif struct pfsync_softc pfsyncif; -int pfsync_sync_ok; struct pfsyncstats pfsyncstats; void pfsyncattach(int); @@ -93,6 +97,7 @@ void pfsync_send_bus(struct pfsync_softc *, u_int8_t); void pfsync_bulk_update(void *); void pfsync_bulkfail(void *); +int pfsync_sync_ok; extern int ifqmaxlen; extern struct timeval time; extern struct timeval mono_time; @@ -670,6 +675,8 @@ pfsync_input(struct mbuf *m, ...) sc->sc_ureq_sent = 0; sc->sc_bulk_tries = 0; timeout_del(&sc->sc_bulkfail_tmo); + if (!pfsync_sync_ok) + carp_suppress_preempt--; pfsync_sync_ok = 1; if (pf_status.debug >= PF_DEBUG_MISC) printf("pfsync: received valid " @@ -797,6 +804,8 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* Request a full state table update. */ sc->sc_ureq_sent = mono_time.tv_sec; + if (pfsync_sync_ok) + carp_suppress_preempt++; pfsync_sync_ok = 0; if (pf_status.debug >= PF_DEBUG_MISC) printf("pfsync: requesting bulk update\n"); @@ -1263,6 +1272,8 @@ pfsync_bulkfail(void *v) /* Pretend like the transfer was ok */ sc->sc_ureq_sent = 0; sc->sc_bulk_tries = 0; + if (!pfsync_sync_ok) + carp_suppress_preempt--; pfsync_sync_ok = 1; if (pf_status.debug >= PF_DEBUG_MISC) printf("pfsync: failed to receive " 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 *); |