summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2007-03-25 18:26:24 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2007-03-25 18:26:24 +0000
commitc79c2c8356953d9f5e3370d0be2c6897be0c0f63 (patch)
treec5e2a6cf2ff965d1c212557113c35ea270db1621
parentb76502f11a09a21f45aa8586d08c8071373ee193 (diff)
Synchronise carp advertisements on group demotion.
This reduces group failover time to a few milliseconds. Diff from Nathanael. OK henning@
-rw-r--r--sys/net/if.c7
-rw-r--r--sys/netinet/ip_carp.c18
2 files changed, 23 insertions, 2 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 7231c29be4b..ddef8fe82e5 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.156 2007/03/18 23:23:17 mpf Exp $ */
+/* $OpenBSD: if.c,v 1.157 2007/03/25 18:26:23 mpf Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -1788,6 +1788,7 @@ if_setgroupattribs(caddr_t data)
{
struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
struct ifg_group *ifg;
+ struct ifg_member *ifgm;
int demote;
TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
@@ -1803,6 +1804,10 @@ if_setgroupattribs(caddr_t data)
ifg->ifg_carp_demoted += demote;
+ TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
+ if (ifgm->ifgm_ifp->if_ioctl)
+ ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp,
+ SIOCSIFGATTR, data);
return (0);
}
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index d2719316dc9..5bb13a82b16 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.133 2007/03/18 23:23:17 mpf Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.134 2007/03/25 18:26:23 mpf Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -193,6 +193,7 @@ void carp_send_arp(struct carp_softc *);
void carp_master_down(void *);
int carp_ioctl(struct ifnet *, u_long, caddr_t);
void carp_ifgroup_ioctl(struct ifnet *, u_long, caddr_t);
+void carp_ifgattr_ioctl(struct ifnet *, u_long, caddr_t);
void carp_start(struct ifnet *);
void carp_setrun(struct carp_softc *, sa_family_t);
void carp_set_state(struct carp_softc *, int);
@@ -2218,6 +2219,9 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
if (sc->sc_suppress)
carp_ifgroup_ioctl(ifp, cmd, addr);
break;
+ case SIOCSIFGATTR:
+ carp_ifgattr_ioctl(ifp, cmd, addr);
+ break;
default:
error = EINVAL;
}
@@ -2246,6 +2250,18 @@ carp_ifgroup_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
}
}
+void
+carp_ifgattr_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
+{
+ struct ifgroupreq *ifgr = (struct ifgroupreq *)addr;
+ struct carp_softc *sc = ifp->if_softc;
+
+ if (ifgr->ifgr_attrib.ifg_carp_demoted > 0 && (sc->sc_if.if_flags &
+ (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING) &&
+ sc->sc_state == MASTER)
+ carp_send_ad(sc);
+}
+
/*
* Start output on carp interface. This function should never be called.
*/