import CS git frr-8.5.3-13.el9_8

This commit is contained in:
AlmaLinux RelEng Bot 2026-06-25 07:25:50 -04:00
parent 6aeecfecf9
commit 0edfe7c81e
5 changed files with 353 additions and 22 deletions

View File

@ -1,4 +1,4 @@
From 2eda8382daa3593abfd6a5af543aca1416b51121 Mon Sep 17 00:00:00 2001
From 46e685d2f9cd1a359e0abd95b584f7cc3df9ae2c Mon Sep 17 00:00:00 2001
From: David Lamparter <equinox@opensourcerouting.org>
Date: Wed, 22 Jan 2025 11:23:31 +0100
Subject: [PATCH] lib: clean up nexthop hashing mess
@ -11,16 +11,17 @@ The reason this was done was to try to make it faster, but made a
complex maze out of everything. Time for a refactor.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit 001fcfa1dd9f7dc2639b4f5c7a52ab59cc425452)
---
lib/nexthop.c | 87 ++++++-----------------------------------
lib/nexthop.h | 104 +++++++++++++++++++++++++++++++++-----------------
2 files changed, 80 insertions(+), 111 deletions(-)
diff --git a/lib/nexthop.c b/lib/nexthop.c
index 1eeed4a..fd1d1e9 100644
index 98b05295b996..90931676e5de 100644
--- a/lib/nexthop.c
+++ b/lib/nexthop.c
@@ -693,68 +693,30 @@ unsigned int nexthop_level(const struct nexthop *nexthop)
@@ -746,68 +746,30 @@ unsigned int nexthop_level(const struct nexthop *nexthop)
return rv;
}
@ -101,7 +102,7 @@ index 1eeed4a..fd1d1e9 100644
}
if (nexthop->nh_srv6) {
@@ -768,31 +730,6 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
@@ -842,31 +804,6 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
return key;
}
@ -134,10 +135,10 @@ index 1eeed4a..fd1d1e9 100644
const struct nexthop *nexthop,
struct nexthop *rparent)
diff --git a/lib/nexthop.h b/lib/nexthop.h
index f35cc5e..9383799 100644
index 02ea4d96f2df..12e6424f2774 100644
--- a/lib/nexthop.h
+++ b/lib/nexthop.h
@@ -23,6 +23,7 @@
@@ -8,6 +8,7 @@
#ifndef _LIB_NEXTHOP_H
#define _LIB_NEXTHOP_H
@ -145,7 +146,7 @@ index f35cc5e..9383799 100644
#include "prefix.h"
#include "mpls.h"
#include "vxlan.h"
@@ -71,15 +72,48 @@ struct nexthop {
@@ -56,15 +57,48 @@ struct nexthop {
struct nexthop *next;
struct nexthop *prev;
@ -197,7 +198,7 @@ index f35cc5e..9383799 100644
uint16_t flags;
#define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
@@ -97,18 +131,15 @@ struct nexthop {
@@ -82,18 +116,15 @@ struct nexthop {
#define NEXTHOP_FLAG_EVPN (1 << 8) /* nexthop is EVPN */
#define NEXTHOP_FLAG_LINKDOWN (1 << 9) /* is not removed on link down */
@ -221,7 +222,7 @@ index f35cc5e..9383799 100644
/* Nexthops obtained by recursive resolution.
*
* If the nexthop struct needs to be resolved recursively,
@@ -119,15 +150,9 @@ struct nexthop {
@@ -104,15 +135,9 @@ struct nexthop {
/* Recursive parent */
struct nexthop *rparent;
@ -237,7 +238,7 @@ index f35cc5e..9383799 100644
/* Count and index of corresponding backup nexthop(s) in a backup list;
* only meaningful if the HAS_BACKUP flag is set.
*/
@@ -153,6 +178,29 @@ struct nexthop {
@@ -138,6 +163,29 @@ struct nexthop {
struct nexthop_srv6 *nh_srv6;
};
@ -267,7 +268,7 @@ index f35cc5e..9383799 100644
/* Utility to append one nexthop to another. */
#define NEXTHOP_APPEND(to, new) \
do { \
@@ -196,27 +244,11 @@ struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type,
@@ -181,27 +229,11 @@ struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type,
/*
* Hash a nexthop. Suitable for use with hash tables.
*
@ -298,6 +299,3 @@ index f35cc5e..9383799 100644
extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2);
extern bool nexthop_same_no_labels(const struct nexthop *nh1,
--
2.47.3

View File

@ -0,0 +1,276 @@
From d528c02a204086da0d542d5655b8724de681a65c Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Fri, 7 Jun 2024 13:50:07 -0400
Subject: [PATCH] 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 <sharpd@nvidia.com>
---
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)
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,24 @@ 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;
+
+ 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) {
+ 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;
default:
break;
diff --git a/zebra/rib.h b/zebra/rib.h
index fcd6fb6..49506fd 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -353,6 +353,8 @@ extern void _route_entry_dump(const char *func, union prefixconstptr pp,
union prefixconstptr src_pp,
const struct route_entry *re);
+void zebra_rib_route_entry_free(struct route_entry *re);
+
struct route_entry *
zebra_rib_route_entry_new(vrf_id_t vrf_id, int type, uint8_t instance,
uint32_t flags, uint32_t nhe_id, uint32_t table_id,
@@ -484,6 +486,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/rt_netlink.c b/zebra/rt_netlink.c
index cf8df97..71250ae 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -990,6 +990,8 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h,
re, ng, startup, ctx);
if (ng)
nexthop_group_delete(&ng);
+ if (ctx)
+ zebra_rib_route_entry_free(re);
} else {
/*
* I really don't see how this is possible
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 129416d..ca6be3e 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -4145,6 +4145,12 @@ struct route_entry *zebra_rib_route_entry_new(vrf_id_t vrf_id, int type,
return re;
}
+
+void zebra_rib_route_entry_free(struct route_entry *re)
+{
+ XFREE(MTYPE_RE, re);
+}
+
/*
* Internal route-add implementation; there are a couple of different public
* signatures. Callers in this path are responsible for the memory they
@@ -4434,7 +4440,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;

View File

@ -0,0 +1,48 @@
From c27757965a55e181b3f63239249bbd6ce249a082 Mon Sep 17 00:00:00 2001
From: Jafar Al-Gharaibeh <jafar@atcorp.com>
Date: Mon, 9 Mar 2026 14:36:22 -0500
Subject: [PATCH] bgpd: fix off-by-one error in FlowSpec operator array bounds
check
Change loop > BGP_PBR_MATCH_VAL_MAX to loop >= BGP_PBR_MATCH_VAL_MAX
in bgp_flowspec_op_decode() and bgp_flowspec_bitmask_decode() to
prevent writing one element past the end of the mval[] array when
more than 5 chained operators are present in a FlowSpec component.
Reported-by: Jiahao Lei
Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
---
bgpd/bgp_flowspec_util.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/bgpd/bgp_flowspec_util.c b/bgpd/bgp_flowspec_util.c
index 90e9236..4dd5034 100644
--- a/bgpd/bgp_flowspec_util.c
+++ b/bgpd/bgp_flowspec_util.c
@@ -266,8 +266,10 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
*error = 0;
do {
- if (loop > BGP_PBR_MATCH_VAL_MAX)
+ if (loop >= BGP_PBR_MATCH_VAL_MAX) {
*error = -2;
+ return offset;
+ }
hex2bin(&nlri_ptr[offset], op);
offset++;
len = 2*op[2]+op[3];
@@ -370,8 +372,10 @@ int bgp_flowspec_bitmask_decode(enum bgp_flowspec_util_nlri_t type,
*error = 0;
do {
- if (loop > BGP_PBR_MATCH_VAL_MAX)
+ if (loop >= BGP_PBR_MATCH_VAL_MAX) {
*error = -2;
+ return offset;
+ }
hex2bin(&nlri_ptr[offset], op);
/* if first element, AND bit can not be set */
if (op[1] == 1 && loop == 0)
--
2.52.0

View File

@ -1 +1,2 @@
d /run/frr 0755 frr frr -
d /var/log/frr 0755 frr frr

View File

@ -7,7 +7,7 @@
Name: frr
Version: 8.5.3
Release: 9%{?checkout}%{?dist}.1
Release: 13%{?checkout}%{?dist}
Summary: Routing daemon
License: GPLv2+
URL: http://www.frrouting.org
@ -78,7 +78,9 @@ 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
Patch0015: RHEL-114183.patch
Patch0015: 0015-ipv6-wrong-hash.patch
Patch0016: 0016-dont-ignore-kernel-route.patch
Patch0017: 0017-fix-CVE-2026-37457.patch
%description
FRRouting is free software that manages TCP/IP based routing protocols. It takes
@ -152,8 +154,7 @@ bzip2 -9 selinux/%{name}.pp
%install
mkdir -p %{buildroot}/etc/{frr,rc.d/init.d,sysconfig,logrotate.d,pam.d,default} \
%{buildroot}/var/log/frr %{buildroot}%{_infodir} \
%{buildroot}%{_unitdir}
%{buildroot}%{_infodir} %{buildroot}%{_unitdir}
mkdir -p -m 0755 %{buildroot}%{_libdir}/frr
mkdir -p %{buildroot}%{_tmpfilesdir}
@ -260,7 +261,6 @@ make check PYTHON=%{__python3}
%license COPYING
%doc doc/mpls
%dir %attr(750,frr,frr) %{_sysconfdir}/frr
%dir %attr(755,frr,frr) /var/log/frr
%dir %attr(755,frr,frr) /run/frr
%{_infodir}/*info*
%{_mandir}/man*/*
@ -288,9 +288,17 @@ make check PYTHON=%{__python3}
%endif
%changelog
* Fri Sep 26 2025 RHEL Packaging Agent <jotnar@redhat.com> - 8.5.3-9.1
- Backported a fix for nexthop hashing mess
- Resolves: RHEL-114183
* Thu May 21 2026 Michal Ruprich <mruprich@redhat.com> - 8.5.3-13
- Resolves: RHEL-174677 - denial of service via crafted FlowSpec component
* Fri Jan 16 2026 Michal Ruprich <mruprich@redhat.com> - 8.5.3-12
- Resolves: RHEL-137180 - Files under /var are not properly created in image-mode
* Wed Oct 29 2025 Michal Ruprich <mruprich@redhat.com> - 8.5.3-11
- Resolves: RHEL-64427 - FRR ignores kernel routes from the system
* Fri Sep 19 2025 Michal Ruprich <mruprich@redhat.com> - 8.5.3-10
- Resolves: RHEL-13756 - Source address set in FRR route-map not working with IPv6
* Fri May 16 2025 Michal Ruprich <mruprich@redhat.com> - 8.5.3-9
- Resolves: RHEL-87730 - frr-k8s CI started failing using latest rpm, failures around BFD sessions