[ovs-dev] [PATCH 1/2] cfm: Add ovsdb column "cfm_flap_count".

Alex Wang alexw at nicira.com
Mon Oct 21 21:16:23 UTC 2013


This commit adds a new ovsdb column "cfm_flap_count".  It is to count
the number of cfm fault flapping since start.

Signed-off-by: Alex Wang <alexw at nicira.com>
---
 lib/cfm.c                  |   19 +++++++++++++++++++
 lib/cfm.h                  |    1 +
 ofproto/ofproto-dpif.c     |    1 +
 ofproto/ofproto.h          |    3 +++
 tests/cfm.at               |   44 +++++++++++++++++++++++++++++++++++++++++++-
 vswitchd/bridge.c          |    5 +++++
 vswitchd/vswitch.ovsschema |    7 ++++++-
 vswitchd/vswitch.xml       |    5 +++++
 8 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/lib/cfm.c b/lib/cfm.c
index 730a00f..ad43b3f 100644
--- 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;       /* Counts the flapping since start. */
 };
 
 /* 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;
@@ -834,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,
diff --git a/lib/cfm.h b/lib/cfm.h
index 9d1ea4c..4213eb5 100644
--- a/lib/cfm.h
+++ b/lib/cfm.h
@@ -77,6 +77,7 @@ bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *,
                              struct flow_wildcards *);
 void cfm_process_heartbeat(struct cfm *, const struct ofpbuf *packet);
 int cfm_get_fault(const struct cfm *);
+uint64_t cfm_get_flap_count(const struct cfm *);
 int cfm_get_health(const struct cfm *);
 int cfm_get_opup(const struct cfm *);
 void cfm_get_remote_mpids(const struct cfm *, uint64_t **rmps, size_t *n_rmps);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 90ce715..da19a6a 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1931,6 +1931,7 @@ get_cfm_status(const struct ofport *ofport_,
 
     if (ofport->cfm) {
         status->faults = cfm_get_fault(ofport->cfm);
+        status->flap_count = cfm_get_flap_count(ofport->cfm);
         status->remote_opstate = cfm_get_opup(ofport->cfm);
         status->health = cfm_get_health(ofport->cfm);
         cfm_get_remote_mpids(ofport->cfm, &status->rmps, &status->n_rmps);
diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
index c42b068..929cec5 100644
--- a/ofproto/ofproto.h
+++ b/ofproto/ofproto.h
@@ -408,6 +408,9 @@ struct ofproto_cfm_status {
      * mode. */
     int remote_opstate;
 
+    /* Counts the flapping. */
+    uint64_t flap_count;
+
     /* Ordinarily a "health status" in the range 0...100 inclusive, with 0
      * being worst and 100 being best, or -1 if the health status is not
      * well-defined. */
diff --git a/tests/cfm.at b/tests/cfm.at
index 638e03f..9e351d0 100644
--- a/tests/cfm.at
+++ b/tests/cfm.at
@@ -14,9 +14,16 @@ Remote MPID $7
 ])
 ])
 
+m4_define([CFM_VSCTL_LIST_IFACE], [
+AT_CHECK([ovs-vsctl list interface $1 | sed -n '/$2/p'],[0],
+[dnl
+$3
+])
+])
+
 # test cfm under demand mode.
 AT_SETUP([cfm - demand mode])
