This commit adds a new boolean option "forwarding_if_rx" to bfd.

When forwarding_if_rx is true and BFD state is down, the forwarding
field in "ovs-appctl bfd/show" output will still be true as long as
there are incoming packets received. This is for indicating the
link liveness when the link is congested and consecutive BFD
control packets are lost. Or when BFD is enabled only on one side
of the tunnel.

Signed-off-by: Alex Wang <al...@nicira.com>
---
 lib/bfd.c            |   47 ++++++++++++++++++++++++++++++++++++++++++-----
 vswitchd/vswitch.xml |    8 ++++++++
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/lib/bfd.c b/lib/bfd.c
index 6420bf9..0a0089b 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -189,6 +189,13 @@ struct bfd {
     atomic_bool check_tnl_key;    /* Verify tunnel key of inbound packets? */
     atomic_int ref_cnt;
 
+    /* When forward_if_rx is true and bfd->state is STATE_DOWN, the
+     * bfd_forwarding() will return true as long as there are incoming
+     * packets received. Note, forwarding_override still has
+     * higher priority. */
+    bool forwarding_if_rx;
+    bool has_rx;
+
     /* BFD decay related variables. */
     int decay_min_rx;
     long long int decay_detect_time; /* Decay detection time. */
@@ -216,6 +223,7 @@ static void bfd_put_details(struct ds *, const struct bfd *)
     OVS_REQ_WRLOCK(&mutex);
 static uint64_t bfd_rx_packets(const struct bfd *) OVS_REQ_WRLOCK(&mutex);
 static void bfd_decay(struct bfd *) OVS_REQ_WRLOCK(&mutex);
+static void bfd_check_rx(struct bfd *) OVS_REQ_WRLOCK(&mutex);
 static void bfd_unixctl_show(struct unixctl_conn *, int argc,
                              const char *argv[], void *aux OVS_UNUSED);
 static void bfd_unixctl_set_forwarding_override(struct unixctl_conn *,
@@ -271,7 +279,7 @@ bfd_configure(struct bfd *bfd, const char *name, const 
struct smap *cfg,
 
     int decay_min_rx;
     long long int min_tx, min_rx;
-    bool cpath_down;
+    bool cpath_down, forwarding_if_rx;
     const char *hwaddr;
     uint8_t ea[ETH_ADDR_LEN];
 
@@ -304,6 +312,8 @@ bfd_configure(struct bfd *bfd, const char *name, const 
struct smap *cfg,
         bfd->netdev = netdev_ref(netdev);
         bfd->decay_detect_time = 0;
         bfd->rx_packets = bfd_rx_packets(bfd);
+        bfd->forwarding_if_rx = false;
+        bfd->has_rx = false;
 
         /* RFC 5881 section 4
          * The source port MUST be in the range 49152 through 65535.  The same
@@ -377,6 +387,13 @@ bfd_configure(struct bfd *bfd, const char *name, const 
struct smap *cfg,
         bfd->eth_dst_set = false;
     }
 
+    forwarding_if_rx = smap_get_bool(cfg, "forwarding_if_rx", false);
+    if (bfd->forwarding_if_rx != forwarding_if_rx) {
+        bfd->forwarding_if_rx = forwarding_if_rx;
+        if (bfd->state <= STATE_DOWN && bfd->forwarding_if_rx) {
+            bfd_check_rx(bfd);
+        }
+    }
     ovs_mutex_unlock(&mutex);
     return bfd;
 }
@@ -439,6 +456,11 @@ bfd_run(struct bfd *bfd) OVS_EXCLUDED(mutex)
         bfd_set_state(bfd, STATE_DOWN, DIAG_EXPIRED);
     }
 
+    if (bfd->state <= STATE_DOWN && bfd->forwarding_if_rx
+        && now >= bfd->detect_time) {
+        bfd_check_rx(bfd);
+    }
+
     if (bfd->state == STATE_UP && bfd->decay_min_rx > 0
         && now >= bfd->decay_detect_time) {
         bfd_decay(bfd);
@@ -749,10 +771,11 @@ bfd_forwarding__(const struct bfd *bfd) 
OVS_REQ_WRLOCK(mutex)
         return bfd->forwarding_override == 1;
     }
 
-    return bfd->state == STATE_UP
-        && bfd->rmt_diag != DIAG_PATH_DOWN
-        && bfd->rmt_diag != DIAG_CPATH_DOWN
-        && bfd->rmt_diag != DIAG_RCPATH_DOWN;
+    return (bfd->forwarding_if_rx && bfd->state <= STATE_DOWN
+            ? bfd->has_rx : bfd->state == STATE_UP)
+           && bfd->rmt_diag != DIAG_PATH_DOWN
+           && bfd->rmt_diag != DIAG_CPATH_DOWN
+           && bfd->rmt_diag != DIAG_RCPATH_DOWN;
 }
 
 /* Helpers. */
@@ -982,6 +1005,20 @@ bfd_decay(struct bfd *bfd) OVS_REQ_WRLOCK(mutex)
     }
 }
 
+static void
+bfd_check_rx(struct bfd *bfd) OVS_REQ_WRLOCK(mutex)
+{
+    uint64_t rx_packets = bfd_rx_packets(bfd);
+    int64_t diff;
+
+    diff = rx_packets - bfd->rx_packets;
+    ovs_assert(diff >= 0);
+
+    bfd->rx_packets = rx_packets;
+    bfd->has_rx = (diff > 0);
+    bfd->detect_time = bfd_rx_interval(bfd) * bfd->mult + time_msec();
+}
+
 static uint32_t
 generate_discriminator(void)
 {
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index b73a612..0bbf472 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1889,6 +1889,14 @@
           reconfigured.
       </column>
 
+      <column name="bfd" key="forwarding_if_rx" type='{"type": "boolean"}'>
+          When <code>forwarding_if_rx</code> is true and BFD state is down,
+          the <code>forwarding</code> field in <code>"ovs-appctl bfd/show"
+          </code> output will still be true as long as there are incoming
+          packets received. This option is for indicating the tunnel liveness
+          when the tunnel becomes congested and consecutive BFD control
+          packets are lost.
+      </column>
 
       <column name="bfd" key="cpath_down" type='{"type": "boolean"}'>
           Concatenated path down may be used when the local system should not
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to