[ovs-dev] [PATCH 2/2] bfd: Implements forwarding_if_rx

Alex Wang alexw at nicira.com
Fri Jul 12 01:39:46 UTC 2013


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
tunnel liveness when the tunnel 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 <alexw at nicira.com>
---
 lib/bfd.c            |   48 +++++++++++++++++++++++++++++++++++++++++++-----
 vswitchd/vswitch.xml |    8 ++++++++
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/lib/bfd.c b/lib/bfd.c
index 0d4805a..a16a154 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -186,6 +186,13 @@ struct bfd {
     int ref_cnt;
     int forwarding_override;      /* Manual override of 'forwarding' status. */
 
+    /* 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. */
     bool decay_enabled;           /* Flag that enables bfd decay. */
     int decay_min_rx;
@@ -202,6 +209,7 @@ static long long int bfd_rx_interval(const struct bfd *);
 static uint64_t bfd_rx_packets(const struct bfd *);
 static void bfd_decay_min_rx_set_default(struct bfd *);
 static void bfd_decay(struct bfd *);
+static void bfd_check_rx(struct bfd *);
 static void bfd_set_next_tx(struct bfd *);
 static void bfd_set_state(struct bfd *, enum state, enum diag);
 static uint32_t generate_discriminator(void);
@@ -226,10 +234,11 @@ bfd_forwarding(const struct bfd *bfd)
         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;
 }
 
 /* Returns a 'smap' of key value pairs representing the status of 'bfd'
@@ -261,7 +270,7 @@ bfd_configure(struct bfd *bfd, const char *name,
     static bool init = false;
 
     long long int min_tx, min_rx;
-    bool cpath_down;
+    bool cpath_down, forwarding_if_rx;
 
     if (!init) {
         unixctl_command_register("bfd/show", "[interface]", 0, 1,
@@ -291,6 +300,8 @@ bfd_configure(struct bfd *bfd, const char *name,
         bfd->netdev = 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
@@ -341,6 +352,14 @@ bfd_configure(struct bfd *bfd, const char *name,
         }
         bfd_poll(bfd);
     }
+
+    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);
+        }
+    }
     return bfd;
 }
 
@@ -390,6 +409,11 @@ bfd_run(struct bfd *bfd)
         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_enabled
         && now >= bfd->decay_detect_time) {
         bfd_decay(bfd);
@@ -887,6 +911,20 @@ bfd_decay(struct bfd *bfd)
     }
 }
 
+static void
+bfd_check_rx(struct bfd *bfd)
+{
+    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 f888f4b..8c1170d 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -1896,6 +1896,14 @@
           </code>.
       </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




More information about the dev mailing list