summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2004-04-28 00:28:44 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2004-04-28 00:28:44 +0000
commit6f8c06f8ef514939747639afb8d5cbd5b1b553e6 (patch)
tree5f8a5509b44e88d1267c482bcf63e9e37a1b2d0a /sys/netinet
parent75b55077f740c68d8b550e2c7ab6eb3ef8970d16 (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.c75
-rw-r--r--sys/netinet/ip_carp.h3
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 *);