summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Pfatschbacher <mpf@cvs.openbsd.org>2009-06-17 20:17:20 +0000
committerMarco Pfatschbacher <mpf@cvs.openbsd.org>2009-06-17 20:17:20 +0000
commit797a696817dbc9fc4db366b44674fef4ca5ec2ca (patch)
treeecc85ca4614fc176cf0d3d446ba28053810a59b0
parent9d240caa74ea132af0ef4b7b7c3e7b2a54f65658 (diff)
Correctly handle the carp demote counter in all input cases.
E.g. give up the MASTER status if there's a host with a lower demote count, even if it has a higher advskew. At the moment this shouldn't cause any change, but this is a first step towards the removal of the "bump the advskew to 240 in case of errors" hack, without breaking backward compatibility. OK henning@
-rw-r--r--sys/netinet/ip_carp.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 87be99facf6..c4822b6b4a7 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.170 2009/06/05 00:05:22 claudio Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.171 2009/06/17 20:17:19 mpf Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -753,12 +753,14 @@ carp_proto_input_c(struct mbuf *m, struct carp_header *ch, int ismulti,
case MASTER:
/*
* If we receive an advertisement from a master who's going to
- * be more frequent than us, go into BACKUP state.
+ * be more frequent than us, and whose demote count is not higher
+ * than ours, go into BACKUP state. If his demote count is lower,
+ * also go into BACKUP.
*/
- if (timercmp(&sc_tv, &ch_tv, >) ||
- (timercmp(&sc_tv, &ch_tv, ==) &&
- ch->carp_demote <=
- (carp_group_demote_count(sc) & 0xff))) {
+ if (((timercmp(&sc_tv, &ch_tv, >) ||
+ timercmp(&sc_tv, &ch_tv, ==)) &&
+ (ch->carp_demote <= carp_group_demote_count(sc))) ||
+ ch->carp_demote < carp_group_demote_count(sc)) {
timeout_del(&vhe->ad_tmo);
carp_set_state(vhe, BACKUP);
carp_setrun(vhe, 0);
@@ -769,9 +771,12 @@ carp_proto_input_c(struct mbuf *m, struct carp_header *ch, int ismulti,
case BACKUP:
/*
* If we're pre-empting masters who advertise slower than us,
- * and this one claims to be slower, treat him as down.
+ * and do not have a better demote count, treat them as down.
+ *
*/
- if (carp_opts[CARPCTL_PREEMPT] && timercmp(&sc_tv, &ch_tv, <)) {
+ if (carp_opts[CARPCTL_PREEMPT] &&
+ timercmp(&sc_tv, &ch_tv, <) &&
+ ch->carp_demote >= carp_group_demote_count(sc)) {
carp_master_down(vhe);
break;
}
@@ -780,7 +785,7 @@ carp_proto_input_c(struct mbuf *m, struct carp_header *ch, int ismulti,
* Take over masters advertising with a higher demote count,
* regardless of CARPCTL_PREEMPT.
*/
- if (ch->carp_demote > (carp_group_demote_count(sc) & 0xff)) {
+ if (ch->carp_demote > carp_group_demote_count(sc)) {
carp_master_down(vhe);
break;
}