From 76c4290d8adceeec8ee4ffebd5742b5c1f6a1dec Mon Sep 17 00:00:00 2001 From: alex wang Date: Tue, 22 Oct 2013 05:16:23 +0000 Subject: [PATCH] cfm: Add ovsdb column "cfm_flap_count". This commit adds a new ovsdb column "cfm_flap_count". It counts the number of cfm fault flaps since boot. Signed-off-by: Alex Wang Signed-off-by: Ethan Jackson Acked-by: Ethan Jackson --- lib/cfm.c | 19 ++++++++++++++++ lib/cfm.h | 1 + ofproto/ofproto-dpif.c | 1 + ofproto/ofproto.h | 2 ++ tests/cfm.at | 44 +++++++++++++++++++++++++++++++++++++- vswitchd/bridge.c | 5 +++++ vswitchd/vswitch.ovsschema | 7 +++++- vswitchd/vswitch.xml | 5 +++++ 8 files changed, 82 insertions(+), 2 deletions(-) diff --git a/lib/cfm.c b/lib/cfm.c index 730a00f81..d256a5f75 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; /* 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; @@ -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 9d1ea4c35..4213eb538 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 3bbe329c6..9756480d0 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1953,6 +1953,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 c42b068fc..903d1f4f7 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -408,6 +408,8 @@ struct ofproto_cfm_status { * mode. */ int remote_opstate; + 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 638e03ffb..9e351d06e 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 ec3633c40..fecae60b1 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 538dad3d3..78ebc8931 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 4ad0d63fa..52924ee71 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -2009,6 +2009,11 @@ CFM on this . + + Counts the number of cfm fault flapps since boot. A flap is + considered to be a change of the value. + +

Indicates a connectivity fault triggered by an inability to receive -- 2.39.5