BFD: put session admin-up/admin-down 26/5126/3
authorKlement Sekera <ksekera@cisco.com>
Tue, 14 Feb 2017 06:55:57 +0000 (07:55 +0100)
committerDamjan Marion <dmarion.lists@gmail.com>
Fri, 17 Feb 2017 16:32:51 +0000 (16:32 +0000)
Change-Id: I7d8889dce8495607106593ad83320c9af0f2fa07
Signed-off-by: Klement Sekera <ksekera@cisco.com>
src/vnet/bfd/bfd_main.c
test/bfd.py
test/test_bfd.py

index 0959d0e..c0fd18d 100644 (file)
@@ -335,11 +335,14 @@ bfd_session_set_flags (bfd_session_t * bs, u8 admin_up_down)
   bfd_main_t *bm = &bfd_main;
   if (admin_up_down)
     {
+      BFD_DBG ("Session set admin-up, bs-idx=%u", bs->bs_idx);
       bfd_set_state (bm, bs, BFD_STATE_down, 0);
+      bfd_set_diag (bs, BFD_DIAG_CODE_no_diag);
     }
   else
     {
-      bfd_set_diag (bs, BFD_DIAG_CODE_neighbor_sig_down);
+      BFD_DBG ("Session set admin-down, bs-idx=%u", bs->bs_idx);
+      bfd_set_diag (bs, BFD_DIAG_CODE_admin_down);
       bfd_set_state (bm, bs, BFD_STATE_admin_down, 0);
     }
 }
@@ -439,9 +442,7 @@ bfd_on_state_change (bfd_main_t * bm, bfd_session_t * bs, u64 now,
       break;
     case BFD_STATE_init:
       bfd_set_effective_desired_min_tx (bm, bs, now,
-                                       clib_max
-                                       (bs->config_desired_min_tx_clocks,
-                                        bm->default_desired_min_tx_clocks));
+                                       bs->config_desired_min_tx_clocks);
       bfd_set_timer (bm, bs, now, handling_wakeup);
       break;
     case BFD_STATE_up:
@@ -714,18 +715,13 @@ bfd_on_timeout (vlib_main_t * vm, vlib_node_runtime_t * rt, bfd_main_t * bm,
   switch (bs->local_state)
     {
     case BFD_STATE_admin_down:
-      BFD_ERR ("Unexpected timeout when in %s state",
-              bfd_state_string (bs->local_state));
-      abort ();
+      bfd_send_periodic (vm, rt, bm, bs, now, 1);
       break;
     case BFD_STATE_down:
       bfd_send_periodic (vm, rt, bm, bs, now, 1);
       break;
     case BFD_STATE_init:
-      BFD_ERR ("Unexpected timeout when in %s state",
-              bfd_state_string (bs->local_state));
-      abort ();
-      break;
+      /* fallthrough */
     case BFD_STATE_up:
       bfd_check_rx_timeout (bm, bs, now, 1);
       bfd_send_periodic (vm, rt, bm, bs, now, 1);
@@ -1400,7 +1396,11 @@ bfd_consume_pkt (bfd_main_t * bm, const bfd_pkt_t * pkt, u32 bs_idx)
        }
     }
   if (BFD_STATE_admin_down == bs->local_state)
-    return;
+    {
+      BFD_DBG ("Session is admin-down, ignoring packet, bs_idx=%u",
+              bs->bs_idx);
+      return;
+    }
   if (BFD_STATE_admin_down == bs->remote_state)
     {
       bfd_set_diag (bs, BFD_DIAG_CODE_neighbor_sig_down);
index 8eb3b36..8bd9f9a 100644 (file)
@@ -420,3 +420,12 @@ class VppBFDUDPSession(VppObject):
                                                  self.local_addr_n,
                                                  self.peer_addr_n,
                                                  is_ipv6=is_ipv6)
+
+    def admin_down(self):
+        """ set bfd session admin-down """
+        is_ipv6 = 1 if AF_INET6 == self._af else 0
+        self.test.vapi.bfd_udp_session_set_flags(0,
+                                                 self._interface.sw_if_index,
+                                                 self.local_addr_n,
+                                                 self.peer_addr_n,
+                                                 is_ipv6=is_ipv6)
index 64e9301..68baf83 100644 (file)
@@ -671,10 +671,9 @@ class BFD4TestCase(VppTestCase):
     def test_conn_down(self):
         """ verify session goes down after inactivity """
         bfd_session_up(self)
-        for dummy in range(self.test_session.detect_mult):
-            wait_for_bfd_packet(self)
-            self.assert_equal(len(self.vapi.collect_events()), 0,
-                              "number of bfd events")
+        detection_time = self.vpp_session.detect_mult *\
+            self.vpp_session.required_min_rx / USEC_IN_SEC
+        self.sleep(detection_time, "waiting for BFD session time-out")
         e = self.vapi.wait_for_event(1, "bfd_udp_session_details")
         verify_event(self, e, expected_state=BFDState.down)
 
@@ -808,10 +807,6 @@ class BFD4TestCase(VppTestCase):
                              "time before bfd session goes down")
         verify_event(self, e, expected_state=BFDState.down)
 
-    def test_modify_des_min_tx(self):
-        """ modify desired min tx interval """
-        pass
-
     def test_modify_detect_mult(self):
         """ modify detect multiplier """
         bfd_session_up(self)
@@ -903,6 +898,39 @@ class BFD4TestCase(VppTestCase):
         self.assert_equal(udp_sport_tx, udp_sport_rx, "UDP source port (== "
                           "ECHO packet identifier for test purposes)")
 
+    def test_admin_up_down(self):
+        bfd_session_up(self)
+        self.vpp_session.admin_down()
+        self.pg0.enable_capture()
+        e = self.vapi.wait_for_event(1, "bfd_udp_session_details")
+        verify_event(self, e, expected_state=BFDState.admin_down)
+        for dummy in range(2):
+            p = wait_for_bfd_packet(self)
+            self.assert_equal(BFDState.admin_down, p[BFD].state, BFDState)
+        # try to bring session up - shouldn't be possible
+        self.test_session.update(state=BFDState.init)
+        self.test_session.send_packet()
+        for dummy in range(2):
+            p = wait_for_bfd_packet(self)
+            self.assert_equal(BFDState.admin_down, p[BFD].state, BFDState)
+        self.vpp_session.admin_up()
+        self.test_session.update(state=BFDState.down)
+        e = self.vapi.wait_for_event(1, "bfd_udp_session_details")
+        verify_event(self, e, expected_state=BFDState.down)
+        p = wait_for_bfd_packet(self)
+        self.assert_equal(BFDState.down, p[BFD].state, BFDState)
+        self.test_session.send_packet()
+        p = wait_for_bfd_packet(self)
+        self.assert_equal(BFDState.init, p[BFD].state, BFDState)
+        e = self.vapi.wait_for_event(1, "bfd_udp_session_details")
+        verify_event(self, e, expected_state=BFDState.init)
+        self.test_session.update(state=BFDState.up)
+        self.test_session.send_packet()
+        p = wait_for_bfd_packet(self)
+        self.assert_equal(BFDState.up, p[BFD].state, BFDState)
+        e = self.vapi.wait_for_event(1, "bfd_udp_session_details")
+        verify_event(self, e, expected_state=BFDState.up)
+
 
 class BFD6TestCase(VppTestCase):
     """Bidirectional Forwarding Detection (BFD) (IPv6) """