From 229dc8b434ebacc1638a5d91e4a0dc8903277734 Mon Sep 17 00:00:00 2001 From: Michal Ruprich Date: Mon, 8 Dec 2025 16:40:20 +0100 Subject: [PATCH] Resolves: RHEL-118620 - Rebase FRR in to version 10.4.1 --- .gitignore | 2 +- 0002-enable-openssl.patch | 2 +- 0006-noprefixroute-network-manager.patch | 487 ----------------------- 0007-CVE-2024-44070.patch | 48 --- 0008-bfd-bgp-shutdown-notification.patch | 285 ------------- 0009-bgp-bfd-drop-connection.patch | 69 ---- 0010-frr-reload-escape-strings.patch | 245 ------------ 0011-bfd-peer-established.patch | 42 -- frr.spec | 15 +- frr.te | 3 + remove-babeld-ldpd.sh | 16 + sources | 3 +- 12 files changed, 29 insertions(+), 1188 deletions(-) delete mode 100644 0006-noprefixroute-network-manager.patch delete mode 100644 0007-CVE-2024-44070.patch delete mode 100644 0008-bfd-bgp-shutdown-notification.patch delete mode 100644 0009-bgp-bfd-drop-connection.patch delete mode 100644 0010-frr-reload-escape-strings.patch delete mode 100644 0011-bfd-peer-established.patch create mode 100644 remove-babeld-ldpd.sh diff --git a/.gitignore b/.gitignore index a258b7f..3f9981a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ /frr-7.1.tar.gz /frr-7.2.tar.gz /frr-7.3.tar.gz -/remove-babeld-ldpd.sh /frr-7.3.1.tar.gz /frr-7.4.tar.gz /frr-7.5.tar.gz @@ -20,3 +19,4 @@ /frr-9.0.1.tar.gz /frr-9.1.tar.gz /frr-10.1.tar.gz +/frr-10.4.1.tar.gz diff --git a/0002-enable-openssl.patch b/0002-enable-openssl.patch index 5101f06..928609f 100644 --- a/0002-enable-openssl.patch +++ b/0002-enable-openssl.patch @@ -24,8 +24,8 @@ index 0b7af18..0533e24 100644 lib/log_vty.h \ - lib/md5.h \ lib/memory.h \ - lib/mgmt.pb-c.h \ lib/mgmt_be_client.h \ + lib/mgmt_defines.h \ @@ -191,7 +190,6 @@ pkginclude_HEADERS += \ lib/route_opaque.h \ lib/sbuf.h \ diff --git a/0006-noprefixroute-network-manager.patch b/0006-noprefixroute-network-manager.patch deleted file mode 100644 index ec207e5..0000000 --- a/0006-noprefixroute-network-manager.patch +++ /dev/null @@ -1,487 +0,0 @@ -From f450e1cda41f1b7576094a0b3017ba9849cd55ae Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 7 Jun 2024 12:30:59 -0400 -Subject: [PATCH 1/5] zebra: Make p and src_p const for rib_delete - -The prefix'es p and src_p are not const. Let's make -them so. Useful to signal that we will not change this -data. - -Signed-off-by: Donald Sharp ---- - zebra/rib.h | 2 +- - zebra/zebra_rib.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/zebra/rib.h b/zebra/rib.h -index 84ea766c4733..7f4e3949e02d 100644 ---- a/zebra/rib.h -+++ b/zebra/rib.h -@@ -395,7 +395,7 @@ extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p, - - extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, - unsigned short instance, uint32_t flags, -- struct prefix *p, struct prefix_ipv6 *src_p, -+ const struct prefix *p, const struct prefix_ipv6 *src_p, - const struct nexthop *nh, uint32_t nhe_id, - uint32_t table_id, uint32_t metric, uint8_t distance, - bool fromkernel); -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 59190e9dd330..c1bd61e1db31 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -4393,8 +4393,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, - } - - void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, -- unsigned short instance, uint32_t flags, struct prefix *p, -- struct prefix_ipv6 *src_p, const struct nexthop *nh, -+ unsigned short instance, uint32_t flags, const struct prefix *p, -+ const struct prefix_ipv6 *src_p, const struct nexthop *nh, - uint32_t nhe_id, uint32_t table_id, uint32_t metric, - uint8_t distance, bool fromkernel) - { - -From bdfccf69fa128c51c45bbd3528788f72ac17d854 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 7 Jun 2024 12:56:35 -0400 -Subject: [PATCH 2/5] zebra: Expose rib_update_handle_vrf_all - -This function will be used on interface down -events to allow for kernel routes to be cleaned -up. - -Signed-off-by: Donald Sharp ---- - zebra/rib.h | 2 ++ - zebra/zebra_rib.c | 2 +- - 2 files changed, 3 insertions(+), 1 deletion(-) - -diff --git a/zebra/rib.h b/zebra/rib.h -index 7f4e3949e02d..8792fb7908ac 100644 ---- a/zebra/rib.h -+++ b/zebra/rib.h -@@ -477,6 +477,8 @@ extern uint8_t route_distance(int type); - extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq, - bool rt_delete); - -+extern void rib_update_handle_vrf_all(enum rib_update_event event, int rtype); -+ - /* - * rib_find_rn_from_ctx - * -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index c1bd61e1db31..649450b5c63c 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -4543,7 +4543,7 @@ void rib_update_table(struct route_table *table, enum rib_update_event event, - } - } - --static void rib_update_handle_vrf_all(enum rib_update_event event, int rtype) -+void rib_update_handle_vrf_all(enum rib_update_event event, int rtype) - { - struct zebra_router_table *zrt; - - -From d528c02a204086da0d542d5655b8724de681a65c Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 7 Jun 2024 13:50:07 -0400 -Subject: [PATCH 3/5] zebra: Handle kernel routes appropriately - -Current code intentionally ignores kernel routes. Modify -zebra to allow these routes to be read in on linux. Also -modify zebra to look to see if a route should be treated -as a connected and mark it as such. - -Additionally this should properly handle some of the issues -being seen with NOPREFIXROUTE. - -Signed-off-by: Donald Sharp ---- - zebra/interface.c | 2 + - zebra/rib.h | 1 + - zebra/rt_netlink.c | 2 - - zebra/zebra_rib.c | 105 +++++++++++++++++++++++++++++++++++++++------ - 4 files changed, 96 insertions(+), 14 deletions(-) - -diff --git a/zebra/interface.c b/zebra/interface.c -index 03b710e1a0f9..d146004781a5 100644 ---- a/zebra/interface.c -+++ b/zebra/interface.c -@@ -1058,6 +1058,8 @@ void if_down(struct interface *ifp) - - /* Delete all neighbor addresses learnt through IPv6 RA */ - if_down_del_nbr_connected(ifp); -+ -+ rib_update_handle_vrf_all(RIB_UPDATE_INTERFACE_DOWN, ZEBRA_ROUTE_KERNEL); - } - - void if_refresh(struct interface *ifp) -diff --git a/zebra/rib.h b/zebra/rib.h -index 8792fb7908ac..cd6efbfb36dd 100644 ---- a/zebra/rib.h -+++ b/zebra/rib.h -@@ -326,6 +326,7 @@ typedef struct rib_tables_iter_t_ { - - /* Events/reasons triggering a RIB update. */ - enum rib_update_event { -+ RIB_UPDATE_INTERFACE_DOWN, - RIB_UPDATE_KERNEL, - RIB_UPDATE_RMAP_CHANGE, - RIB_UPDATE_OTHER, -diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index c22145be693b..ddcb83cd8ce7 100644 ---- a/zebra/rt_netlink.c -+++ b/zebra/rt_netlink.c -@@ -799,8 +799,6 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, - return 0; - if (rtm->rtm_protocol == RTPROT_REDIRECT) - return 0; -- if (rtm->rtm_protocol == RTPROT_KERNEL) -- return 0; - - selfroute = is_selfroute(rtm->rtm_protocol); - -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 649450b5c63c..2d6c5148833a 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -1619,6 +1619,10 @@ static bool rib_compare_routes(const struct route_entry *re1, - * v6 link-locals, and we also support multiple addresses in the same - * subnet on a single interface. - */ -+ if (re1->type == ZEBRA_ROUTE_CONNECT && -+ (re1->nhe->nhg.nexthop->ifindex == re2->nhe->nhg.nexthop->ifindex)) -+ return true; -+ - if (re1->type != ZEBRA_ROUTE_CONNECT && re1->type != ZEBRA_ROUTE_LOCAL) - return true; - -@@ -2863,10 +2867,11 @@ static void process_subq_early_route_add(struct zebra_early_route *ere) - - /* Link new re to node.*/ - if (IS_ZEBRA_DEBUG_RIB) { -- rnode_debug( -- rn, re->vrf_id, -- "Inserting route rn %p, re %p (%s) existing %p, same_count %d", -- rn, re, zebra_route_string(re->type), same, same_count); -+ rnode_debug(rn, re->vrf_id, -+ "Inserting route rn %p, re %p (%s/%s/%s) existing %p, same_count %d", -+ rn, re, zebra_route_string(re->type), -+ afi2str(ere->afi), safi2str(ere->safi), same, -+ same_count); - - if (IS_ZEBRA_DEBUG_RIB_DETAILED) - route_entry_dump( -@@ -4383,6 +4388,34 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, - nhe.id = re->nhe_id; - - n = zebra_nhe_copy(&nhe, 0); -+ -+ if (re->type == ZEBRA_ROUTE_KERNEL) { -+ struct interface *ifp; -+ struct connected *connected; -+ -+ if (p->family == AF_INET6 && -+ IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) { -+ zebra_nhg_free(n); -+ zebra_rib_route_entry_free(re); -+ return -1; -+ } -+ -+ ifp = if_lookup_prefix(p, re->vrf_id); -+ if (ifp) { -+ connected = connected_lookup_prefix(ifp, p); -+ -+ if (connected && !CHECK_FLAG(connected->flags, -+ ZEBRA_IFA_NOPREFIXROUTE)) { -+ zebra_nhg_free(n); -+ zebra_rib_route_entry_free(re); -+ return -1; -+ } -+ -+ if (ifp->ifindex == ng->nexthop->ifindex) -+ re->type = ZEBRA_ROUTE_CONNECT; -+ } -+ } -+ - ret = rib_add_multipath_nhe(afi, safi, p, src_p, re, n, startup); - - /* In error cases, free the route also */ -@@ -4458,6 +4491,9 @@ static const char *rib_update_event2str(enum rib_update_event event) - const char *ret = "UNKNOWN"; - - switch (event) { -+ case RIB_UPDATE_INTERFACE_DOWN: -+ ret = "RIB_UPDATE_INTERFACE_DOWN"; -+ break; - case RIB_UPDATE_KERNEL: - ret = "RIB_UPDATE_KERNEL"; - break; -@@ -4474,15 +4510,56 @@ static const char *rib_update_event2str(enum rib_update_event event) - return ret; - } - -+/* -+ * We now keep kernel routes, but we don't have any -+ * trigger events for them when they are implicitly -+ * deleted. Since we are already walking the -+ * entire table on a down event let's look at -+ * the few kernel routes we may have -+ */ -+static void -+rib_update_handle_kernel_route_down_possibility(struct route_node *rn, -+ struct route_entry *re) -+{ -+ struct nexthop *nexthop = NULL; -+ bool alive = false; -+ -+ for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) { -+ struct interface *ifp = if_lookup_by_index(nexthop->ifindex, -+ nexthop->vrf_id); -+ -+ if (ifp && if_is_up(ifp)) { -+ alive = true; -+ break; -+ } -+ } -+ -+ if (!alive) { -+ struct rib_table_info *rib_table = srcdest_rnode_table_info(rn); -+ const struct prefix *p; -+ const struct prefix_ipv6 *src_p; -+ -+ srcdest_rnode_prefixes(rn, &p, (const struct prefix **)&src_p); -+ -+ rib_delete(rib_table->afi, rib_table->safi, re->vrf_id, -+ re->type, re->instance, re->flags, p, src_p, NULL, 0, -+ re->table, re->metric, re->distance, true); -+ } -+} -+ - - /* Schedule route nodes to be processed if they match the type */ --static void rib_update_route_node(struct route_node *rn, int type) -+static void rib_update_route_node(struct route_node *rn, int type, -+ enum rib_update_event event) - { - struct route_entry *re, *next; - bool re_changed = false; - - RNODE_FOREACH_RE_SAFE (rn, re, next) { -- if (type == ZEBRA_ROUTE_ALL || type == re->type) { -+ if (event == RIB_UPDATE_INTERFACE_DOWN && type == re->type && -+ type == ZEBRA_ROUTE_KERNEL) -+ rib_update_handle_kernel_route_down_possibility(rn, re); -+ else if (type == ZEBRA_ROUTE_ALL || type == re->type) { - SET_FLAG(re->status, ROUTE_ENTRY_CHANGED); - re_changed = true; - } -@@ -4522,20 +4599,24 @@ void rib_update_table(struct route_table *table, enum rib_update_event event, - /* - * If we are looking at a route node and the node - * has already been queued we don't -- * need to queue it up again -+ * need to queue it up again, unless it is -+ * an interface down event as that we need -+ * to process this no matter what. - */ -- if (rn->info -- && CHECK_FLAG(rib_dest_from_rnode(rn)->flags, -- RIB_ROUTE_ANY_QUEUED)) -+ if (rn->info && -+ CHECK_FLAG(rib_dest_from_rnode(rn)->flags, -+ RIB_ROUTE_ANY_QUEUED) && -+ event != RIB_UPDATE_INTERFACE_DOWN) - continue; - - switch (event) { -+ case RIB_UPDATE_INTERFACE_DOWN: - case RIB_UPDATE_KERNEL: -- rib_update_route_node(rn, ZEBRA_ROUTE_KERNEL); -+ rib_update_route_node(rn, ZEBRA_ROUTE_KERNEL, event); - break; - case RIB_UPDATE_RMAP_CHANGE: - case RIB_UPDATE_OTHER: -- rib_update_route_node(rn, rtype); -+ rib_update_route_node(rn, rtype, event); - break; - case RIB_UPDATE_MAX: - break; - -From 9bc0cd8241f39e4fd751edfa52c09fae6db2db1c Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 26 Jun 2024 13:21:38 -0400 -Subject: [PATCH 4/5] zebra: Prevent accidental re memory leak in odd case - -There exists a path in rib_add_multipath where if a decision -is made to not use the passed in re, we just drop the memory -instead of freeing it. Let's free it. - -Signed-off-by: Donald Sharp ---- - zebra/zebra_rib.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 2d6c5148833a..b4baee148aef 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -4375,8 +4375,10 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, - return -1; - - /* We either need nexthop(s) or an existing nexthop id */ -- if (ng == NULL && re->nhe_id == 0) -+ if (ng == NULL && re->nhe_id == 0) { -+ zebra_rib_route_entry_free(re); - return -1; -+ } - - /* - * Use a temporary nhe to convey info to the common/main api. - -From 37dd51867f2b98f0fb616fc3cf9922240346fd19 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Thu, 15 Aug 2024 16:02:55 -0400 -Subject: [PATCH 5/5] tests: Add some tests to show new behavior works as - expected - -a) A noprefix address by itself should not create a connected route. - This was pre-existing. -b) A noprefix address with a corresponding route should result in a - connected route. This is how NetworkManager appears to work. - This is new behavior, so a new test. -c) A route is added to the system from someone else. - This is new behavior, so a new test. - -Signed-off-by: Donald Sharp ---- - .../r1/ip_route_connected.json | 24 +++++++++++ - .../r1/ip_route_kernel.json | 24 +++++++++++ - .../test_zebra_multiple_connected.py | 43 +++++++++++++++++++ - 3 files changed, 91 insertions(+) - create mode 100644 tests/topotests/zebra_multiple_connected/r1/ip_route_connected.json - create mode 100644 tests/topotests/zebra_multiple_connected/r1/ip_route_kernel.json - -diff --git a/tests/topotests/zebra_multiple_connected/r1/ip_route_connected.json b/tests/topotests/zebra_multiple_connected/r1/ip_route_connected.json -new file mode 100644 -index 000000000000..db03ce84a6a4 ---- /dev/null -+++ b/tests/topotests/zebra_multiple_connected/r1/ip_route_connected.json -@@ -0,0 +1,24 @@ -+{ -+ "192.168.44.0/24":[ -+ { -+ "prefix":"192.168.44.0/24", -+ "prefixLen":24, -+ "protocol":"connected", -+ "vrfName":"default", -+ "selected":true, -+ "destSelected":true, -+ "distance":0, -+ "metric":0, -+ "installed":true, -+ "table":254, -+ "nexthops":[ -+ { -+ "fib":true, -+ "directlyConnected":true, -+ "interfaceName":"r1-eth1", -+ "active":true -+ } -+ ] -+ } -+ ] -+} -diff --git a/tests/topotests/zebra_multiple_connected/r1/ip_route_kernel.json b/tests/topotests/zebra_multiple_connected/r1/ip_route_kernel.json -new file mode 100644 -index 000000000000..22465cb477d3 ---- /dev/null -+++ b/tests/topotests/zebra_multiple_connected/r1/ip_route_kernel.json -@@ -0,0 +1,24 @@ -+{ -+ "4.5.6.7/32":[ -+ { -+ "prefix":"4.5.6.7/32", -+ "prefixLen":32, -+ "protocol":"kernel", -+ "vrfName":"default", -+ "selected":true, -+ "destSelected":true, -+ "distance":0, -+ "metric":0, -+ "installed":true, -+ "table":254, -+ "nexthops":[ -+ { -+ "fib":true, -+ "directlyConnected":true, -+ "interfaceName":"r1-eth1", -+ "active":true -+ } -+ ] -+ } -+ ] -+} -diff --git a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py -index dc47527c74c2..7dbeb6f1ccb3 100644 ---- a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py -+++ b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py -@@ -19,6 +19,9 @@ - import pytest - import json - from functools import partial -+from lib.topolog import logger -+ -+pytestmark = pytest.mark.random_order(disabled=True) - - # Save the Current Working Directory to find configuration files. - CWD = os.path.dirname(os.path.realpath(__file__)) -@@ -159,6 +162,46 @@ def test_zebra_noprefix_connected(): - assert result, "Connected Route should not have been added" - - -+def test_zebra_noprefix_connected_add(): -+ "Test that a noprefixroute created with a manual route works as expected, this is for NetworkManager" -+ -+ tgen = get_topogen() -+ if tgen.routers_have_failure(): -+ pytest.skip(tgen.errors) -+ -+ router = tgen.gears["r1"] -+ router.run("ip route add 192.168.44.0/24 dev r1-eth1") -+ -+ connected = "{}/{}/ip_route_connected.json".format(CWD, router.name) -+ expected = json.loads(open(connected).read()) -+ -+ test_func = partial( -+ topotest.router_json_cmp, router, "show ip route 192.168.44.0/24 json", expected -+ ) -+ result, _ = topotest.run_and_expect(test_func, None, count=20, wait=1) -+ assert result, "Connected Route should have been added\n{}".format(_) -+ -+ -+def test_zebra_kernel_route_add(): -+ "Test that a random kernel route is properly handled as expected" -+ -+ tgen = get_topogen() -+ if tgen.routers_have_failure(): -+ pytest.skip(tgen.errors) -+ -+ router = tgen.gears["r1"] -+ router.run("ip route add 4.5.6.7/32 dev r1-eth1") -+ -+ kernel = "{}/{}/ip_route_kernel.json".format(CWD, router.name) -+ expected = json.loads(open(kernel).read()) -+ -+ test_func = partial( -+ topotest.router_json_cmp, router, "show ip route 4.5.6.7/32 json", expected -+ ) -+ result, _ = topotest.run_and_expect(test_func, None, count=20, wait=1) -+ assert result, "Connected Route should have been added\n{}".format(_) -+ -+ - if __name__ == "__main__": - args = ["-s"] + sys.argv[1:] - sys.exit(pytest.main(args)) diff --git a/0007-CVE-2024-44070.patch b/0007-CVE-2024-44070.patch deleted file mode 100644 index 89ebf9e..0000000 --- a/0007-CVE-2024-44070.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0998b38e4d61179441f90dd7e7fd6a3a8b7bd8c5 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Wed, 31 Jul 2024 08:35:14 +0300 -Subject: [PATCH] bgpd: Check the actual remaining stream length before taking - TLV value - -``` - 0 0xb50b9f898028 in __sanitizer_print_stack_trace (/home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/.libs/bgpd+0x368028) (BuildId: 3292703ed7958b20076550c967f879db8dc27ca7) - 1 0xb50b9f7ed8e4 in fuzzer::PrintStackTrace() (/home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/.libs/bgpd+0x2bd8e4) (BuildId: 3292703ed7958b20076550c967f879db8dc27ca7) - 2 0xb50b9f7d4d9c in fuzzer::Fuzzer::CrashCallback() (/home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/.libs/bgpd+0x2a4d9c) (BuildId: 3292703ed7958b20076550c967f879db8dc27ca7) - 3 0xe0d12d7469cc (linux-vdso.so.1+0x9cc) (BuildId: 1a77697e9d723fe22246cfd7641b140c427b7e11) - 4 0xe0d12c88f1fc in __pthread_kill_implementation nptl/pthread_kill.c:43:17 - 5 0xe0d12c84a678 in gsignal signal/../sysdeps/posix/raise.c:26:13 - 6 0xe0d12c83712c in abort stdlib/abort.c:79:7 - 7 0xe0d12d214724 in _zlog_assert_failed /home/ubuntu/frr-public/frr_public_private-libfuzzer/lib/zlog.c:789:2 - 8 0xe0d12d1285e4 in stream_get /home/ubuntu/frr-public/frr_public_private-libfuzzer/lib/stream.c:324:3 - 9 0xb50b9f8e47c4 in bgp_attr_encap /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_attr.c:2758:3 - 10 0xb50b9f8dcd38 in bgp_attr_parse /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_attr.c:3783:10 - 11 0xb50b9faf74b4 in bgp_update_receive /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:2383:20 - 12 0xb50b9faf1dcc in bgp_process_packet /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:4075:11 - 13 0xb50b9f8c90d0 in LLVMFuzzerTestOneInput /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_main.c:582:3 -``` - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis ---- - bgpd/bgp_attr.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index 2ed49935e52b..ac5d08b6fe6e 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -2749,6 +2749,14 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args) - args->total); - } - -+ if (STREAM_READABLE(BGP_INPUT(peer)) < sublength) { -+ zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining stream length %zu", -+ sublength, STREAM_READABLE(BGP_INPUT(peer))); -+ return bgp_attr_malformed(args, -+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, -+ args->total); -+ } -+ - /* alloc and copy sub-tlv */ - /* TBD make sure these are freed when attributes are released */ - tlv = XCALLOC(MTYPE_ENCAP_TLV, diff --git a/0008-bfd-bgp-shutdown-notification.patch b/0008-bfd-bgp-shutdown-notification.patch deleted file mode 100644 index ccd1870..0000000 --- a/0008-bfd-bgp-shutdown-notification.patch +++ /dev/null @@ -1,285 +0,0 @@ -From 59f5dd686a324f888602fa4a56f6da90e844103c Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Tue, 11 Jun 2024 11:40:40 +0300 -Subject: [PATCH 1/3] tests: Check if BFD notification is sent and session - remains in down state - -Signed-off-by: Donatas Abraitis ---- - .../r1/bfdd.conf | 4 + - .../r1/bgpd.conf | 2 +- - .../test_bgp_bfd_down_cease_notification.py | 3 + - ...gp_bfd_down_cease_notification_shutdown.py | 122 ++++++++++++++++++ - 4 files changed, 130 insertions(+), 1 deletion(-) - create mode 100644 tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py - -diff --git a/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf b/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf -index 0ae384eb53ca..1033b27c568d 100644 ---- a/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf -+++ b/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf -@@ -1,5 +1,9 @@ - bfd -+ profile r1 -+ exit -+ ! - peer 192.168.255.2 interface r1-eth0 -+ profile r1 - exit - ! - exit -diff --git a/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf b/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf -index e855f75c20de..58a90d1a490c 100644 ---- a/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf -+++ b/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf -@@ -3,7 +3,7 @@ router bgp 65001 - neighbor 192.168.255.2 remote-as external - neighbor 192.168.255.2 timers 3 10 - neighbor 192.168.255.2 timers connect 1 -- neighbor 192.168.255.2 bfd -+ neighbor 192.168.255.2 bfd profile r1 - neighbor 192.168.255.2 passive - address-family ipv4 - redistribute connected -diff --git a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py -index 00142981c502..3be34300078b 100644 ---- a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py -+++ b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py -@@ -89,6 +89,9 @@ def _bgp_bfd_down_notification(): - "192.168.255.1": { - "lastNotificationReason": "Cease/BFD Down", - "lastNotificationHardReset": True, -+ "peerBfdInfo": { -+ "status": "Up", -+ }, - } - } - return topotest.json_cmp(output, expected) -diff --git a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py -new file mode 100644 -index 000000000000..5ffeed5033ae ---- /dev/null -+++ b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py -@@ -0,0 +1,122 @@ -+#!/usr/bin/env python -+# SPDX-License-Identifier: ISC -+ -+# -+# bgp_bfd_down_cease_notification_shutdown.py -+# -+# Copyright (c) 2024 by -+# Donatas Abraitis -+# -+ -+""" -+Check if Cease/BFD Down notification message is sent/received -+when the BFD is down (administratively). -+""" -+ -+import os -+import sys -+import json -+import pytest -+import functools -+ -+CWD = os.path.dirname(os.path.realpath(__file__)) -+sys.path.append(os.path.join(CWD, "../")) -+ -+# pylint: disable=C0413 -+from lib import topotest -+from lib.topogen import Topogen, TopoRouter, get_topogen -+from lib.common_config import kill_router_daemons, step -+ -+pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd] -+ -+ -+def build_topo(tgen): -+ for routern in range(1, 3): -+ tgen.add_router("r{}".format(routern)) -+ -+ switch = tgen.add_switch("s1") -+ switch.add_link(tgen.gears["r1"]) -+ switch.add_link(tgen.gears["r2"]) -+ -+ -+def setup_module(mod): -+ tgen = Topogen(build_topo, mod.__name__) -+ tgen.start_topology() -+ -+ router_list = tgen.routers() -+ -+ for i, (rname, router) in enumerate(router_list.items(), 1): -+ router.load_config( -+ TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) -+ ) -+ router.load_config( -+ TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) -+ ) -+ router.load_config( -+ TopoRouter.RD_BFD, os.path.join(CWD, "{}/bfdd.conf".format(rname)) -+ ) -+ -+ tgen.start_router() -+ -+ -+def teardown_module(mod): -+ tgen = get_topogen() -+ tgen.stop_topology() -+ -+ -+def test_bgp_bfd_down_notification_shutdown(): -+ tgen = get_topogen() -+ -+ if tgen.routers_have_failure(): -+ pytest.skip(tgen.errors) -+ -+ r1 = tgen.gears["r1"] -+ r2 = tgen.gears["r2"] -+ -+ def _bgp_converge(): -+ output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) -+ expected = { -+ "192.168.255.1": { -+ "bgpState": "Established", -+ "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, -+ "peerBfdInfo": {"status": "Up"}, -+ } -+ } -+ return topotest.json_cmp(output, expected) -+ -+ def _bgp_bfd_down_notification(): -+ output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) -+ expected = { -+ "192.168.255.1": { -+ "lastNotificationReason": "Cease/BFD Down", -+ "lastNotificationHardReset": True, -+ "peerBfdInfo": { -+ "status": "Down", -+ }, -+ } -+ } -+ return topotest.json_cmp(output, expected) -+ -+ step("Initial BGP converge") -+ test_func = functools.partial(_bgp_converge) -+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) -+ assert result is None, "Failed to see BGP convergence on R2" -+ -+ r1.vtysh_cmd( -+ """ -+ configure -+ bfd -+ profile r1 -+ shutdown -+ """ -+ ) -+ -+ step("Check if we received Cease/BFD Down notification message") -+ test_func = functools.partial(_bgp_bfd_down_notification) -+ _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) -+ assert result is None, "Failed to see BGP Cease/BFD Down notification message on R2" -+ -+ -+if __name__ == "__main__": -+ args = ["-s"] + sys.argv[1:] -+ sys.exit(pytest.main(args)) - -From ae1f3a48513f51c540788a090b05c24750665f55 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Tue, 11 Jun 2024 11:41:53 +0300 -Subject: [PATCH 2/3] bgpd: Keep last notification's state about hard reset - -When we receive a hard-reset notification, we always show it if it was a hard, -or not. - -For sending side, we missed that. Let's display it too. - -Signed-off-by: Donatas Abraitis ---- - bgpd/bgp_packet.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index 3f38790cbda3..8a4453f12472 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -982,6 +982,7 @@ static void bgp_notify_send_internal(struct peer_connection *connection, - peer->notify.code = bgp_notify.code; - peer->notify.subcode = bgp_notify.subcode; - peer->notify.length = bgp_notify.length; -+ peer->notify.hard_reset = hard_reset; - - if (bgp_notify.length && data) { - bgp_notify.data = XMALLOC(MTYPE_BGP_NOTIFICATION, - -From 1fb48f5d13faf4ec1e6d4c2cdded9ca2dcd6d609 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Wed, 12 Jun 2024 08:39:48 +0300 -Subject: [PATCH 3/3] bgpd: Do not start BGP session if BFD profile is in - shutdown state - -If we do: - -``` -bfd - profile foo - shutdown -``` - -The session is dropped, but immediately established again because we don't -have a proper check on BFD. - -If BFD is administratively shutdown, ignore starting the session. - -Fixes: https://github.com/FRRouting/frr/issues/16186 - -Signed-off-by: Donatas Abraitis ---- - bgpd/bgpd.c | 6 ++++++ - lib/bfd.c | 6 ++++++ - lib/bfd.h | 2 ++ - 3 files changed, 14 insertions(+) - -diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 81506f4410b1..869d2b455214 100644 ---- a/bgpd/bgpd.c -+++ b/bgpd/bgpd.c -@@ -4507,6 +4507,12 @@ bool peer_active(struct peer *peer) - { - if (BGP_CONNECTION_SU_UNSPEC(peer->connection)) - return false; -+ -+ if (peer->bfd_config) { -+ if (bfd_session_is_down(peer->bfd_config->session)) -+ return false; -+ } -+ - if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST] - || peer->afc[AFI_IP][SAFI_LABELED_UNICAST] - || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP] -diff --git a/lib/bfd.c b/lib/bfd.c -index 2222bb954737..4535fc123378 100644 ---- a/lib/bfd.c -+++ b/lib/bfd.c -@@ -1334,3 +1334,9 @@ int bfd_nht_update(const struct prefix *match, const struct zapi_route *route) - - return 0; - } -+ -+bool bfd_session_is_down(const struct bfd_session_params *session) -+{ -+ return session->bss.state == BSS_DOWN || -+ session->bss.state == BSS_ADMIN_DOWN; -+} -diff --git a/lib/bfd.h b/lib/bfd.h -index bfa5287340f2..48929a95642c 100644 ---- a/lib/bfd.h -+++ b/lib/bfd.h -@@ -464,6 +464,8 @@ extern bool bfd_protocol_integration_shutting_down(void); - 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); -+ - #ifdef __cplusplus - } - #endif diff --git a/0009-bgp-bfd-drop-connection.patch b/0009-bgp-bfd-drop-connection.patch deleted file mode 100644 index 201603c..0000000 --- a/0009-bgp-bfd-drop-connection.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 247a75d5c662893f6c08daf6ffbe82eb3073205a Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Tue, 5 Nov 2024 15:51:58 +0200 -Subject: [PATCH] bgpd: Reset BGP session only if it was a real BFD DOWN event - -Without this patch we always see a double-reset, e.g.: - -``` -2024/11/04 12:42:43.010 BGP: [VQY9X-CQZKG] bgp_peer_bfd_update_source: address [0.0.0.0->172.18.0.3] to [172.18.0.2->172.18.0.3] -2024/11/04 12:42:43.010 BGP: [X8BD9-8RKN4] bgp_peer_bfd_update_source: interface none to eth0 -2024/11/04 12:42:43.010 BFD: [MSVDW-Y8Z5Q] ptm-del-dest: deregister peer [mhop:no peer:172.18.0.3 local:0.0.0.0 vrf:default cbit:0x00 minimum-ttl:255] -2024/11/04 12:42:43.010 BFD: [NYF5K-SE3NS] ptm-del-session: [mhop:no peer:172.18.0.3 local:0.0.0.0 vrf:default] refcount=0 -2024/11/04 12:42:43.010 BFD: [NW21R-MRYNT] session-delete: mhop:no peer:172.18.0.3 local:0.0.0.0 vrf:default -2024/11/04 12:42:43.010 BGP: [P3D3N-3277A] 172.18.0.3 [FSM] Timer (routeadv timer expire) -2024/11/04 12:42:43.010 BFD: [YA0Q5-C0BPV] control-packet: no session found [mhop:no peer:172.18.0.3 local:172.18.0.2 port:11] -2024/11/04 12:42:43.010 BFD: [MSVDW-Y8Z5Q] ptm-add-dest: register peer [mhop:no peer:172.18.0.3 local:172.18.0.2 vrf:default cbit:0x00 minimum-ttl:255] -2024/11/04 12:42:43.011 BFD: [PSB4R-8T1TJ] session-new: mhop:no peer:172.18.0.3 local:172.18.0.2 vrf:default ifname:eth0 -2024/11/04 12:42:43.011 BGP: [Q4BCV-6FHZ5] zclient_bfd_session_update: 172.18.0.2/32 -> 172.18.0.3/32 (interface eth0) VRF default(0) (CPI bit no): Down -2024/11/04 12:42:43.011 BGP: [MKVHZ-7MS3V] bfd_session_status_update: neighbor 172.18.0.3 vrf default(0) bfd state Up -> Down -2024/11/04 12:42:43.011 BGP: [HZN6M-XRM1G] %NOTIFICATION: sent to neighbor 172.18.0.3 6/10 (Cease/BFD Down) 0 bytes -2024/11/04 12:42:43.011 BGP: [QFMSE-NPSNN] zclient_bfd_session_update: sessions updated: 1 -2024/11/04 12:42:43.011 BGP: [ZWCSR-M7FG9] 172.18.0.3 [FSM] BGP_Stop (Established->Clearing), fd 22 -``` - -Reset is due to the source address change. - -With this patch, we reset the session only if it's a _REAL_ BFD down event, which -means we trigger session reset if BFD session is established earlier than BGP. - -Signed-off-by: Donatas Abraitis ---- - bgpd/bgp_bfd.c | 23 ++++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - -diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c -index 14ff5f2e1151..af6068cb1feb 100644 ---- a/bgpd/bgp_bfd.c -+++ b/bgpd/bgp_bfd.c -@@ -53,14 +53,23 @@ static void bfd_session_status_update(struct bfd_session_params *bsp, - peer->host); - return; - } -- peer->last_reset = PEER_DOWN_BFD_DOWN; - -- /* rfc9384 */ -- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) -- bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, -- BGP_NOTIFY_CEASE_BFD_DOWN); -- -- BGP_EVENT_ADD(peer->connection, BGP_Stop); -+ /* Once the BFD session is UP, and later BGP session is UP, -+ * BFD notices that peer->su_local changed, and BFD session goes down. -+ * We should trigger BGP session reset if BFD session is UP -+ * only when BGP session is UP already. -+ * Otherwise, we end up resetting BGP session when BFD session is UP, -+ * when the source address is changed, e.g. 0.0.0.0 -> 10.0.0.1. -+ */ -+ if (bss->last_event > peer->uptime) { -+ peer->last_reset = PEER_DOWN_BFD_DOWN; -+ /* rfc9384 */ -+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) -+ bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, -+ BGP_NOTIFY_CEASE_BFD_DOWN); -+ -+ BGP_EVENT_ADD(peer->connection, BGP_Stop); -+ } - } - - if (bss->state == BSS_UP && bss->previous_state != BSS_UP && diff --git a/0010-frr-reload-escape-strings.patch b/0010-frr-reload-escape-strings.patch deleted file mode 100644 index e0ba9c7..0000000 --- a/0010-frr-reload-escape-strings.patch +++ /dev/null @@ -1,245 +0,0 @@ -diff --git a/tools/frr-reload.py b/tools/frr-reload.py -index 461f0e8..12c71de 100755 ---- a/tools/frr-reload.py -+++ b/tools/frr-reload.py -@@ -201,9 +201,9 @@ def get_normalized_es_id(line): - """ - The es-id or es-sys-mac need to be converted to lower case - """ -- sub_strs = ["evpn mh es-id", "evpn mh es-sys-mac"] -+ sub_strs = [r"evpn mh es-id", r"evpn mh es-sys-mac"] - for sub_str in sub_strs: -- obj = re.match(sub_str + " (?P\S*)", line) -+ obj = re.match(sub_str + r" (?P\S*)", line) - if obj: - line = "%s %s" % (sub_str, obj.group("esi").lower()) - break -@@ -228,7 +228,7 @@ def get_normalized_interface_vrf(line): - correctly and configurations are matched appropriately. - """ - -- intf_vrf = re.search("interface (\S+) vrf (\S+)", line) -+ intf_vrf = re.search(r"interface (\S+) vrf (\S+)", line) - if intf_vrf: - old_line = "vrf %s" % intf_vrf.group(2) - new_line = line.replace(old_line, "").strip() -@@ -813,7 +813,7 @@ def bgp_delete_nbr_remote_as_line(lines_to_add): - if ctx_keys[0] not in pg_dict: - pg_dict[ctx_keys[0]] = dict() - # find 'neighbor peer-group' -- re_pg = re.match("neighbor (\S+) peer-group$", line) -+ re_pg = re.match(r"neighbor (\S+) peer-group$", line) - if re_pg and re_pg.group(1) not in pg_dict[ctx_keys[0]]: - pg_dict[ctx_keys[0]][re_pg.group(1)] = { - "nbr": list(), -@@ -836,13 +836,13 @@ def bgp_delete_nbr_remote_as_line(lines_to_add): - if ctx_keys[0] in pg_dict: - for pg_key in pg_dict[ctx_keys[0]]: - # Find 'neighbor remote-as' -- pg_rmtas = "neighbor %s remote-as (\S+)" % pg_key -+ pg_rmtas = r"neighbor %s remote-as (\S+)" % pg_key - re_pg_rmtas = re.search(pg_rmtas, line) - if re_pg_rmtas: - pg_dict[ctx_keys[0]][pg_key]["remoteas"] = True - - # Find 'neighbor [interface] peer-group ' -- nb_pg = "neighbor (\S+) peer-group %s$" % pg_key -+ nb_pg = r"neighbor (\S+) peer-group %s$" % pg_key - re_nbr_pg = re.search(nb_pg, line) - if ( - re_nbr_pg -@@ -860,7 +860,7 @@ def bgp_delete_nbr_remote_as_line(lines_to_add): - and line - and line.startswith("neighbor ") - ): -- nbr_rmtas = "neighbor (\S+) remote-as.*" -+ nbr_rmtas = r"neighbor (\S+) remote-as.*" - re_nbr_rmtas = re.search(nbr_rmtas, line) - if re_nbr_rmtas and ctx_keys[0] in pg_dict: - for pg in pg_dict[ctx_keys[0]]: -@@ -889,8 +889,8 @@ def bgp_remove_neighbor_cfg(lines_to_del, del_nbr_dict): - ): - if ctx_keys[0] in del_nbr_dict: - for nbr in del_nbr_dict[ctx_keys[0]]: -- re_nbr_pg = re.search("neighbor (\S+) .*peer-group (\S+)", line) -- nb_exp = "neighbor %s .*" % nbr -+ re_nbr_pg = re.search(r"neighbor (\S+) .*peer-group (\S+)", line) -+ nb_exp = r"neighbor %s .*" % nbr - if not re_nbr_pg: - re_nb = re.search(nb_exp, line) - if re_nb: -@@ -988,7 +988,7 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del): - # neighbor uplink1 interface remote-as internal - # - # 'no neighbor peer [interface] remote-as <>' -- nb_remoteas = "neighbor (\S+) .*remote-as (\S+)" -+ nb_remoteas = r"neighbor (\S+) .*remote-as (\S+)" - re_nb_remoteas = re.search(nb_remoteas, line) - if re_nb_remoteas: - lines_to_del_to_app.append((ctx_keys, line)) -@@ -996,7 +996,7 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del): - # 'no neighbor peer [interface] peer-group <>' is in lines_to_del - # copy the neighbor and look for all config removal lines associated - # to neighbor and delete them from the lines_to_del -- re_nbr_pg = re.search("neighbor (\S+) .*peer-group (\S+)", line) -+ re_nbr_pg = re.search(r"neighbor (\S+) .*peer-group (\S+)", line) - if re_nbr_pg: - if ctx_keys[0] not in del_nbr_dict: - del_nbr_dict[ctx_keys[0]] = list() -@@ -1008,7 +1008,7 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del): - if ctx_keys[0] not in del_dict: - del_dict[ctx_keys[0]] = dict() - # find 'no neighbor peer-group' -- re_pg = re.match("neighbor (\S+) peer-group$", line) -+ re_pg = re.match(r"neighbor (\S+) peer-group$", line) - if re_pg and re_pg.group(1) not in del_dict[ctx_keys[0]]: - del_dict[ctx_keys[0]][re_pg.group(1)] = list() - found_pg_del_cmd = True -@@ -1035,7 +1035,7 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del): - if ctx_keys[0] in del_dict: - for pg_key in del_dict[ctx_keys[0]]: - # 'neighbor [interface] peer-group ' -- nb_pg = "neighbor (\S+) .*peer-group %s$" % pg_key -+ nb_pg = r"neighbor (\S+) .*peer-group %s$" % pg_key - re_nbr_pg = re.search(nb_pg, line) - if ( - re_nbr_pg -@@ -1053,13 +1053,13 @@ def bgp_delete_move_lines(lines_to_add, lines_to_del): - if ctx_keys[0] in del_dict: - for pg in del_dict[ctx_keys[0]]: - for nbr in del_dict[ctx_keys[0]][pg]: -- nb_exp = "neighbor %s .*" % nbr -+ nb_exp = r"neighbor %s .*" % nbr - re_nb = re.search(nb_exp, line) - # add peer configs to delete list. - if re_nb and line not in lines_to_del_to_del: - lines_to_del_to_del.append((ctx_keys, line)) - -- pg_exp = "neighbor %s peer-group$" % pg -+ pg_exp = r"neighbor %s peer-group$" % pg - re_pg = re.match(pg_exp, line) - if re_pg: - lines_to_del_to_app.append((ctx_keys, line)) -@@ -1093,7 +1093,7 @@ def pim_delete_move_lines(lines_to_add, lines_to_del): - - # no ip msdp peer <> does not accept source so strip it off. - if line and line.startswith("ip msdp peer "): -- pim_msdp_peer = re.search("ip msdp peer (\S+) source (\S+)", line) -+ pim_msdp_peer = re.search(r"ip msdp peer (\S+) source (\S+)", line) - if pim_msdp_peer: - source_sub_str = "source %s" % pim_msdp_peer.group(2) - new_line = line.replace(source_sub_str, "").strip() -@@ -1186,10 +1186,10 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # - # If so then chop the del line and the corresponding add lines - re_swpx_int_peergroup = re.search( -- "neighbor (\S+) interface peer-group (\S+)", line -+ r"neighbor (\S+) interface peer-group (\S+)", line - ) - re_swpx_int_v6only_peergroup = re.search( -- "neighbor (\S+) interface v6only peer-group (\S+)", line -+ r"neighbor (\S+) interface v6only peer-group (\S+)", line - ) - - if re_swpx_int_peergroup or re_swpx_int_v6only_peergroup: -@@ -1246,7 +1246,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - - if re_nbr_bfd_timers: - nbr = re_nbr_bfd_timers.group(1) -- bfd_nbr = "neighbor %s" % nbr -+ bfd_nbr = r"neighbor %s" % nbr - bfd_search_string = bfd_nbr + r" bfd (\S+) (\S+) (\S+)" - - for ctx_keys, add_line in lines_to_add: -@@ -1271,13 +1271,13 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # they actually match and if we are going from a very old style - # command such that the neighbor command is under the `router - # bgp ..` node that we need to handle that appropriately -- re_nbr_rm = re.search("neighbor(.*)route-map(.*)(in|out)$", line) -+ re_nbr_rm = re.search(r"neighbor(.*)route-map(.*)(in|out)$", line) - if re_nbr_rm: - adjust_for_bgp_node = 0 - neighbor_name = re_nbr_rm.group(1) - rm_name_del = re_nbr_rm.group(2) - dir = re_nbr_rm.group(3) -- search = "neighbor%sroute-map(.*)%s" % (neighbor_name, dir) -+ search = r"neighbor%sroute-map(.*)%s" % (neighbor_name, dir) - save_line = "EMPTY" - for ctx_keys_al, add_line in lines_to_add: - if ctx_keys_al[0].startswith("router bgp"): -@@ -1330,10 +1330,10 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # - # If so then chop the del line and the corresponding add lines - re_swpx_int_remoteas = re.search( -- "neighbor (\S+) interface remote-as (\S+)", line -+ r"neighbor (\S+) interface remote-as (\S+)", line - ) - re_swpx_int_v6only_remoteas = re.search( -- "neighbor (\S+) interface v6only remote-as (\S+)", line -+ r"neighbor (\S+) interface v6only remote-as (\S+)", line - ) - - if re_swpx_int_remoteas or re_swpx_int_v6only_remoteas: -@@ -1373,7 +1373,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # unnecessary session resets. - if "multipath-relax" in line: - re_asrelax_new = re.search( -- "^bgp\s+bestpath\s+as-path\s+multipath-relax$", line -+ r"^bgp\s+bestpath\s+as-path\s+multipath-relax$", line - ) - old_asrelax_cmd = "bgp bestpath as-path multipath-relax no-as-set" - found_asrelax_old = line_exist(lines_to_add, ctx_keys, old_asrelax_cmd) -@@ -1398,7 +1398,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # the new syntax. This causes an unnecessary 'no import-table' followed - # by the same old 'ip import-table' which causes perturbations in - # announced routes leading to traffic blackholes. Fix this issue. -- re_importtbl = re.search("^ip\s+import-table\s+(\d+)$", ctx_keys[0]) -+ re_importtbl = re.search(r"^ip\s+import-table\s+(\d+)$", ctx_keys[0]) - if re_importtbl: - table_num = re_importtbl.group(1) - for ctx in lines_to_add: -@@ -1419,7 +1419,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # access-list FOO seq 5 permit 2.2.2.2/32 - # ipv6 access-list BAR seq 5 permit 2:2:2::2/128 - re_acl_pfxlst = re.search( -- "^(ip |ipv6 |)(prefix-list|access-list)(\s+\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", -+ r"^(ip |ipv6 |)(prefix-list|access-list)(\s+\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", - ctx_keys[0], - ) - if re_acl_pfxlst: -@@ -1452,7 +1452,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # bgp large-community-list standard llist seq 5 permit 65001:65001:1 - # bgp extcommunity-list standard elist seq 5 permit soo 123:123 - re_bgp_lists = re.search( -- "^(bgp )(community-list|large-community-list|extcommunity-list)(\s+\S+\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", -+ r"^(bgp )(community-list|large-community-list|extcommunity-list)(\s+\S+\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", - ctx_keys[0], - ) - if re_bgp_lists: -@@ -1481,7 +1481,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - # Examples: - # bgp as-path access-list important_internet_bgp_as_numbers seq 30 permit _40841_" - re_bgp_as_path = re.search( -- "^(bgp )(as-path )(access-list )(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", -+ r"^(bgp )(as-path )(access-list )(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$", - ctx_keys[0], - ) - if re_bgp_as_path: -@@ -1511,7 +1511,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del): - and ctx_keys[2].startswith("vni") - ): - re_route_target = ( -- re.search("^route-target import (.*)$", line) -+ re.search(r"^route-target import (.*)$", line) - if line is not None - else False - ) -@@ -1648,7 +1648,7 @@ def compare_context_objects(newconf, running): - pcclist_to_del = [] - candidates_to_add = [] - delete_bgpd = False -- area_stub_no_sum = "area (\S+) stub no-summary" -+ area_stub_no_sum = r"area (\S+) stub no-summary" - deleted_keychains = [] - - # Find contexts that are in newconf but not in running diff --git a/0011-bfd-peer-established.patch b/0011-bfd-peer-established.patch deleted file mode 100644 index ab3ce78..0000000 --- a/0011-bfd-peer-established.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 7479885..fbce4fb 100644 ---- a/bgpd/bgpd.c -+++ b/bgpd/bgpd.c -@@ -4525,8 +4525,11 @@ bool peer_active(struct peer *peer) - return false; - - if (peer->bfd_config) { -- if (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->connection) && -+ bfd_session_is_down(peer->bfd_config->session)) -+ return false; - } - - if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST] -diff --git a/lib/bfd.c b/lib/bfd.c -index 4535fc1..9898922 100644 ---- a/lib/bfd.c -+++ b/lib/bfd.c -@@ -1340,3 +1340,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 48929a9..29c960a 100644 ---- a/lib/bfd.h -+++ b/lib/bfd.h -@@ -465,6 +465,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/frr.spec b/frr.spec index 97b7abe..29e02a0 100644 --- a/frr.spec +++ b/frr.spec @@ -8,8 +8,8 @@ %bcond selinux 1 Name: frr -Version: 10.1 -Release: 11%{?dist} +Version: 10.4.1 +Release: 1%{?dist} Summary: Routing daemon License: GPL-2.0-or-later AND ISC AND LGPL-2.0-or-later AND BSD-2-Clause AND BSD-3-Clause AND (GPL-2.0-or-later OR ISC) AND MIT URL: http://www.frrouting.org @@ -20,18 +20,13 @@ Source2: %{name}-sysusers.conf Source3: frr.fc Source4: frr.te Source5: frr.if +Source6: remove-babeld-ldpd.sh Patch0000: 0000-remove-babeld-and-ldpd.patch Patch0002: 0002-enable-openssl.patch Patch0003: 0003-disable-eigrp-crypto.patch Patch0004: 0004-fips-mode.patch Patch0005: 0005-remove-grpc-test.patch -Patch0006: 0006-noprefixroute-network-manager.patch -Patch0007: 0007-CVE-2024-44070.patch -Patch0008: 0008-bfd-bgp-shutdown-notification.patch -Patch0009: 0009-bgp-bfd-drop-connection.patch -Patch0010: 0010-frr-reload-escape-strings.patch -Patch0011: 0011-bfd-peer-established.patch BuildRequires: autoconf BuildRequires: automake @@ -115,6 +110,7 @@ cp -p %{SOURCE3} %{SOURCE4} %{SOURCE5} selinux sed -r -i 's/(AX_CXX_COMPILE_STDCXX\(\[)11(\])/\117\2/' configure.ac %build +export CFLAGS="%{optflags} -DINET_NTOP_NO_OVERRIDE" autoreconf -ivf %configure \ @@ -282,6 +278,9 @@ rm tests/lib/*grpc* %endif %changelog +* Mon Dec 08 2025 Michal Ruprich - 10.4.1-1 +- Resolves: RHEL-118620 - Rebase FRR in to version 10.4.1 + * Wed Aug 06 2025 Michal Ruprich - 10.1-11 - Resolves: RHEL-107464 - bgp session not recovered due to incorect error no AF activated for peer diff --git a/frr.te b/frr.te index 68af3e9..54012f5 100644 --- a/frr.te +++ b/frr.te @@ -98,12 +98,15 @@ corenet_tcp_bind_cmadmin_port(frr_t) corenet_udp_bind_cmadmin_port(frr_t) corenet_tcp_bind_firepower_port(frr_t) corenet_tcp_bind_generic_port(frr_t) +corenet_udp_bind_generic_port(frr_t) corenet_tcp_bind_priority_e_com_port(frr_t) corenet_udp_bind_router_port(frr_t) corenet_tcp_bind_qpasa_agent_port(frr_t) corenet_tcp_bind_smntubootstrap_port(frr_t) corenet_tcp_bind_versa_tek_port(frr_t) corenet_tcp_bind_zebra_port(frr_t) +# general reserved port for pimd +corenet_tcp_bind_reserved_port(frr_t) domain_use_interactive_fds(frr_t) diff --git a/remove-babeld-ldpd.sh b/remove-babeld-ldpd.sh new file mode 100644 index 0000000..ae76a45 --- /dev/null +++ b/remove-babeld-ldpd.sh @@ -0,0 +1,16 @@ +#!/bin/sh +#this script is used to remove babled and ldpd from the tar sources +#Usage: sh remove-babeld-ldpd.sh +#Example: sh remove-babeld-ldpd.sh 7.3.1 - this is for frr-7.3.1.tar.gz file + +VERSION=$1 +TAR=frr-${VERSION}.tar.gz +DIR=frr-${VERSION} + +echo ${VERSION} +echo ${TAR} +echo ${DIR} + +tar -xzf ${TAR} +rm -rf ${DIR}/babeld ${DIR}/ldpd +tar -czf ${TAR} ${DIR} diff --git a/sources b/sources index 0cd4e6a..fd43644 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -SHA512 (frr-10.1.tar.gz) = 7484238a502ab12f178e4a210e6e4a33d0ce53edbb49b127fdc3167e31dd61c1122c1ef2d30e4bcb83b7f520b37fb9ad73e2a6a16790b608b1adf2e23b556445 -SHA512 (remove-babeld-ldpd.sh) = a5bf67a3722cb20d43cef1dac28f839db68df73a1b7d34d8438e4f9366da3b67d85c1f44281f93434e8dd8ebcb2d3dc258b77eaa5627475b7395d207f020839d +SHA512 (frr-10.4.1.tar.gz) = 79ab8bced3ea1ac123c23de8568ed6d1a136b33b7b3edba0936b8cd5dea7cceb796d32632688f06f9e98e8c7f3e07aa57881331e74180edb761f620c8b20f77a