cfm: Notify connectivity_seq on remote maintenance points change.
[cascardo/ovs.git] / lib / cfm.c
index d256a5f..d31c1aa 100644 (file)
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include "byte-order.h"
+#include "connectivity.h"
 #include "dynamic-string.h"
 #include "flow.h"
 #include "hash.h"
@@ -31,6 +32,7 @@
 #include "packets.h"
 #include "poll-loop.h"
 #include "random.h"
+#include "seq.h"
 #include "timer.h"
 #include "timeval.h"
 #include "unixctl.h"
@@ -234,7 +236,7 @@ static int
 ccm_interval_to_ms(uint8_t interval)
 {
     switch (interval) {
-    case 0:  NOT_REACHED(); /* Explicitly not supported by 802.1ag. */
+    case 0:  OVS_NOT_REACHED(); /* Explicitly not supported by 802.1ag. */
     case 1:  return 3;      /* Not recommended due to timer resolution. */
     case 2:  return 10;     /* Not recommended due to timer resolution. */
     case 3:  return 100;
@@ -242,10 +244,10 @@ ccm_interval_to_ms(uint8_t interval)
     case 5:  return 10000;
     case 6:  return 60000;
     case 7:  return 600000;
-    default: NOT_REACHED(); /* Explicitly not supported by 802.1ag. */
+    default: OVS_NOT_REACHED(); /* Explicitly not supported by 802.1ag. */
     }
 
-    NOT_REACHED();
+    OVS_NOT_REACHED();
 }
 
 static long long int
@@ -395,7 +397,12 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex)
     if (timer_expired(&cfm->fault_timer)) {
         long long int interval = cfm_fault_interval(cfm);
         struct remote_mp *rmp, *rmp_next;
+        uint64_t old_flap_count = cfm->flap_count;
+        int old_health = cfm->health;
+        size_t old_rmps_array_len = cfm->rmps_array_len;
+        bool old_rmps_deleted = false;
         bool old_cfm_fault = cfm->fault;
+        bool old_rmp_opup = cfm->remote_opup;
         bool demand_override;
         bool rmp_set_opup = false;
         bool rmp_set_opdown = false;
@@ -453,6 +460,7 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex)
                           " %lldms", cfm->name, rmp->mpid,
                           time_msec() - rmp->last_rx);
                 if (!demand_override) {
+                    old_rmps_deleted = true;
                     hmap_remove(&cfm->remote_mps, &rmp->node);
                     free(rmp);
                 }
@@ -480,16 +488,18 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex)
             cfm->fault |= CFM_FAULT_RECV;
         }
 
-        if (old_cfm_fault != cfm->fault && !VLOG_DROP_INFO(&rl)) {
-            struct ds ds = DS_EMPTY_INITIALIZER;
-
-            ds_put_cstr(&ds, "from [");
-            ds_put_cfm_fault(&ds, old_cfm_fault);
-            ds_put_cstr(&ds, "] to [");
-            ds_put_cfm_fault(&ds, cfm->fault);
-            ds_put_char(&ds, ']');
-            VLOG_INFO("%s: CFM faults changed %s.", cfm->name, ds_cstr(&ds));
-            ds_destroy(&ds);
+        if (old_cfm_fault != cfm->fault) {
+            if (!VLOG_DROP_INFO(&rl)) {
+                struct ds ds = DS_EMPTY_INITIALIZER;
+
+                ds_put_cstr(&ds, "from [");
+                ds_put_cfm_fault(&ds, old_cfm_fault);
+                ds_put_cstr(&ds, "] to [");
+                ds_put_cfm_fault(&ds, cfm->fault);
+                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) {
@@ -497,6 +507,16 @@ cfm_run(struct cfm *cfm) OVS_EXCLUDED(mutex)
             }
         }
 
+        /* These variables represent the cfm session status, it is desirable
+         * to update them to database immediately after change. */
+        if (old_health != cfm->health
+            || old_rmp_opup != cfm->remote_opup
+            || (old_rmps_array_len != cfm->rmps_array_len || old_rmps_deleted)
+            || old_cfm_fault != cfm->fault
+            || old_flap_count != cfm->flap_count) {
+            seq_change(connectivity_seq_get());
+        }
+
         cfm->booted = true;
         timer_set_duration(&cfm->fault_timer, interval);
         VLOG_DBG("%s: new fault interval", cfm->name);
@@ -1018,6 +1038,7 @@ cfm_unixctl_set_fault(struct unixctl_conn *conn, int argc, const char *argv[],
         }
     }
 
+    seq_change(connectivity_seq_get());
     unixctl_command_reply(conn, "OK");
 
 out: