summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2010-04-25 17:38:54 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2010-04-25 17:38:54 +0000
commit5423a7142fc3ef05c909fe26338c0f6914e80312 (patch)
treec58a5aade62001862e15f95d46e7e81748f8d9e1 /sys/netinet
parent083209be9a6b6859f96522362fd5cee27e5b10aa (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.c65
-rw-r--r--sys/netinet/ip_carp.h4
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 **);