-#Create 2 bridges connected by patch ports and enable BFD
+#Create 2 bridges connected by patch ports and enable cfm
 OVS_VSWITCHD_START([add-br br1 -- \
                     set bridge br1 datapath-type=dummy \
                     other-config:hwaddr=aa:55:aa:56:00:00 -- \
@@ -55,3 +62,38 @@ done
 
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+# test cfm_flap_count.
+AT_SETUP([cfm - flap_count])
+#Create 2 bridges connected by patch ports and enable cfm
+OVS_VSWITCHD_START([add-br br1 -- \
+                    set bridge br1 datapath-type=dummy \
+                    other-config:hwaddr=aa:55:aa:56:00:00 -- \
+                    add-port br1 p1 -- set Interface p1 type=patch \
+                    options:peer=p0 -- \
+                    add-port br0 p0 -- set Interface p0 type=patch \
+                    options:peer=p1 -- \
+                    set Interface p0 cfm_mpid=1 other_config:cfm_interval=100 other_config:cfm_extended=true -- \
+                    set Interface p1 cfm_mpid=2 other_config:cfm_interval=100 other_config:cfm_extended=true])
+
+ovs-appctl time/stop
+
+# wait for a while to stablize cfm.
+for i in `seq 0 100`; do ovs-appctl time/warp 100; done
+CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up])
+CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up])
+
+# turn cfm on p1 off, should increment the cfm_flap_count on p1.
+AT_CHECK([ovs-vsctl remove interface p1 cfm_mpid 2])
+for i in `seq 0 10`; do ovs-appctl time/warp 100; done
+CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count      : 1])
+CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count      : [[]]])
+
+# turn cfm on p1 on again, should increment the cfm_flap_count on p1.
+AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2])
+for i in `seq 0 10`; do ovs-appctl time/warp 100; done
+CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count      : 2])
+CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count      : 0])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
\ No newline at end of file
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index ec3633c..fecae60 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -376,6 +376,7 @@ bridge_init(const char *remote)
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_fault);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_fault_status);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_remote_mpids);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_flap_count);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_health);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_cfm_remote_opstate);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_bfd_status);
@@ -1890,11 +1891,13 @@ iface_refresh_cfm_stats(struct iface *iface)
         ovsrec_interface_set_cfm_fault(cfg, NULL, 0);
         ovsrec_interface_set_cfm_fault_status(cfg, NULL, 0);
         ovsrec_interface_set_cfm_remote_opstate(cfg, NULL);
+        ovsrec_interface_set_cfm_flap_count(cfg, NULL, 0);
         ovsrec_interface_set_cfm_health(cfg, NULL, 0);
         ovsrec_interface_set_cfm_remote_mpids(cfg, NULL, 0);
     } else {
         const char *reasons[CFM_FAULT_N_REASONS];
         int64_t cfm_health = status.health;
+        int64_t cfm_flap_count = status.flap_count;
         bool faulted = status.faults != 0;
         size_t i, j;
 
@@ -1909,6 +1912,8 @@ iface_refresh_cfm_stats(struct iface *iface)
         }
         ovsrec_interface_set_cfm_fault_status(cfg, (char **) reasons, j);
 
+        ovsrec_interface_set_cfm_flap_count(cfg, &cfm_flap_count, 1);
+
         if (status.remote_opstate >= 0) {
             const char *remote_opstate = status.remote_opstate ? "up" : "down";
             ovsrec_interface_set_cfm_remote_opstate(cfg, remote_opstate);
diff --git a/vswitchd/vswitch.ovsschema b/vswitchd/vswitch.ovsschema
index 538dad3..78ebc89 100644
--- a/vswitchd/vswitch.ovsschema
+++ b/vswitchd/vswitch.ovsschema
@@ -1,6 +1,6 @@
 {"name": "Open_vSwitch",
  "version": "7.3.0",
- "cksum": "2483452374 20182",
+ "cksum": "2811681289 20311",
  "tables": {
    "Open_vSwitch": {
      "columns": {
@@ -224,6 +224,11 @@
            "min": 0,
            "max": "unlimited"},
          "ephemeral": true},
+       "cfm_flap_count": {
+         "type": {
+           "key": {"type": "integer"},
+           "min": 0,
+           "max": 1}},
        "cfm_fault": {
          "type": {
            "key": { "type": "boolean"},
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index c12fd8f..36f1bc6 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -2000,6 +2000,11 @@
         CFM on this <ref table="Interface"/>.
       </column>
 
+      <column name="cfm_flap_count">
+        Counts the number of cfm fault flapping since start.  A flap is
+        considered as the change of <ref column="cfm_fault"/> value.
+      </column>
+
       <column name="cfm_fault">
         <p>
           Indicates a connectivity fault triggered by an inability to receive
-- 
1.7.9.5




More information about the dev mailing list