atomic_bool check_tnl_key; /* Verify the tunnel key of inbound packets? */
atomic_bool extended; /* Extended mode. */
atomic_int ref_cnt;
+
+ uint64_t flap_count; /* Count the flaps since boot. */
};
/* Remote MPs represent foreign network entities that are configured to have
cfm->fault_override = -1;
cfm->health = -1;
cfm->last_tx = 0;
+ cfm->flap_count = 0;
atomic_init(&cfm->extended, false);
atomic_init(&cfm->check_tnl_key, false);
atomic_init(&cfm->ref_cnt, 1);
ds_put_char(&ds, ']');
VLOG_INFO("%s: CFM faults changed %s.", cfm->name, ds_cstr(&ds));
ds_destroy(&ds);
+
+ /* If there is a flap, increments the counter. */
+ if (old_cfm_fault == false || cfm->fault == false) {
+ cfm->flap_count++;
+ }
}
cfm->booted = true;
void
cfm_wait(struct cfm *cfm) OVS_EXCLUDED(mutex)
{
+ poll_timer_wait_until(cfm_wake_time(cfm));
+}
+
+
+/* Returns the next cfm wakeup time. */
+long long int
+cfm_wake_time(struct cfm *cfm) OVS_EXCLUDED(mutex)
+{
+ long long int retval;
+
+ if (!cfm) {
+ return LLONG_MAX;
+ }
+
ovs_mutex_lock(&mutex);
- timer_wait(&cfm->tx_timer);
- timer_wait(&cfm->fault_timer);
+ retval = MIN(cfm->tx_timer.t, cfm->fault_timer.t);
ovs_mutex_unlock(&mutex);
+ return retval;
}
+
/* Configures 'cfm' with settings from 's'. */
bool
cfm_configure(struct cfm *cfm, const struct cfm_settings *s)
return fault;
}
+/* Gets the number of cfm fault flapping since start. */
+uint64_t
+cfm_get_flap_count(const struct cfm *cfm) OVS_EXCLUDED(mutex)
+{
+ uint64_t flap_count;
+ ovs_mutex_lock(&mutex);
+ flap_count = cfm->flap_count;
+ ovs_mutex_unlock(&mutex);
+ return flap_count;
+}
+
/* Gets the health of 'cfm'. Returns an integer between 0 and 100 indicating
* the health of the link as a percentage of ccm frames received in
* CFM_HEALTH_INTERVAL * 'fault_interval' if there is only 1 remote_mpid,