NOT_REACHED();
}
+static long long int
+cfm_fault_interval(struct cfm_internal *cfmi)
+{
+ /* According to the 802.1ag specification we should assume every other MP
+ * with the same MAID has the same transmission interval that we have. If
+ * an MP has a different interval, cfm_process_heartbeat will register it
+ * as a fault (likely due to a configuration error). Thus we can check all
+ * MPs at once making this quite a bit simpler.
+ *
+ * According to the specification we should check when (ccm_interval_ms *
+ * 3.5)ms have passed. */
+ return (cfmi->ccm_interval_ms * 7) / 2;
+}
+
static uint8_t
ms_to_ccm_interval(int interval_ms)
{
{
long long now = time_msec();
struct cfm_internal *cfmi = cfm_to_internal(cfm);
- long long fault_interval;
- /* According to the 802.1ag specification we should assume every other MP
- * with the same MAID has the same transmission interval that we have. If
- * an MP has a different interval, cfm_process_heartbeat will register it
- * as a fault (likely due to a configuration error). Thus we can check all
- * MPs at once making this quite a bit simpler.
- *
- * According to the specification we should check when (ccm_interval_ms *
- * 3.5)ms have passed. */
- fault_interval = (cfmi->ccm_interval_ms * 7) / 2;
if (timer_expired(&cfmi->fault_timer)) {
bool fault;
struct remote_mp *rmp;
+ long long int interval;
- fault = now < cfmi->x_recv_time + fault_interval;
+ 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;
}
}
cfm->fault = fault;
- timer_set_duration(&cfmi->fault_timer, fault_interval);
+ timer_set_duration(&cfmi->fault_timer, interval);
}
}
bool
cfm_configure(struct cfm *cfm)
{
- struct cfm_internal *cfmi;
+ struct cfm_internal *cfmi = cfm_to_internal(cfm);
+ uint8_t interval;
if (!cfm_is_valid_mpid(cfm->mpid) || !cfm->interval) {
return false;
}
- cfmi = cfm_to_internal(cfm);
- cfmi->ccm_interval = ms_to_ccm_interval(cfm->interval);
- cfmi->ccm_interval_ms = ccm_interval_to_ms(cfmi->ccm_interval);
+ interval = ms_to_ccm_interval(cfm->interval);
+
+ if (interval != cfmi->ccm_interval) {
+ cfmi->ccm_interval = interval;
+ cfmi->ccm_interval_ms = ccm_interval_to_ms(interval);
+
+ timer_set_expired(&cfmi->tx_timer);
+ timer_set_duration(&cfmi->fault_timer, cfm_fault_interval(cfmi));
+ }
- /* Force a resend and check in case anything changed. */
- timer_set_expired(&cfmi->tx_timer);
- timer_set_expired(&cfmi->fault_timer);
return true;
}