diff options
author | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2004-05-08 02:53:04 +0000 |
---|---|---|
committer | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2004-05-08 02:53:04 +0000 |
commit | c8561b5c4f91aeb363d01182215a54da48f8adfa (patch) | |
tree | 5522721cdfba0ff651f70fc129c291eff0ce77eb | |
parent | 97ea8f0a797a731e94768a4f2d6e4809ed88ea83 (diff) |
If a carp interface has more than CARP_SENDAD_MAX_ERRORS failed
advertisements in a row, back off all the other interfaces, until
CARP_SENDAD_MIN_SUCCESS advertisements are successful.
This makes carp deal better with ip output errors.
-rw-r--r-- | sys/netinet/ip_carp.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index f9806c00a3f..260913a3876 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.45 2004/04/28 00:28:43 mcbride Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.46 2004/05/08 02:53:03 mcbride Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -108,6 +108,12 @@ struct carp_softc { int sc_flags_backup; int sc_suppress; + + int sc_sendad_errors; +#define CARP_SENDAD_MAX_ERRORS 3 + int sc_sendad_success; +#define CARP_SENDAD_MIN_SUCCESS 3 + int sc_vhid; int sc_advskew; int sc_naddrs; @@ -791,8 +797,23 @@ carp_send_ad(void *v) sc->sc_ac.ac_if.if_obytes += len; carpstats.carps_opackets++; - if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) + if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)) { sc->sc_ac.ac_if.if_oerrors++; + if (sc->sc_sendad_errors < INT_MAX) + sc->sc_sendad_errors++; + if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) + carp_suppress_preempt++; + sc->sc_sendad_success = 0; + } else { + if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) { + if (++sc->sc_sendad_success >= + CARP_SENDAD_MIN_SUCCESS) { + carp_suppress_preempt--; + sc->sc_sendad_errors = 0; + } + } else + sc->sc_sendad_errors = 0; + } } #endif /* INET */ #ifdef INET6 @@ -841,8 +862,23 @@ carp_send_ad(void *v) sc->sc_ac.ac_if.if_obytes += len; carpstats.carps_opackets6++; - if (ip6_output(m, NULL, NULL, 0, &sc->sc_im6o, NULL)) + if (ip6_output(m, NULL, NULL, 0, &sc->sc_im6o, NULL)) { sc->sc_ac.ac_if.if_oerrors++; + if (sc->sc_sendad_errors < INT_MAX) + sc->sc_sendad_errors++; + if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) + carp_suppress_preempt++; + sc->sc_sendad_success = 0; + } else { + if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) { + if (++sc->sc_sendad_success >= + CARP_SENDAD_MIN_SUCCESS) { + carp_suppress_preempt--; + sc->sc_sendad_errors = 0; + } + } else + sc->sc_sendad_errors = 0; + } } #endif /* INET6 */ |