summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/mii/mii_physubr.c13
-rw-r--r--sys/net/if.c10
-rw-r--r--sys/net/if_pfsync.c15
-rw-r--r--sys/netinet/ip_carp.c75
-rw-r--r--sys/netinet/ip_carp.h3
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 *);