cfm: Add ovsdb column "cfm_flap_count".
[sliver-openvswitch.git] / lib / cfm.c
index e8f86dc..d256a5f 100644 (file)
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -129,6 +129,8 @@ struct cfm {
     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
@@ -330,6 +332,7 @@ cfm_create(const struct netdev *netdev) OVS_EXCLUDED(mutex)
     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);
@@ -487,6 +490,11 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex)
             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;
@@ -580,12 +588,27 @@ cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet,
 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)
@@ -819,6 +842,17 @@ cfm_get_fault(const struct cfm *cfm) OVS_EXCLUDED(mutex)
     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,