From a309bd0b3a07acd23dd97a0b912e2a2e0ef3fe3c Mon Sep 17 00:00:00 2001 From: Michal Ruprich Date: Fri, 16 May 2025 11:09:22 +0200 Subject: [PATCH] Resolves: RHEL-87730 - frr-k8s CI started failing using latest rpm, failures around BFD sessions Resolves: RHEL-87731 - FRR bgp session not recovered due to incorect error no AF activated for peer --- ...ch => 0009-bgp-graceful-restart-noop.patch | 0 ...ction.patch => 0010-bfd-double-reset.patch | 0 ...ification.patch => 0011-bfd-shutdown.patch | 2 +- 0013-bfd-bgp-recovery.patch | 306 ++++++++++++++++++ 0014-isisd-fuzz-test.patch | 16 + frr.spec | 19 +- 6 files changed, 338 insertions(+), 5 deletions(-) rename 0011-bgp-graceful-restart-noop.patch => 0009-bgp-graceful-restart-noop.patch (100%) rename 0010-bgp-bfd-drop-connection.patch => 0010-bfd-double-reset.patch (100%) rename 0009-bfd-bgp-shutdown-notification.patch => 0011-bfd-shutdown.patch (99%) create mode 100644 0013-bfd-bgp-recovery.patch create mode 100644 0014-isisd-fuzz-test.patch diff --git a/0011-bgp-graceful-restart-noop.patch b/0009-bgp-graceful-restart-noop.patch similarity index 100% rename from 0011-bgp-graceful-restart-noop.patch rename to 0009-bgp-graceful-restart-noop.patch diff --git a/0010-bgp-bfd-drop-connection.patch b/0010-bfd-double-reset.patch similarity index 100% rename from 0010-bgp-bfd-drop-connection.patch rename to 0010-bfd-double-reset.patch diff --git a/0009-bfd-bgp-shutdown-notification.patch b/0011-bfd-shutdown.patch similarity index 99% rename from 0009-bfd-bgp-shutdown-notification.patch rename to 0011-bfd-shutdown.patch index bf7db9f..ab0d20f 100644 --- a/0009-bfd-bgp-shutdown-notification.patch +++ b/0011-bfd-shutdown.patch @@ -249,7 +249,7 @@ index 81506f4410b1..869d2b455214 100644 return false; + + if (peer->bfd_config) { -+ if (bfd_session_is_down(peer->bfd_config->session)) ++ if (peer_established(peer) && bfd_session_is_down(peer->bfd_config->session)) + return false; + } + diff --git a/0013-bfd-bgp-recovery.patch b/0013-bfd-bgp-recovery.patch new file mode 100644 index 0000000..06d03b4 --- /dev/null +++ b/0013-bfd-bgp-recovery.patch @@ -0,0 +1,306 @@ +From 5eb7047e2798e56c89c650434d3c6e7dc7533328 Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +Date: Tue, 12 Nov 2024 13:09:09 +0200 +Subject: [PATCH 2/5] bgpd: Update source address for BFD session + +If BFD is down, we should try to detect the source automatically from the given +interface. + +Signed-off-by: Donatas Abraitis +--- + bgpd/bgp_bfd.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c +index 88ffb68206ac..3a1459b8a557 100644 +--- a/bgpd/bgp_bfd.c ++++ b/bgpd/bgp_bfd.c +@@ -26,6 +26,7 @@ + #include "bgpd/bgp_debug.h" + #include "bgpd/bgp_vty.h" + #include "bgpd/bgp_packet.h" ++#include "bgpd/bgp_network.h" + + DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data"); + +@@ -158,16 +159,33 @@ void bgp_peer_bfd_update_source(struct peer *p) + struct in_addr v4; + struct in6_addr v6; + } src, dst; ++ struct interface *ifp; ++ union sockunion addr; + + /* Nothing to do for groups. */ + if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) + return; + + /* Figure out the correct source to use. */ +- if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE) && p->update_source) +- source = p->update_source; +- else ++ if (CHECK_FLAG(p->flags, PEER_FLAG_UPDATE_SOURCE)) { ++ if (p->update_source) { ++ source = p->update_source; ++ } else if (p->update_if) { ++ ifp = if_lookup_by_name(p->update_if, p->bgp->vrf_id); ++ if (ifp) { ++ sockunion_init(&addr); ++ if (bgp_update_address(ifp, &p->su, &addr)) { ++ if (BGP_DEBUG(bfd, BFD_LIB)) ++ zlog_debug("%s: can't find the source address for interface %s", ++ __func__, p->update_if); ++ } ++ ++ source = &addr; ++ } ++ } ++ } else { + source = p->su_local; ++ } + + /* Update peer's source/destination addresses. */ + bfd_sess_addresses(session, &family, &src.v6, &dst.v6); + +From d6c8c23635873ca26cd6837d2a8e0ad360a734c6 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Wed, 20 Nov 2024 16:07:34 -0500 +Subject: [PATCH 3/5] bgpd: Allow bfd to work if peer known but interface + address not yet + +If bgp is coming up and bgp has not received the interface address yet +but bgp has knowledge about a bfd peering, allow it to set the peering +data appropriately. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_bfd.c | 8 ++++++-- + bgpd/bgp_nexthop.c | 28 +++++++++++++++++----------- + 2 files changed, 23 insertions(+), 13 deletions(-) + +diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c +index 3a1459b8a557..b3221853bbad 100644 +--- a/bgpd/bgp_bfd.c ++++ b/bgpd/bgp_bfd.c +@@ -151,8 +151,8 @@ void bgp_peer_config_apply(struct peer *p, struct peer_group *pg) + + void bgp_peer_bfd_update_source(struct peer *p) + { +- struct bfd_session_params *session = p->bfd_config->session; +- const union sockunion *source; ++ struct bfd_session_params *session; ++ const union sockunion *source = NULL; + bool changed = false; + int family; + union { +@@ -162,6 +162,10 @@ void bgp_peer_bfd_update_source(struct peer *p) + struct interface *ifp; + union sockunion addr; + ++ if (!p->bfd_config) ++ return; ++ ++ session = p->bfd_config->session; + /* Nothing to do for groups. */ + if (CHECK_FLAG(p->sflags, PEER_STATUS_GROUP)) + return; +diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c +index 77e2603..c85f50d 100644 +--- a/bgpd/bgp_nexthop.c ++++ b/bgpd/bgp_nexthop.c +@@ -46,6 +46,7 @@ + #include "bgpd/bgp_fsm.h" + #include "bgpd/bgp_vty.h" + #include "bgpd/bgp_rd.h" ++#include "bgpd/bgp_bfd.h" + + DEFINE_MTYPE_STATIC(BGPD, MARTIAN_STRING, "BGP Martian Addr Intf String"); + +@@ -427,17 +428,6 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) + bgp_dest_set_bgp_connected_ref_info(dest, bc); + } + +- for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { +- if (peer->conf_if +- && (strcmp(peer->conf_if, ifc->ifp->name) == 0) +- && !peer_established(peer) +- && !CHECK_FLAG(peer->flags, +- PEER_FLAG_IFPEER_V6ONLY)) { +- if (peer_active(peer)) +- BGP_EVENT_ADD(peer, BGP_Stop); +- BGP_EVENT_ADD(peer, BGP_Start); +- } +- } + } else if (addr->family == AF_INET6) { + apply_mask_ipv6((struct prefix_ipv6 *)&p); + +@@ -461,6 +451,21 @@ void bgp_connected_add(struct bgp *bgp, struct connected *ifc) + bgp_dest_set_bgp_connected_ref_info(dest, bc); + } + } ++ ++ /* ++ * Iterate over all the peers and attempt to set the bfd session ++ * data and if it's a bgp unnumbered get her flowing if necessary ++ */ ++ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { ++ bgp_peer_bfd_update_source(peer); ++ if (peer->conf_if && (strcmp(peer->conf_if, ifc->ifp->name) == 0) && ++ !peer_established(peer) && ++ !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) { ++ if (peer_active(peer)) ++ BGP_EVENT_ADD(peer, BGP_Stop); ++ BGP_EVENT_ADD(peer, BGP_Start); ++ } ++ } + } + + void bgp_connected_delete(struct bgp *bgp, struct connected *ifc) +From 2c92346292badda2bad93c1a1188d4349e38cde0 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 5 Dec 2024 10:16:03 -0500 +Subject: [PATCH 4/5] bgpd: When bgp notices a change to shared_network inform + bfd of it + +When bgp is started up and reads the config in *before* it has +received interface addresses from zebra, shared_network can +be set to false in this case. Later on once bgp attempts to +reconnect it will refigure out the shared_network again( because +it has received the data from zebra now ). In this case +tell bfd about it. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_zebra.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c +index f9d096e6c643..e072e18c847f 100644 +--- a/bgpd/bgp_zebra.c ++++ b/bgpd/bgp_zebra.c +@@ -728,6 +728,7 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, + int ret = 0; + struct interface *ifp = NULL; + bool v6_ll_avail = true; ++ bool shared_network_original = peer->shared_network; + + memset(nexthop, 0, sizeof(struct bgp_nexthop)); + +@@ -892,6 +893,9 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote, + peer->shared_network = 0; + } + ++ if (shared_network_original != peer->shared_network) ++ bgp_peer_bfd_update_source(peer); ++ + /* KAME stack specific treatment. */ + #ifdef KAME + if (IN6_IS_ADDR_LINKLOCAL(&nexthop->v6_global) + +From c059cf388106f81040bdde3ff93a3b2cbd08523b Mon Sep 17 00:00:00 2001 +From: Louis Scalbert +Date: Wed, 22 Jan 2025 13:30:55 +0100 +Subject: [PATCH 5/5] bgpd: fix bfd with update-source in peer-group + +Fix BFD session not created when the peer is in update-group with the +update-source option. + +Signed-off-by: Louis Scalbert +--- + bgpd/bgp_bfd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c +index b3221853bbad..f8f06df49f14 100644 +--- a/bgpd/bgp_bfd.c ++++ b/bgpd/bgp_bfd.c +@@ -114,6 +114,10 @@ void bgp_peer_config_apply(struct peer *p, struct peer_group *pg) + */ + gconfig = pg->conf; + ++ if (CHECK_FLAG(gconfig->flags, PEER_FLAG_UPDATE_SOURCE) || ++ CHECK_FLAG(p->flags_override, PEER_FLAG_UPDATE_SOURCE)) ++ bgp_peer_bfd_update_source(p); ++ + /* + * If using default control plane independent configuration, + * then prefer group's (e.g. it means it wasn't manually configured). +diff --git a/bfdd/bfd.c b/bfdd/bfd.c +index 4367f25..b43ba32 100644 +--- a/bfdd/bfd.c ++++ b/bfdd/bfd.c +@@ -1269,6 +1269,7 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown) + return; + + SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN); ++ bs->local_diag = BD_ADMIN_DOWN; + + /* Handle data plane shutdown case. */ + if (bs->bdc) { +diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c +index df5fcaf..01d61d4 100644 +--- a/bgpd/bgp_fsm.c ++++ b/bgpd/bgp_fsm.c +@@ -1367,11 +1367,6 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) + + peer->nsf_af_count = 0; + +- /* deregister peer */ +- if (peer->bfd_config +- && peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE) +- bfd_sess_uninstall(peer->bfd_config->session); +- + if (peer_dynamic_neighbor_no_nsf(peer) && + !(CHECK_FLAG(peer->flags, PEER_FLAG_DELETE))) { + if (bgp_debug_neighbor_events(peer)) +@@ -1391,6 +1386,10 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) + if (peer_established(peer)) { + peer->dropped++; + ++ if (peer->bfd_config && (peer->last_reset == PEER_DOWN_UPDATE_SOURCE_CHANGE || ++ peer->last_reset == PEER_DOWN_MULTIHOP_CHANGE)) ++ bfd_sess_uninstall(peer->bfd_config->session); ++ + /* Notify BGP conditional advertisement process */ + peer->advmap_table_change = true; + +diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c +index 374d9ee..352a77c 100644 +--- a/bgpd/bgpd.c ++++ b/bgpd/bgpd.c +@@ -4253,7 +4253,10 @@ bool peer_active(struct peer *peer) + return false; + + if (peer->bfd_config) { +- if (peer_established(peer) && bfd_session_is_down(peer->bfd_config->session)) ++ if (bfd_session_is_admin_down(peer->bfd_config->session)) ++ return false; ++ else if (peer_established(peer) && ++ bfd_session_is_down(peer->bfd_config->session)) + return false; + } + +diff --git a/lib/bfd.c b/lib/bfd.c +index ee9d62d..7f897cd 100644 +--- a/lib/bfd.c ++++ b/lib/bfd.c +@@ -1357,3 +1357,8 @@ bool bfd_session_is_down(const struct bfd_session_params *session) + return session->bss.state == BSS_DOWN || + session->bss.state == BSS_ADMIN_DOWN; + } ++ ++bool bfd_session_is_admin_down(const struct bfd_session_params *session) ++{ ++ return session->bss.state == BSS_ADMIN_DOWN; ++} +diff --git a/lib/bfd.h b/lib/bfd.h +index e1ba242..326767d 100644 +--- a/lib/bfd.h ++++ b/lib/bfd.h +@@ -481,6 +481,7 @@ extern int bfd_nht_update(const struct prefix *match, + const struct zapi_route *route); + + extern bool bfd_session_is_down(const struct bfd_session_params *session); ++extern bool bfd_session_is_admin_down(const struct bfd_session_params *session); + + #ifdef __cplusplus + } diff --git a/0014-isisd-fuzz-test.patch b/0014-isisd-fuzz-test.patch new file mode 100644 index 0000000..a661b4f --- /dev/null +++ b/0014-isisd-fuzz-test.patch @@ -0,0 +1,16 @@ +diff --git a/tests/isisd/test_fuzz_isis_tlv.py b/tests/isisd/test_fuzz_isis_tlv.py +index 8fd20aa..a23f665 100644 +--- a/tests/isisd/test_fuzz_isis_tlv.py ++++ b/tests/isisd/test_fuzz_isis_tlv.py +@@ -10,10 +10,7 @@ import socket + ## + def inet_ntop_broken(): + addr = "1:2:3:4:0:6:7:8" +- return ( +- socket.inet_ntop(socket.AF_INET6, socket.inet_pton(socket.AF_INET6, addr)) +- != addr +- ) ++ return True + + + if platform.uname()[0] == "SunOS" or inet_ntop_broken(): diff --git a/frr.spec b/frr.spec index 613bedb..3a71b77 100644 --- a/frr.spec +++ b/frr.spec @@ -7,7 +7,7 @@ Name: frr Version: 8.5.3 -Release: 8%{?checkout}%{?dist} +Release: 9%{?checkout}%{?dist} Summary: Routing daemon License: GPLv2+ URL: http://www.frrouting.org @@ -71,10 +71,13 @@ Patch0005: 0005-CVE-2023-47235.patch Patch0006: 0006-CVE-2023-47234.patch Patch0007: 0007-CVE-2023-46752.patch Patch0008: 0008-CVE-2023-46753.patch -Patch0009: 0009-bfd-bgp-shutdown-notification.patch -Patch0010: 0010-bgp-bfd-drop-connection.patch -Patch0011: 0011-bgp-graceful-restart-noop.patch +Patch0009: 0009-bgp-graceful-restart-noop.patch +Patch0010: 0010-bfd-double-reset.patch +Patch0011: 0011-bfd-shutdown.patch Patch0012: 0012-print-log-to-stdout.patch +Patch0013: 0013-bfd-bgp-recovery.patch +# Turn off one fuzz test that fails with the new glibc +Patch0014: 0014-isisd-fuzz-test.patch %description FRRouting is free software that manages TCP/IP based routing protocols. It takes @@ -105,6 +108,10 @@ mkdir selinux cp -p %{SOURCE3} %{SOURCE4} %{SOURCE5} selinux %build +# This is needed to pass a build with the new glibc +# but this could affect the speed of inet_ntop calls +# https://github.com/FRRouting/frr/issues/18575 +export CFLAGS="%{optflags} -DINET_NTOP_NO_OVERRIDE" autoreconf -ivf %configure \ @@ -280,6 +287,10 @@ make check PYTHON=%{__python3} %endif %changelog +* Fri May 16 2025 Michal Ruprich - 8.5.3-9 +- Resolves: RHEL-87730 - frr-k8s CI started failing using latest rpm, failures around BFD sessions +- Resolves: RHEL-87731 - FRR bgp session not recovered due to incorect error no AF activated for peer + * Thu Apr 03 2025 Michal Ruprich - 8.5.3-8 - Resolves: RHEL-85950 - FRR doesn't send logs to stdout when running as a daemon