Import CS frr-8.5.3-10.el9
This commit is contained in:
parent
8b09286f3d
commit
3940dd48f0
@ -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;
|
||||
+ }
|
||||
+
|
||||
108
SOURCES/0012-print-log-to-stdout.patch
Normal file
108
SOURCES/0012-print-log-to-stdout.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 4d28aea95851dc14b3987b004f457d7a4a1535f8 Mon Sep 17 00:00:00 2001
|
||||
From: Lou Berger <lberger@labn.net>
|
||||
Date: Sun, 2 Oct 2022 15:56:07 +0000
|
||||
Subject: [PATCH] lib: when running as a daemon, only redirect sdtin, stdout,
|
||||
sdterr to null when a tty.
|
||||
|
||||
Also write memstat to stderr when stderr is not a tty
|
||||
and allow for --log stdout
|
||||
|
||||
Signed-off-by: Lou Berger <lberger@labn.net>
|
||||
---
|
||||
lib/libfrr.c | 44 +++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 31 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/lib/libfrr.c b/lib/libfrr.c
|
||||
index 07e2eafec59c..e8900572694a 100644
|
||||
--- a/lib/libfrr.c
|
||||
+++ b/lib/libfrr.c
|
||||
@@ -130,6 +130,7 @@ static const struct optspec os_always = {
|
||||
" --limit-fds Limit number of fds supported\n",
|
||||
lo_always};
|
||||
|
||||
+static bool logging_to_stdout = false; /* set when --log stdout specified */
|
||||
|
||||
static const struct option lo_cfg[] = {
|
||||
{"config_file", required_argument, NULL, 'f'},
|
||||
@@ -738,6 +739,11 @@ struct event_loop *frr_init(void)
|
||||
while ((log_arg = log_args_pop(di->early_logging))) {
|
||||
command_setup_early_logging(log_arg->target,
|
||||
di->early_loglevel);
|
||||
+ /* this is a bit of a hack,
|
||||
+ but need to notice when
|
||||
+ the target is stdout */
|
||||
+ if (strcmp(log_arg->target, "stdout") == 0)
|
||||
+ logging_to_stdout = true;
|
||||
XFREE(MTYPE_TMP, log_arg);
|
||||
}
|
||||
|
||||
@@ -1088,9 +1094,15 @@ static void frr_terminal_close(int isexit)
|
||||
"%s: failed to open /dev/null: %s", __func__,
|
||||
safe_strerror(errno));
|
||||
} else {
|
||||
- dup2(nullfd, 0);
|
||||
- dup2(nullfd, 1);
|
||||
- dup2(nullfd, 2);
|
||||
+ int fd;
|
||||
+ /*
|
||||
+ * only redirect stdin, stdout, stderr to null when a tty also
|
||||
+ * don't redirect when stdout is set with --log stdout
|
||||
+ */
|
||||
+ for (fd = 2; fd >= 0; fd--)
|
||||
+ if (isatty(fd) &&
|
||||
+ (fd != STDOUT_FILENO || !logging_to_stdout))
|
||||
+ dup2(nullfd, fd);
|
||||
close(nullfd);
|
||||
}
|
||||
}
|
||||
@@ -1168,9 +1180,16 @@ void frr_run(struct event_loop *master)
|
||||
"%s: failed to open /dev/null: %s",
|
||||
__func__, safe_strerror(errno));
|
||||
} else {
|
||||
- dup2(nullfd, 0);
|
||||
- dup2(nullfd, 1);
|
||||
- dup2(nullfd, 2);
|
||||
+ int fd;
|
||||
+ /*
|
||||
+ * only redirect stdin, stdout, stderr to null when a
|
||||
+ * tty also don't redirect when stdout is set with --log
|
||||
+ * stdout
|
||||
+ */
|
||||
+ for (fd = 2; fd >= 0; fd--)
|
||||
+ if (isatty(fd) &&
|
||||
+ (fd != STDOUT_FILENO || !logging_to_stdout))
|
||||
+ dup2(nullfd, fd);
|
||||
close(nullfd);
|
||||
}
|
||||
|
||||
@@ -1194,7 +1213,7 @@ void frr_fini(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char filename[128];
|
||||
- int have_leftovers;
|
||||
+ int have_leftovers = 0;
|
||||
|
||||
hook_call(frr_fini);
|
||||
|
||||
@@ -1220,16 +1239,15 @@ void frr_fini(void)
|
||||
/* frrmod_init -> nothing needed / hooks */
|
||||
rcu_shutdown();
|
||||
|
||||
- if (!debug_memstats_at_exit)
|
||||
- return;
|
||||
-
|
||||
- have_leftovers = log_memstats(stderr, di->name);
|
||||
+ /* also log memstats to stderr when stderr goes to a file*/
|
||||
+ if (debug_memstats_at_exit || !isatty(STDERR_FILENO))
|
||||
+ have_leftovers = log_memstats(stderr, di->name);
|
||||
|
||||
/* in case we decide at runtime that we want exit-memstats for
|
||||
- * a daemon, but it has no stderr because it's daemonized
|
||||
+ * a daemon
|
||||
* (only do this if we actually have something to print though)
|
||||
*/
|
||||
- if (!have_leftovers)
|
||||
+ if (!debug_memstats_at_exit || !have_leftovers)
|
||||
return;
|
||||
|
||||
snprintf(filename, sizeof(filename), "/tmp/frr-memstats-%s-%llu-%llu",
|
||||
306
SOURCES/0013-bfd-bgp-recovery.patch
Normal file
306
SOURCES/0013-bfd-bgp-recovery.patch
Normal file
@ -0,0 +1,306 @@
|
||||
From 5eb7047e2798e56c89c650434d3c6e7dc7533328 Mon Sep 17 00:00:00 2001
|
||||
From: Donatas Abraitis <donatas@opensourcerouting.org>
|
||||
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 <donatas@opensourcerouting.org>
|
||||
---
|
||||
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 <sharpd@nvidia.com>
|
||||
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 <sharpd@nvidia.com>
|
||||
---
|
||||
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 <sharpd@nvidia.com>
|
||||
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 <sharpd@nvidia.com>
|
||||
---
|
||||
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 <louis.scalbert@6wind.com>
|
||||
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 <louis.scalbert@6wind.com>
|
||||
---
|
||||
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
|
||||
}
|
||||
16
SOURCES/0014-isisd-fuzz-test.patch
Normal file
16
SOURCES/0014-isisd-fuzz-test.patch
Normal file
@ -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():
|
||||
301
SOURCES/0015-ipv6-wrong-hash.patch
Normal file
301
SOURCES/0015-ipv6-wrong-hash.patch
Normal file
@ -0,0 +1,301 @@
|
||||
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
|
||||
|
||||
We were hashing 4 bytes of the address. Even for IPv6 addresses.
|
||||
|
||||
Oops.
|
||||
|
||||
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 98b05295b996..90931676e5de 100644
|
||||
--- a/lib/nexthop.c
|
||||
+++ b/lib/nexthop.c
|
||||
@@ -746,68 +746,30 @@ unsigned int nexthop_level(const struct nexthop *nexthop)
|
||||
return rv;
|
||||
}
|
||||
|
||||
-/* Only hash word-sized things, let cmp do the rest. */
|
||||
-uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
|
||||
+uint32_t nexthop_hash(const struct nexthop *nexthop)
|
||||
{
|
||||
uint32_t key = 0x45afe398;
|
||||
- int i;
|
||||
|
||||
- key = jhash_3words(nexthop->type, nexthop->vrf_id,
|
||||
- nexthop->nh_label_type, key);
|
||||
-
|
||||
- if (nexthop->nh_label) {
|
||||
- int labels = nexthop->nh_label->num_labels;
|
||||
+ /* type, vrf, ifindex, ip addresses - see nexthop.h */
|
||||
+ key = _nexthop_hash_bytes(nexthop, key);
|
||||
|
||||
- i = 0;
|
||||
+ key = jhash_1word(nexthop->flags & NEXTHOP_FLAGS_HASHED, key);
|
||||
|
||||
- while (labels >= 3) {
|
||||
- key = jhash_3words(nexthop->nh_label->label[i],
|
||||
- nexthop->nh_label->label[i + 1],
|
||||
- nexthop->nh_label->label[i + 2],
|
||||
- key);
|
||||
- labels -= 3;
|
||||
- i += 3;
|
||||
- }
|
||||
-
|
||||
- if (labels >= 2) {
|
||||
- key = jhash_2words(nexthop->nh_label->label[i],
|
||||
- nexthop->nh_label->label[i + 1],
|
||||
- key);
|
||||
- labels -= 2;
|
||||
- i += 2;
|
||||
- }
|
||||
+ if (nexthop->nh_label) {
|
||||
+ const struct mpls_label_stack *ls = nexthop->nh_label;
|
||||
|
||||
- if (labels >= 1)
|
||||
- key = jhash_1word(nexthop->nh_label->label[i], key);
|
||||
+ /* num_labels itself isn't useful to hash, if the number of
|
||||
+ * labels is different, the hash value will change just due to
|
||||
+ * that already.
|
||||
+ */
|
||||
+ key = jhash(ls->label, sizeof(ls->label[0]) * ls->num_labels, key);
|
||||
}
|
||||
|
||||
- key = jhash_2words(nexthop->ifindex,
|
||||
- CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK),
|
||||
- key);
|
||||
-
|
||||
/* Include backup nexthops, if present */
|
||||
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
|
||||
int backups = nexthop->backup_num;
|
||||
|
||||
- i = 0;
|
||||
-
|
||||
- while (backups >= 3) {
|
||||
- key = jhash_3words(nexthop->backup_idx[i],
|
||||
- nexthop->backup_idx[i + 1],
|
||||
- nexthop->backup_idx[i + 2], key);
|
||||
- backups -= 3;
|
||||
- i += 3;
|
||||
- }
|
||||
-
|
||||
- while (backups >= 2) {
|
||||
- key = jhash_2words(nexthop->backup_idx[i],
|
||||
- nexthop->backup_idx[i + 1], key);
|
||||
- backups -= 2;
|
||||
- i += 2;
|
||||
- }
|
||||
-
|
||||
- if (backups >= 1)
|
||||
- key = jhash_1word(nexthop->backup_idx[i], key);
|
||||
+ key = jhash(nexthop->backup_idx, sizeof(nexthop->backup_idx[0]) * backups, key);
|
||||
}
|
||||
|
||||
if (nexthop->nh_srv6) {
|
||||
@@ -842,31 +804,6 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)
|
||||
return key;
|
||||
}
|
||||
|
||||
-
|
||||
-#define GATE_SIZE 4 /* Number of uint32_t words in struct g_addr */
|
||||
-
|
||||
-/* For a more granular hash */
|
||||
-uint32_t nexthop_hash(const struct nexthop *nexthop)
|
||||
-{
|
||||
- uint32_t gate_src_rmap_raw[GATE_SIZE * 3] = {};
|
||||
- /* Get all the quick stuff */
|
||||
- uint32_t key = nexthop_hash_quick(nexthop);
|
||||
-
|
||||
- assert(((sizeof(nexthop->gate) + sizeof(nexthop->src)
|
||||
- + sizeof(nexthop->rmap_src))
|
||||
- / 3)
|
||||
- == (GATE_SIZE * sizeof(uint32_t)));
|
||||
-
|
||||
- memcpy(gate_src_rmap_raw, &nexthop->gate, GATE_SIZE);
|
||||
- memcpy(gate_src_rmap_raw + GATE_SIZE, &nexthop->src, GATE_SIZE);
|
||||
- memcpy(gate_src_rmap_raw + (2 * GATE_SIZE), &nexthop->rmap_src,
|
||||
- GATE_SIZE);
|
||||
-
|
||||
- key = jhash2(gate_src_rmap_raw, (GATE_SIZE * 3), key);
|
||||
-
|
||||
- return key;
|
||||
-}
|
||||
-
|
||||
void nexthop_copy_no_recurse(struct nexthop *copy,
|
||||
const struct nexthop *nexthop,
|
||||
struct nexthop *rparent)
|
||||
diff --git a/lib/nexthop.h b/lib/nexthop.h
|
||||
index 02ea4d96f2df..12e6424f2774 100644
|
||||
--- a/lib/nexthop.h
|
||||
+++ b/lib/nexthop.h
|
||||
@@ -8,6 +8,7 @@
|
||||
#ifndef _LIB_NEXTHOP_H
|
||||
#define _LIB_NEXTHOP_H
|
||||
|
||||
+#include "jhash.h"
|
||||
#include "prefix.h"
|
||||
#include "mpls.h"
|
||||
#include "vxlan.h"
|
||||
@@ -56,15 +57,48 @@ struct nexthop {
|
||||
struct nexthop *next;
|
||||
struct nexthop *prev;
|
||||
|
||||
- /*
|
||||
- * What vrf is this nexthop associated with?
|
||||
+
|
||||
+ /* begin of hashed data - all fields from here onwards are given to
|
||||
+ * jhash() as one consecutive chunk. DO NOT create "padding holes".
|
||||
+ * DO NOT insert pointers that need to be deep-hashed.
|
||||
+ *
|
||||
+ * static_assert() below needs to be updated when fields are added
|
||||
*/
|
||||
+ char _hash_begin[0];
|
||||
+
|
||||
+ /* see above */
|
||||
+ enum nexthop_types_t type;
|
||||
+
|
||||
+ /* What vrf is this nexthop associated with? */
|
||||
vrf_id_t vrf_id;
|
||||
|
||||
/* Interface index. */
|
||||
ifindex_t ifindex;
|
||||
|
||||
- enum nexthop_types_t type;
|
||||
+ /* Type of label(s), if any */
|
||||
+ enum lsp_types_t nh_label_type;
|
||||
+
|
||||
+ /* padding: keep 16 byte alignment here */
|
||||
+
|
||||
+ /* Nexthop address
|
||||
+ * make sure all 16 bytes for IPv6 are zeroed when putting in an IPv4
|
||||
+ * address since the entire thing is hashed as-is
|
||||
+ */
|
||||
+ union {
|
||||
+ union g_addr gate;
|
||||
+ enum blackhole_type bh_type;
|
||||
+ };
|
||||
+ union g_addr src;
|
||||
+ union g_addr rmap_src; /* Src is set via routemap */
|
||||
+
|
||||
+ /* end of hashed data - remaining fields in this struct are not
|
||||
+ * directly fed into jhash(). Most of them are actually part of the
|
||||
+ * hash but have special rules or handling attached.
|
||||
+ */
|
||||
+ char _hash_end[0];
|
||||
+
|
||||
+ /* Weight of the nexthop ( for unequal cost ECMP ) */
|
||||
+ uint8_t weight;
|
||||
|
||||
uint16_t flags;
|
||||
#define NEXTHOP_FLAG_ACTIVE (1 << 0) /* This nexthop is alive. */
|
||||
@@ -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 */
|
||||
|
||||
+ /* which flags are part of nexthop_hash(). Should probably be split
|
||||
+ * off into a separate field...
|
||||
+ */
|
||||
+#define NEXTHOP_FLAGS_HASHED NEXTHOP_FLAG_ONLINK
|
||||
+
|
||||
#define NEXTHOP_IS_ACTIVE(flags) \
|
||||
(CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \
|
||||
&& !CHECK_FLAG(flags, NEXTHOP_FLAG_DUPLICATE))
|
||||
|
||||
- /* Nexthop address */
|
||||
- union {
|
||||
- union g_addr gate;
|
||||
- enum blackhole_type bh_type;
|
||||
- };
|
||||
- union g_addr src;
|
||||
- union g_addr rmap_src; /* Src is set via routemap */
|
||||
-
|
||||
/* Nexthops obtained by recursive resolution.
|
||||
*
|
||||
* If the nexthop struct needs to be resolved recursively,
|
||||
@@ -104,15 +135,9 @@ struct nexthop {
|
||||
/* Recursive parent */
|
||||
struct nexthop *rparent;
|
||||
|
||||
- /* Type of label(s), if any */
|
||||
- enum lsp_types_t nh_label_type;
|
||||
-
|
||||
/* Label(s) associated with this nexthop. */
|
||||
struct mpls_label_stack *nh_label;
|
||||
|
||||
- /* Weight of the nexthop ( for unequal cost ECMP ) */
|
||||
- uint8_t weight;
|
||||
-
|
||||
/* Count and index of corresponding backup nexthop(s) in a backup list;
|
||||
* only meaningful if the HAS_BACKUP flag is set.
|
||||
*/
|
||||
@@ -138,6 +163,29 @@ struct nexthop {
|
||||
struct nexthop_srv6 *nh_srv6;
|
||||
};
|
||||
|
||||
+/* all hashed fields (including padding, if it is necessary to add) need to
|
||||
+ * be listed in the static_assert below
|
||||
+ */
|
||||
+
|
||||
+#define S(field) sizeof(((struct nexthop *)NULL)->field)
|
||||
+
|
||||
+static_assert(
|
||||
+ offsetof(struct nexthop, _hash_end) - offsetof(struct nexthop, _hash_begin) ==
|
||||
+ S(type) + S(vrf_id) + S(ifindex) + S(nh_label_type) + S(gate) + S(src) + S(rmap_src),
|
||||
+ "struct nexthop contains padding, this can break things. insert _pad fields at appropriate places");
|
||||
+
|
||||
+#undef S
|
||||
+
|
||||
+/* this is here to show exactly what is meant by the comments above about
|
||||
+ * the hashing
|
||||
+ */
|
||||
+static inline uint32_t _nexthop_hash_bytes(const struct nexthop *nh, uint32_t seed)
|
||||
+{
|
||||
+ return jhash(&nh->_hash_begin,
|
||||
+ offsetof(struct nexthop, _hash_end) - offsetof(struct nexthop, _hash_begin),
|
||||
+ seed);
|
||||
+}
|
||||
+
|
||||
/* Utility to append one nexthop to another. */
|
||||
#define NEXTHOP_APPEND(to, new) \
|
||||
do { \
|
||||
@@ -181,27 +229,11 @@ struct nexthop *nexthop_from_blackhole(enum blackhole_type bh_type,
|
||||
/*
|
||||
* Hash a nexthop. Suitable for use with hash tables.
|
||||
*
|
||||
- * This function uses the following values when computing the hash:
|
||||
- * - vrf_id
|
||||
- * - ifindex
|
||||
- * - type
|
||||
- * - gate
|
||||
- *
|
||||
- * nexthop
|
||||
- * The nexthop to hash
|
||||
- *
|
||||
- * Returns:
|
||||
- * 32-bit hash of nexthop
|
||||
+ * Please double check the code on what is included in the hash, there was
|
||||
+ * documentation here but it got outdated and the only thing worse than no
|
||||
+ * doc is incorrect doc.
|
||||
*/
|
||||
uint32_t nexthop_hash(const struct nexthop *nexthop);
|
||||
-/*
|
||||
- * Hash a nexthop only on word-sized attributes:
|
||||
- * - vrf_id
|
||||
- * - ifindex
|
||||
- * - type
|
||||
- * - (some) flags
|
||||
- */
|
||||
-uint32_t nexthop_hash_quick(const struct nexthop *nexthop);
|
||||
|
||||
extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2);
|
||||
extern bool nexthop_same_no_labels(const struct nexthop *nh1,
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
Name: frr
|
||||
Version: 8.5.3
|
||||
Release: 7%{?checkout}%{?dist}
|
||||
Release: 10%{?checkout}%{?dist}
|
||||
Summary: Routing daemon
|
||||
License: GPLv2+
|
||||
URL: http://www.frrouting.org
|
||||
@ -71,9 +71,14 @@ 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
|
||||
Patch0015: 0015-ipv6-wrong-hash.patch
|
||||
|
||||
%description
|
||||
FRRouting is free software that manages TCP/IP based routing protocols. It takes
|
||||
@ -104,6 +109,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 \
|
||||
@ -279,6 +288,16 @@ make check PYTHON=%{__python3}
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
- Resolves: RHEL-87731 - FRR bgp session not recovered due to incorect error no AF activated for peer
|
||||
|
||||
* Thu Apr 03 2025 Michal Ruprich <mruprich@redhat.com> - 8.5.3-8
|
||||
- Resolves: RHEL-85950 - FRR doesn't send logs to stdout when running as a daemon
|
||||
|
||||
* Fri Feb 14 2025 Michal Ruprich <mruprich@redhat.com> - 8.5.3-7
|
||||
- Resolves: RHEL-68432 - FRR gives false warning when Graceful Restart enabled
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user