bfd: Add an update API that has create new or modify existing semantics 69/35269/1
authorNeale Ranns <neale@graphiant.com>
Wed, 9 Feb 2022 13:47:29 +0000 (13:47 +0000)
committerNeale Ranns <neale@graphiant.com>
Wed, 9 Feb 2022 13:47:29 +0000 (13:47 +0000)
Type: improvement

helps keep the agents stateless

Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: I3588f13c081e24f5a8083b490eb02856361e4ccb

src/vnet/bfd/bfd.api
src/vnet/bfd/bfd_api.c
src/vnet/bfd/bfd_api.h
src/vnet/bfd/bfd_udp.c
test/bfd.py
test/test_bfd.py

index f53cc76..3957a94 100644 (file)
@@ -107,6 +107,26 @@ autoreply define bfd_udp_add
   u8 bfd_key_id;
   u32 conf_key_id;
 };
+define bfd_udp_upd
+{
+  u32 client_index;
+  u32 context;
+  vl_api_interface_index_t sw_if_index;
+  u32 desired_min_tx;
+  u32 required_min_rx;
+  vl_api_address_t local_addr;
+  vl_api_address_t peer_addr;
+  u8 detect_mult;
+  bool is_authenticated;
+  u8 bfd_key_id;
+  u32 conf_key_id;
+};
+define bfd_udp_upd_reply
+{
+  u32 context;
+  i32 retval;
+  u32 stats_index;
+};
 
 /** \brief Modify UDP BFD session on interface
     @param client_index - opaque cookie to identify the sender
index 0ae8508..4d76f71 100644 (file)
@@ -70,6 +70,27 @@ vl_api_bfd_udp_add_t_handler (vl_api_bfd_udp_add_t * mp)
   REPLY_MACRO (VL_API_BFD_UDP_ADD_REPLY);
 }
 
+static void
+vl_api_bfd_udp_upd_t_handler (vl_api_bfd_udp_add_t *mp)
+{
+  vl_api_bfd_udp_upd_reply_t *rmp;
+  int rv;
+
+  VALIDATE_SW_IF_INDEX (mp);
+
+  BFD_UDP_API_PARAM_COMMON_CODE;
+
+  rv = bfd_udp_upd_session (
+    BFD_UDP_API_PARAM_FROM_MP (mp), clib_net_to_host_u32 (mp->desired_min_tx),
+    clib_net_to_host_u32 (mp->required_min_rx), mp->detect_mult,
+    mp->is_authenticated, clib_net_to_host_u32 (mp->conf_key_id),
+    mp->bfd_key_id);
+
+  BAD_SW_IF_INDEX_LABEL;
+  REPLY_MACRO2 (VL_API_BFD_UDP_UPD_REPLY,
+               ({ rmp->stats_index = clib_host_to_net_u32 (0); }));
+}
+
 static void
 vl_api_bfd_udp_mod_t_handler (vl_api_bfd_udp_mod_t * mp)
 {
index 2a6c69b..f051e6b 100644 (file)
@@ -44,6 +44,15 @@ bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
                     u8 detect_mult, u8 is_authenticated, u32 conf_key_id,
                     u8 bfd_key_id);
 
+/**
+ * @brief create a new or modify and existing bfd session
+ */
+vnet_api_error_t
+bfd_udp_upd_session (u32 sw_if_index, const ip46_address_t *local_addr,
+                    const ip46_address_t *peer_addr, u32 desired_min_tx_usec,
+                    u32 required_min_rx_usec, u8 detect_mult,
+                    u8 is_authenticated, u32 conf_key_id, u8 bfd_key_id);
+
 /**
  * @brief modify existing session
  */
index 333b321..a58d9e2 100644 (file)
@@ -738,6 +738,39 @@ bfd_udp_del_session_internal (vlib_main_t * vm, bfd_session_t * bs)
   bfd_put_session (bum->bfd_main, bs);
 }
 
