aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2011-04-06 17:23:40 -0700
committerEthan Jackson <ethan@nicira.com>2011-04-07 09:34:34 -0700
commit58bd2941187c9df4717ab4f3c6fc3c78f3f25165 (patch)
tree468d794bea86c681bf00ee762dd3edcb763432fe
parentc042664ff51c217c407899b889c10215ba9b3952 (diff)
cfm: Fix broken fault logic.v1.1.0
If the last receive time for a remote MP was before the last fault check, the CFM code would not declare a fault. This is, of course, exactly the wrong response. Bug #5303.
-rw-r--r--lib/cfm.c9
-rw-r--r--lib/timer.c13
-rw-r--r--lib/timer.h1
3 files changed, 20 insertions, 3 deletions
diff --git a/lib/cfm.c b/lib/cfm.c
index 5a547d0d..a504714c 100644
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -174,11 +174,14 @@ cfm_run(struct cfm *cfm)
if (timer_expired(&cfmi->fault_timer)) {
bool fault;
struct remote_mp *rmp;
+ long long int interval;
- fault = now < cfmi->x_recv_time + cfm_fault_interval(cfmi);
+ interval = cfm_fault_interval(cfmi);
+ fault = now < cfmi->x_recv_time + interval;
HMAP_FOR_EACH (rmp, node, &cfm->remote_mps) {
- if (timer_expired_at(&cfmi->fault_timer, rmp->recv_time)) {
+ if (rmp->recv_time < timer_enabled_at(&cfmi->fault_timer, interval)
+ || timer_expired_at(&cfmi->fault_timer, rmp->recv_time)) {
rmp->fault = true;
}
@@ -188,7 +191,7 @@ cfm_run(struct cfm *cfm)
}
cfm->fault = fault;
- timer_set_duration(&cfmi->fault_timer, cfm_fault_interval(cfmi));
+ timer_set_duration(&cfmi->fault_timer, interval);
}
}
diff --git a/lib/timer.c b/lib/timer.c
index b640a7be..1c3c0f48 100644
--- a/lib/timer.c
+++ b/lib/timer.c
@@ -40,3 +40,16 @@ timer_wait(const struct timer *timer)
poll_timer_wait_until(timer->t);
}
}
+
+/* Returns the time at which 'timer' was set with 'duration'. Infinite timers
+ * were enabled at time LLONG_MAX. Manually expired timers were enabled at
+ * LLONG_MIN. */
+long long int
+timer_enabled_at(const struct timer *timer, long long int duration)
+{
+ switch (timer->t) {
+ case LLONG_MAX: return LLONG_MAX;
+ case LLONG_MIN: return LLONG_MIN;
+ default: return timer->t - duration;
+ }
+}
diff --git a/lib/timer.h b/lib/timer.h
index d2bfd86b..73020556 100644
--- a/lib/timer.h
+++ b/lib/timer.h
@@ -26,6 +26,7 @@ struct timer {
};
long long int timer_msecs_until_expired(const struct timer *);
+long long int timer_enabled_at(const struct timer *, long long int duration);
void timer_wait(const struct timer *);
/* Causes 'timer' to expire when 'duration' milliseconds have passed.