diff options
-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 *); |