+static vnet_api_error_t
+bfd_udp_add_and_start_session (u32 sw_if_index,
+                              const ip46_address_t *local_addr,
+                              const ip46_address_t *peer_addr,
+                              u32 desired_min_tx_usec,
+                              u32 required_min_rx_usec, u8 detect_mult,
+                              u8 is_authenticated, u32 conf_key_id,
+                              u8 bfd_key_id)
+{
+  bfd_session_t *bs = NULL;
+  vnet_api_error_t rv;
+
+  rv = bfd_udp_add_session_internal (
+    vlib_get_main (), &bfd_udp_main, sw_if_index, desired_min_tx_usec,
+    required_min_rx_usec, detect_mult, local_addr, peer_addr, &bs);
+
+  if (!rv && is_authenticated)
+    {
+      rv = bfd_auth_activate (bs, conf_key_id, bfd_key_id,
+                             0 /* is not delayed */);
+      if (rv)
+       {
+         bfd_udp_del_session_internal (vlib_get_main (), bs);
+       }
+    }
+  if (!rv)
+    {
+      bfd_session_start (bfd_udp_main.bfd_main, bs);
+    }
+
+  return rv;
+}
+
 vnet_api_error_t
 bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
                     const ip46_address_t * peer_addr,
@@ -752,27 +785,44 @@ bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
     bfd_api_verify_common (sw_if_index, desired_min_tx_usec,
                           required_min_rx_usec, detect_mult,
                           local_addr, peer_addr);
-  bfd_session_t *bs = NULL;
+
   if (!rv)
