diff options
author | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2010-04-25 17:38:54 +0000 |
---|---|---|
committer | Marco Pfatschbacher <mpf@cvs.openbsd.org> | 2010-04-25 17:38:54 +0000 |
commit | 5423a7142fc3ef05c909fe26338c0f6914e80312 (patch) | |
tree | c58a5aade62001862e15f95d46e7e81748f8d9e1 /sys/netinet | |
parent | 083209be9a6b6859f96522362fd5cee27e5b10aa (diff) |
Properly adjust group demotion counters when groups are added or
removed. Extend carp demote logging to also show the reason for
the demote. Return EINVAL instead of ERANGE if a carpdemote request
is out range. Requested from otto.
OK mcbride, henning.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_carp.c | 65 | ||||
-rw-r--r-- | sys/netinet/ip_carp.h | 4 |
2 files changed, 44 insertions, 25 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index f00d0fdc613..af64fd19e40 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.174 2010/01/13 01:26:28 henning Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.175 2010/04/25 17:38:53 mpf Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -141,6 +141,7 @@ struct carp_softc { int sc_suppress; int sc_bow_out; + int sc_demote_cnt; int sc_sendad_errors; #define CARP_SENDAD_MAX_ERRORS(sc) (3 * (sc)->sc_vhe_count) @@ -970,12 +971,9 @@ carpdetach(struct carp_softc *sc) carp_del_all_timeouts(sc); - if (sc->sc_suppress) - carp_group_demote_adj(&sc->sc_if, -1); + if (sc->sc_demote_cnt) + carp_group_demote_adj(&sc->sc_if, sc->sc_demote_cnt, "detach"); sc->sc_suppress = 0; - - if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS(sc)) - carp_group_demote_adj(&sc->sc_if, -1); sc->sc_sendad_errors = 0; carp_set_state_all(sc, INIT); @@ -1189,13 +1187,15 @@ carp_send_ad(void *v) if (sc->sc_sendad_errors < INT_MAX) sc->sc_sendad_errors++; if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS(sc)) - carp_group_demote_adj(&sc->sc_if, 1); + carp_group_demote_adj(&sc->sc_if, 1, + "> snderrors"); sc->sc_sendad_success = 0; } else { if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS(sc)) { if (++sc->sc_sendad_success >= CARP_SENDAD_MIN_SUCCESS(sc)) { - carp_group_demote_adj(&sc->sc_if, -1); + carp_group_demote_adj(&sc->sc_if, -1, + "< snderrors"); sc->sc_sendad_errors = 0; } } else @@ -1274,13 +1274,15 @@ carp_send_ad(void *v) if (sc->sc_sendad_errors < INT_MAX) sc->sc_sendad_errors++; if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS(sc)) - carp_group_demote_adj(&sc->sc_if, 1); + carp_group_demote_adj(&sc->sc_if, 1, + "> snd6errors"); sc->sc_sendad_success = 0; } else { if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS(sc)) { if (++sc->sc_sendad_success >= CARP_SENDAD_MIN_SUCCESS(sc)) { - carp_group_demote_adj(&sc->sc_if, -1); + carp_group_demote_adj(&sc->sc_if, -1, + "< snd6errors"); sc->sc_sendad_errors = 0; } } else @@ -2341,7 +2343,7 @@ carp_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) break; case SIOCAIFGROUP: case SIOCDIFGROUP: - if (sc->sc_suppress) + if (sc->sc_demote_cnt) carp_ifgroup_ioctl(ifp, cmd, addr); break; case SIOCSIFGATTR: @@ -2443,16 +2445,21 @@ carp_ifgroup_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) { struct ifgroupreq *ifgr = (struct ifgroupreq *)addr; struct ifg_list *ifgl; + int *dm, adj; if (!strcmp(ifgr->ifgr_group, IFG_ALL)) return; + adj = ((struct carp_softc *)ifp->if_softc)->sc_demote_cnt; + if (cmd == SIOCDIFGROUP) + adj = adj * -1; + TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) if (!strcmp(ifgl->ifgl_group->ifg_group, ifgr->ifgr_group)) { - if (cmd == SIOCAIFGROUP) - ifgl->ifgl_group->ifg_carp_demoted++; - else if (cmd == SIOCDIFGROUP && - ifgl->ifgl_group->ifg_carp_demoted) - ifgl->ifgl_group->ifg_carp_demoted--; + dm = &ifgl->ifgl_group->ifg_carp_demoted; + if (*dm + adj >= 0) + *dm += adj; + else + *dm = 0; } } @@ -2550,12 +2557,20 @@ carp_set_state(struct carp_vhost_entry *vhe, int state) } void -carp_group_demote_adj(struct ifnet *ifp, int adj) +carp_group_demote_adj(struct ifnet *ifp, int adj, char *reason) { struct ifg_list *ifgl; int *dm; struct carp_softc *nil = NULL; + if (ifp->if_type == IFT_CARP) { + dm = &((struct carp_softc *)ifp->if_softc)->sc_demote_cnt; + if (*dm + adj >= 0) + *dm += adj; + else + *dm = 0; + } + TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) { if (!strcmp(ifgl->ifgl_group->ifg_group, IFG_ALL)) continue; @@ -2568,8 +2583,10 @@ carp_group_demote_adj(struct ifnet *ifp, int adj) if (adj > 0 && *dm == 1) carp_send_ad_all(); - CARP_LOG(LOG_INFO, nil, ("%s demoted group %s to %d", ifp->if_xname, - ifgl->ifgl_group->ifg_group, *dm)); + CARP_LOG(LOG_NOTICE, nil, + ("%s demoted group %s by %d to %d (%s)", + ifp->if_xname, ifgl->ifgl_group->ifg_group, + adj, *dm, reason)); } } @@ -2582,6 +2599,9 @@ carp_group_demote_count(struct carp_softc *sc) TAILQ_FOREACH(ifgl, &sc->sc_if.if_groups, ifgl_next) count += ifgl->ifgl_group->ifg_carp_demoted; + if (count == 0 && sc->sc_demote_cnt) + count = sc->sc_demote_cnt; + return (count > 255 ? 255 : count); } @@ -2608,13 +2628,12 @@ carp_carpdev_state(void *v) sc->sc_suppress = 1; carp_setrun_all(sc, 0); if (!suppressed) - carp_group_demote_adj(&sc->sc_if, 1); - } else { + carp_group_demote_adj(&sc->sc_if, 1, "carpdev"); + } else if (suppressed) { carp_set_state_all(sc, INIT); sc->sc_suppress = 0; carp_setrun_all(sc, 0); - if (suppressed) - carp_group_demote_adj(&sc->sc_if, -1); + carp_group_demote_adj(&sc->sc_if, -1, "carpdev"); } } } diff --git a/sys/netinet/ip_carp.h b/sys/netinet/ip_carp.h index 145bc9d4023..57155e2313c 100644 --- a/sys/netinet/ip_carp.h +++ b/sys/netinet/ip_carp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.h,v 1.27 2008/06/14 21:46:22 reyk Exp $ */ +/* $OpenBSD: ip_carp.h,v 1.28 2010/04/25 17:38:53 mpf Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -166,7 +166,7 @@ struct carpreq { void carp_ifdetach (struct ifnet *); void carp_proto_input (struct mbuf *, ...); void carp_carpdev_state(void *); -void carp_group_demote_adj(struct ifnet *, int); +void carp_group_demote_adj(struct ifnet *, int, char *); int carp6_proto_input(struct mbuf **, int *, int); int carp_iamatch(struct in_ifaddr *, u_char *, u_int8_t **, u_int8_t **); |