From 63f2c7d70136761e24b19cca1f09d9cbdde66b69 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 9 Feb 2022 13:47:29 +0000 Subject: bfd: Add an update API that has create new or modify existing semantics Type: improvement helps keep the agents stateless Signed-off-by: Neale Ranns Change-Id: I3588f13c081e24f5a8083b490eb02856361e4ccb --- src/vnet/bfd/bfd.api | 20 +++++++++++ src/vnet/bfd/bfd_api.c | 21 ++++++++++++ src/vnet/bfd/bfd_api.h | 9 +++++ src/vnet/bfd/bfd_udp.c | 92 ++++++++++++++++++++++++++++++++++++++------------ test/bfd.py | 24 +++++++++++++ test/test_bfd.py | 28 +++++++++++++++ 6 files changed, 172 insertions(+), 22 deletions(-) diff --git a/src/vnet/bfd/bfd.api b/src/vnet/bfd/bfd.api index f53cc7630fd..3957a94f6a6 100644 --- a/src/vnet/bfd/bfd.api +++ b/src/vnet/bfd/bfd.api @@ -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 diff --git a/src/vnet/bfd/bfd_api.c b/src/vnet/bfd/bfd_api.c index 0ae8508f865..4d76f71fd9f 100644 --- a/src/vnet/bfd/bfd_api.c +++ b/src/vnet/bfd/bfd_api.c @@ -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) { diff --git a/src/vnet/bfd/bfd_api.h b/src/vnet/bfd/bfd_api.h index 2a6c69b78b6..f051e6b679c 100644 --- a/src/vnet/bfd/bfd_api.h +++ b/src/vnet/bfd/bfd_api.h @@ -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 */ diff --git a/src/vnet/bfd/bfd_udp.c b/src/vnet/bfd/bfd_udp.c index 333b321f3c1..a58d9e2e1ca 100644 --- a/src/vnet/bfd/bfd_udp.c +++ b/src/vnet/bfd/bfd_udp.c @@ -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; diff --git a/test/bfd.py b/test/bfd.py index 9d44425ec9f..bbfa5945593 100644 --- a/test/bfd.py +++ b/test/bfd.py @@ -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 diff --git a/test/test_bfd.py b/test/test_bfd.py index e6a710d7bf9..7a444cb3caf 100644 --- a/test/test_bfd.py +++ b/test/test_bfd.py @@ -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 -- cgit 1.2.3-korg