From ac506cb20e02dcc9954ed47c74b141252ceda2e7 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 21 Apr 2021 15:27:20 -0300 Subject: [PATCH] lib: BFD session handling improvement Don't uninstall sessions if the address, interface, VRF or TTL didn't change. Update the library documentation to make it clear to other developers. Signed-off-by: Rafael Zalamena --- lib/bfd.c | 41 +++++++++++++++++++++++++++++++++++++++++ lib/bfd.h | 45 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/lib/bfd.c b/lib/bfd.c index bf3eaa32db..5ca5840c5c 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -795,9 +795,33 @@ void bfd_sess_free(struct bfd_session_params **bsp) XFREE(MTYPE_BFD_INFO, (*bsp)); } +static bool bfd_sess_address_changed(const struct bfd_session_params *bsp, + uint32_t family, + const struct in6_addr *src, + const struct in6_addr *dst) +{ + size_t addrlen; + + if (bsp->args.family != family) + return true; + + addrlen = (family == AF_INET) ? sizeof(struct in_addr) + : sizeof(struct in6_addr); + if ((src == NULL && memcmp(&bsp->args.src, &i6a_zero, addrlen)) + || (src && memcmp(src, &bsp->args.src, addrlen)) + || memcmp(dst, &bsp->args.dst, addrlen)) + return true; + + return false; +} + void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, struct in_addr *src, struct in_addr *dst) { + if (!bfd_sess_address_changed(bsp, AF_INET, (struct in6_addr *)src, + (struct in6_addr *)dst)) + return; + /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); @@ -818,6 +842,10 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, struct in6_addr *src, struct in6_addr *dst) { + if (!bfd_sess_address_changed(bsp, AF_INET, (struct in6_addr *)src, + (struct in6_addr *)dst)) + return; + /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); @@ -835,6 +863,10 @@ void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, void bfd_sess_set_interface(struct bfd_session_params *bsp, const char *ifname) { + if ((ifname == NULL && bsp->args.ifnamelen == 0) + || (ifname && strcmp(bsp->args.ifname, ifname) == 0)) + return; + /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); @@ -868,6 +900,9 @@ void bfd_sess_set_profile(struct bfd_session_params *bsp, const char *profile) void bfd_sess_set_vrf(struct bfd_session_params *bsp, vrf_id_t vrf_id) { + if (bsp->args.vrf_id == vrf_id) + return; + /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); @@ -878,6 +913,9 @@ void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl) { assert(min_ttl != 0); + if (bsp->args.ttl == ((BFD_SINGLE_HOP_TTL + 1) - min_ttl)) + return; + /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); @@ -889,6 +927,9 @@ void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl) void bfd_sess_set_hop_count(struct bfd_session_params *bsp, uint8_t min_ttl) { + if (bsp->args.ttl == min_ttl) + return; + /* If already installed, remove the old setting. */ _bfd_sess_remove(bsp); diff --git a/lib/bfd.h b/lib/bfd.h index 230fde5e1f..113f167d3b 100644 --- a/lib/bfd.h +++ b/lib/bfd.h @@ -169,7 +169,7 @@ typedef void (*bsp_status_update)(struct bfd_session_params *bsp, /** * Allocates and initializes the session parameters. * - * \param updatedb status update notification callback. + * \param updatecb status update notification callback. * \param args application independent data. * * \returns pointer to configuration storage. @@ -187,6 +187,10 @@ void bfd_sess_free(struct bfd_session_params **bsp); /** * Set the local and peer address of the BFD session. * + * NOTE: + * If the address changed the session is removed and must be installed again + * with `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param src local address (optional, can be `NULL`). * \param dst remote address (mandatory). @@ -197,6 +201,10 @@ void bfd_sess_set_ipv4_addrs(struct bfd_session_params *bsp, /** * Set the local and peer address of the BFD session. * + * NOTE: + * If the address changed the session is removed and must be installed again + * with `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param src local address (optional, can be `NULL`). * \param dst remote address (mandatory). @@ -207,6 +215,10 @@ void bfd_sess_set_ipv6_addrs(struct bfd_session_params *bsp, /** * Configure the BFD session interface. * + * NOTE: + * If the interface changed the session is removed and must be installed again + * with `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param ifname interface name (or `NULL` to remove it). */ @@ -215,6 +227,9 @@ void bfd_sess_set_interface(struct bfd_session_params *bsp, const char *ifname); /** * Configure the BFD session profile name. * + * NOTE: + * Session profile will only change after a `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param profile profile name (or `NULL` to remove it). */ @@ -223,6 +238,10 @@ void bfd_sess_set_profile(struct bfd_session_params *bsp, const char *profile); /** * Configure the BFD session VRF. * + * NOTE: + * If the VRF changed the session is removed and must be installed again + * with `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param vrf_id the VRF identification number. */ @@ -231,6 +250,10 @@ void bfd_sess_set_vrf(struct bfd_session_params *bsp, vrf_id_t vrf_id); /** * Configure the BFD session single/multi hop setting. * + * NOTE: + * If the TTL changed the session is removed and must be installed again + * with `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param min_ttl minimum TTL value expected (255 for single hop, 254 for * multi hop with single hop, 253 for multi hop with two hops @@ -252,6 +275,10 @@ void bfd_sess_set_mininum_ttl(struct bfd_session_params *bsp, uint8_t min_ttl); * Instead of receiving the minimum expected TTL, it receives the amount of * hops the protocol will jump. * + * NOTE: + * If the TTL changed the session is removed and must be installed again + * with `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param min_ttl minimum amount of hops expected (1 for single hop, 2 or * more for multi hop). @@ -261,6 +288,9 @@ void bfd_sess_set_hop_count(struct bfd_session_params *bsp, uint8_t min_ttl); /** * Configure the BFD session to set the Control Plane Independent bit. * + * NOTE: + * Session CPI bit will only change after a `bfd_sess_install`. + * * \param bsp BFD session parameters. * \param enable BFD Control Plane Independent state. */ @@ -272,6 +302,11 @@ void bfd_sess_set_cbit(struct bfd_session_params *bsp, bool enable); * Configures the BFD session timers to use. This is specially useful with * `ptm-bfd` which does not support timers. * + * NOTE: + * Session timers will only apply if the session has not been created yet. + * If the session is already installed you must uninstall and install again + * to take effect. + * * \param bsp BFD session parameters. * \param detection_multiplier the detection multiplier value. * \param min_rx minimum required receive period. @@ -284,6 +319,10 @@ void bfd_sess_set_timers(struct bfd_session_params *bsp, /** * Installs or updates the BFD session based on the saved session arguments. * + * NOTE: + * This function has a delayed effect: it will only install/update after + * all northbound/CLI command batch finishes. + * * \param bsp session parameters. */ void bfd_sess_install(struct bfd_session_params *bsp); @@ -291,6 +330,10 @@ void bfd_sess_install(struct bfd_session_params *bsp); /** * Uninstall the BFD session based on the saved session arguments. * + * NOTE: + * This function uninstalls the session immediately (if installed) and cancels + * any previous `bfd_sess_install` calls. + * * \param bsp session parameters. */ void bfd_sess_uninstall(struct bfd_session_params *bsp); -- 2.39.5