-    {
-      rv =
-       bfd_udp_add_session_internal (vlib_get_main (), &bfd_udp_main,
-                                     sw_if_index, desired_min_tx_usec,
-                                     required_min_rx_usec, detect_mult,
-                                     local_addr, peer_addr, &bs);
-    }
-  if (!rv && is_authenticated)
-    {
-      rv = bfd_auth_activate (bs, conf_key_id, bfd_key_id,
-                             0 /* is not delayed */ );
-      if (rv)
-       {
-         bfd_udp_del_session_internal (vlib_get_main (), bs);
-       }
-    }
+    rv = bfd_udp_add_and_start_session (
+      sw_if_index, local_addr, peer_addr, desired_min_tx_usec,
+      required_min_rx_usec, detect_mult, is_authenticated, conf_key_id,
+      bfd_key_id);
+
+  bfd_unlock (bm);
+  return rv;
+}
+
+vnet_api_error_t
+bfd_udp_upd_session (u32 sw_if_index, const ip46_address_t *local_addr,
+                    const ip46_address_t *peer_addr, u32 desired_min_tx_usec,
+                    u32 required_min_rx_usec, u8 detect_mult,
+                    u8 is_authenticated, u32 conf_key_id, u8 bfd_key_id)
+{
+  bfd_main_t *bm = &bfd_main;
+  bfd_lock (bm);
+
+  vnet_api_error_t rv = bfd_api_verify_common (
+    sw_if_index, desired_min_tx_usec, required_min_rx_usec, detect_mult,
+    local_addr, peer_addr);
   if (!rv)
     {
-      bfd_session_start (bfd_udp_main.bfd_main, bs);
+      bfd_session_t *bs = NULL;
+
+      rv = bfd_udp_find_session_by_api_input (sw_if_index, local_addr,
+                                             peer_addr, &bs);
+      if (VNET_API_ERROR_BFD_ENOENT == rv)
+       rv = bfd_udp_add_and_start_session (
+         sw_if_index, local_addr, peer_addr, desired_min_tx_usec,
+         required_min_rx_usec, detect_mult, is_authenticated, conf_key_id,
+         bfd_key_id);
+      else
+       rv = bfd_session_set_params (bfd_udp_main.bfd_main, bs,
+                                    desired_min_tx_usec, required_min_rx_usec,
+                                    detect_mult);
     }
 
   bfd_unlock (bm);
@@ -780,10 +830,8 @@ bfd_udp_add_session (u32 sw_if_index, const ip46_address_t * local_addr,
 }
 
 vnet_api_error_t
-bfd_udp_mod_session (u32 sw_if_index,
-                    const ip46_address_t * local_addr,
-                    const ip46_address_t * peer_addr,
-                    u32 desired_min_tx_usec,
+bfd_udp_mod_session (u32 sw_if_index, const ip46_address_t *local_addr,
+                    const ip46_address_t *peer_addr, u32 desired_min_tx_usec,
                     u32 required_min_rx_usec, u8 detect_mult)
 {
   bfd_session_t *bs = NULL;
index 9d44425..bbfa594 100644 (file)
@@ -392,6 +392,30 @@ class VppBFDUDPSession(VppObject):
                                    is_authenticated=is_authenticated)
         self._test.registry.register(self, self.test.logger)
 
+    def upd_vpp_config(self,
+                       detect_mult=None,
+                       desired_min_tx=None,
+                       required_min_rx=None):
+        if desired_min_tx:
+            self._desired_min_tx = desired_min_tx
+        if required_min_rx:
+            self._required_min_rx = required_min_rx
+        if detect_mult:
+            self._detect_mult = detect_mult
+        bfd_key_id = self._bfd_key_id if self._sha1_key else None
+        conf_key_id = self._sha1_key.conf_key_id if self._sha1_key else None
+        is_authenticated = True if self._sha1_key else False
+        self.test.vapi.bfd_udp_upd(sw_if_index=self._interface.sw_if_index,
+                                   desired_min_tx=self.desired_min_tx,
+                                   required_min_rx=self.required_min_rx,
+                                   detect_mult=self.detect_mult,
+                                   local_addr=self.local_addr,
+                                   peer_addr=self.peer_addr,
+                                   bfd_key_id=bfd_key_id,
+                                   conf_key_id=conf_key_id,
+                                   is_authenticated=is_authenticated)
+        self._test.registry.register(self, self.test.logger)
+
     def query_vpp_config(self):
         session = self.get_bfd_udp_session_dump_entry()
         return session is not None
index e6a710d..7a444cb 100644 (file)
@@ -142,6 +142,34 @@ class BFDAPITestCase(VppTestCase):
                           "required min receive interval")
         self.assert_equal(session.detect_mult, s.detect_mult, "detect mult")
 
+    def test_upd_bfd(self):
+        """ Create/Modify w/ Update BFD session parameters """
+        session = VppBFDUDPSession(self, self.pg0, self.pg0.remote_ip4,
+                                   desired_min_tx=50000,
+                                   required_min_rx=10000,
+                                   detect_mult=1)
+        session.upd_vpp_config()
+        s = session.get_bfd_udp_session_dump_entry()
+        self.assert_equal(session.desired_min_tx,
+                          s.desired_min_tx,
+                          "desired min transmit interval")
+        self.assert_equal(session.required_min_rx,
+                          s.required_min_rx,
+                          "required min receive interval")
+
+        self.assert_equal(session.detect_mult, s.detect_mult, "detect mult")
+        session.upd_vpp_config(desired_min_tx=session.desired_min_tx * 2,
+                               required_min_rx=session.required_min_rx * 2,
+                               detect_mult=session.detect_mult * 2)
+        s = session.get_bfd_udp_session_dump_entry()
+        self.assert_equal(session.desired_min_tx,
+                          s.desired_min_tx,
+                          "desired min transmit interval")
+        self.assert_equal(session.required_min_rx,
+                          s.required_min_rx,
+                          "required min receive interval")
+        self.assert_equal(session.detect_mult, s.detect_mult, "detect mult")
+
     def test_add_sha1_keys(self):
         """ add SHA1 keys """
         key_count = 10