cfm: update remote opstate only when a CCM is received.
authorPaul Ingram <pingram@nicira.com>
Sat, 3 Aug 2013 07:12:36 +0000 (07:12 +0000)
committerBen Pfaff <blp@nicira.com>
Tue, 10 Sep 2013 05:15:09 +0000 (22:15 -0700)
The remote opstate for a CFM interface is presumed to be up unless a CCM is
received which signals opstate down. This means than an interface configured
for CFM demand mode may incorrectly appear to be opstate up if it has not
received a CCM within the last fault interval.

We should remember the last remote opstate for a CFM interface and only
change it when a CCM arrives signaling a change.

Bug #18806
Signed-off-by: Paul Ingram <pingram@nicira.com>
Signed-off-by: Ethan Jackson <ethan@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
AUTHORS
lib/cfm.c

diff --git a/AUTHORS b/AUTHORS
index c42fa7c..a9cb0c9 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -61,6 +61,7 @@ Natasha Gude            natasha@nicira.com
 Neil McKee              neil.mckee@inmon.com
 Paraneetharan Chandrasekaran    paraneetharanc@gmail.com
 Paul Fazzone            pfazzone@nicira.com
+Paul Ingram             paul@nicira.com
 Pavithra Ramesh         paramesh@vmware.com
 Philippe Jung           phil.jung@free.fr
 Pravin B Shelar         pshelar@nicira.com
@@ -179,7 +180,6 @@ Mikael Doverhag         mdoverhag@nicira.com
 Niklas Andersson        nandersson@nicira.com
 Padmanabhan Krishnan    kprad1@yahoo.com
 Pankaj Thakkar          thakkar@nicira.com
-Paul Ingram             paul@nicira.com
 Paulo Cravero           pcravero@as2594.net
 Peter Balland           peter@nicira.com
 Peter Phaal             peter.phaal@inmon.com
index 235d121..a7cc890 100644 (file)
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -350,6 +350,8 @@ cfm_run(struct cfm *cfm)
         struct remote_mp *rmp, *rmp_next;
         bool old_cfm_fault = cfm->fault;
         bool demand_override;
+        bool rmp_set_opup = false;
+        bool rmp_set_opdown = false;
 
         cfm->fault = cfm->recv_fault;
         cfm->recv_fault = 0;
@@ -359,7 +361,6 @@ cfm_run(struct cfm *cfm)
         cfm->rmps_array = xmalloc(hmap_count(&cfm->remote_mps) *
                                   sizeof *cfm->rmps_array);
 
-        cfm->remote_opup = true;
         if (cfm->health_interval == CFM_HEALTH_INTERVAL) {
             /* Calculate the cfm health of the interface.  If the number of
              * remote_mpids of a cfm interface is > 1, the cfm health is
@@ -411,14 +412,23 @@ cfm_run(struct cfm *cfm)
             } else {
                 rmp->recv = false;
 
-                if (!rmp->opup) {
-                    cfm->remote_opup = rmp->opup;
+                if (rmp->opup) {
+                    rmp_set_opup = true;
+                } else {
+                    rmp_set_opdown = true;
                 }
 
                 cfm->rmps_array[cfm->rmps_array_len++] = rmp->mpid;
             }
         }
 
+        if (rmp_set_opdown) {
+            cfm->remote_opup = false;
+        }
+        else if (rmp_set_opup) {
+            cfm->remote_opup = true;
+        }
+
         if (hmap_is_empty(&cfm->remote_mps)) {
             cfm->fault |= CFM_FAULT_RECV;
         }