diff options
author | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2006-08-16 09:40:53 +0000 |
---|---|---|
committer | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2006-08-16 09:40:53 +0000 |
commit | 7934b9e12b22abb1859a182b83a3603e072416c7 (patch) | |
tree | 55be6028df5172ccdcfe8bbea87bf2e61cfadef0 /sys/netinet/ip_carp.c | |
parent | dd109580266c56df7b5feb24de5100e6d457579f (diff) |
Send out a second delayed gratuitous ARP request after
we've won the MASTER election.
This seems to be necessary w/ some wacky L3 switches,
that only learn by looking at ARP packets.
Fixes PR 5148.
OK mcbride@
Diffstat (limited to 'sys/netinet/ip_carp.c')
-rw-r--r-- | sys/netinet/ip_carp.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index defa6af28e4..54ce44045a4 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.127 2006/06/16 16:49:40 henning Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.128 2006/08/16 09:40:52 mpf Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -141,6 +141,7 @@ struct carp_softc { struct timeout sc_ad_tmo; /* advertisement timeout */ struct timeout sc_md_tmo; /* master down timeout */ struct timeout sc_md6_tmo; /* master down timeout */ + int sc_delayed_arp; /* delayed ARP request countdown */ LIST_HEAD(__carp_mchead, carp_mc_entry) carp_mc_listhead; }; @@ -1035,6 +1036,12 @@ carp_send_ad(void *v) } else sc->sc_sendad_errors = 0; } + if (sc->sc_delayed_arp > 0) + sc->sc_delayed_arp--; + if (sc->sc_delayed_arp == 0) { + carp_send_arp(sc); + sc->sc_delayed_arp = -1; + } } #endif /* INET */ #ifdef INET6 @@ -1383,6 +1390,8 @@ carp_master_down(void *v) carp_set_state(sc, MASTER); carp_send_ad(sc); carp_send_arp(sc); + /* Schedule a delayed ARP request to deal w/ some L3 switches */ + sc->sc_delayed_arp = 2; #ifdef INET6 carp_send_na(sc); #endif /* INET6 */ @@ -1426,6 +1435,7 @@ carp_setrun(struct carp_softc *sc, sa_family_t af) timeout_del(&sc->sc_ad_tmo); tv.tv_sec = 3 * sc->sc_advbase; tv.tv_usec = sc->sc_advskew * 1000000 / 256; + sc->sc_delayed_arp = -1; switch (af) { #ifdef INET case AF_INET: |