File 0004-bgpd-Validate-only-affected-RPKI-prefixes-instead-of.patch of Package frr.40391
From 2a98fd93555d9442f4a5475ea029b910511437e0 Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.com>
Date: Tue, 19 Aug 2025 13:06:19 +0200
Upstream: yes
References: bsc#1235237,CVE-2024-55553,https://github.com/opensourcerouting/frr/commit/cc1c66a7e8dd31c681f396f6635192c0d60a543c
Subject: [PATCH] bgpd: Validate only affected RPKI prefixes instead of a full
RIB
This is backport of https://github.com/FRRouting/frr/commit/b0800bfdf04b4fcf48504737ebfe4ba7f05268d3 for 8.6
based on https://github.com/opensourcerouting/frr/commit/cc1c66a7e8dd31c681f396f6635192c0d60a543c for 8.4.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Signed-off-by: Marius Tomaschewski <mt@suse.com>
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 496f97004f..3cfa486ccd 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -64,6 +64,10 @@ DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_CACHE_GROUP, "BGP RPKI Cache server group");
DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_RTRLIB, "BGP RPKI RTRLib");
DEFINE_MTYPE_STATIC(BGPD, BGP_RPKI_REVALIDATE, "BGP RPKI Revalidation");
+#define RPKI_VALID 1
+#define RPKI_NOTFOUND 2
+#define RPKI_INVALID 3
+
#define POLLING_PERIOD_DEFAULT 3600
#define EXPIRE_INTERVAL_DEFAULT 7200
#define RETRY_INTERVAL_DEFAULT 600
@@ -123,7 +127,6 @@ static void print_record(const struct pfx_record *record, struct vty *vty,
json_object *json);
static bool is_synchronized(void);
static bool is_running(void);
-static bool is_stopping(void);
static void route_match_free(void *rule);
static enum route_map_cmd_result_t route_match(void *rule,
const struct prefix *prefix,
@@ -131,7 +134,6 @@ static enum route_map_cmd_result_t route_match(void *rule,
void *object);
static void *route_match_compile(const char *arg);
static void revalidate_bgp_node(struct bgp_dest *dest, afi_t afi, safi_t safi);
-static void revalidate_all_routes(void);
static struct rtr_mgr_config *rtr_config;
static struct list *cache_list;
@@ -368,11 +370,6 @@ inline bool is_running(void)
return rtr_is_running;
}
-inline bool is_stopping(void)
-{
- return rtr_is_stopping;
-}
-
static void pfx_record_to_prefix(struct pfx_record *record,
struct prefix *prefix)
{
@@ -416,36 +413,10 @@ static void rpki_revalidate_prefix(struct thread *thread)
XFREE(MTYPE_BGP_RPKI_REVALIDATE, rrp);
}
-static void bgpd_sync_callback(struct thread *thread)
+static void revalidate_single_prefix(struct prefix prefix, afi_t afi)
{
struct bgp *bgp;
struct listnode *node;
- struct prefix prefix;
- struct pfx_record rec;
-
- thread_add_read(bm->master, bgpd_sync_callback, NULL,
- rpki_sync_socket_bgpd, NULL);
-
- if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) {
- while (read(rpki_sync_socket_bgpd, &rec,
- sizeof(struct pfx_record)) != -1)
- ;
-
- atomic_store_explicit(&rtr_update_overflow, 0,
- memory_order_seq_cst);
- revalidate_all_routes();
- return;
- }
-
- int retval =
- read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record));
- if (retval != sizeof(struct pfx_record)) {
- RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
- return;
- }
- pfx_record_to_prefix(&rec, &prefix);
-
- afi_t afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
safi_t safi;
@@ -468,6 +439,48 @@ static void bgpd_sync_callback(struct thread *thread)
}
}
+static void bgpd_sync_callback(struct thread *thread)
+{
+ struct prefix prefix;
+ struct pfx_record rec;
+ afi_t afi;
+ int retval;
+
+ if (atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst)) {
+ ssize_t size = 0;
+
+ retval = read(rpki_sync_socket_bgpd, &rec,
+ sizeof(struct pfx_record));
+ while (retval != -1) {
+ if (retval != sizeof(struct pfx_record))
+ break;
+
+ size += retval;
+ pfx_record_to_prefix(&rec, &prefix);
+ afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
+ revalidate_single_prefix(prefix, afi);
+
+ retval = read(rpki_sync_socket_bgpd, &rec,
+ sizeof(struct pfx_record));
+ }
+
+ atomic_store_explicit(&rtr_update_overflow, 0,
+ memory_order_seq_cst);
+ return;
+ }
+
+ retval = read(rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record));
+ if (retval != sizeof(struct pfx_record)) {
+ RPKI_DEBUG("Could not read from rpki_sync_socket_bgpd");
+ return;
+ }
+ pfx_record_to_prefix(&rec, &prefix);
+
+ afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
+
+ revalidate_single_prefix(prefix, afi);
+}
+
static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi,
safi_t safi)
{
@@ -490,73 +503,11 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi,
}
}
-/*
- * The act of a soft reconfig in revalidation is really expensive
- * coupled with the fact that the download of a full rpki state
- * from a rpki server can be expensive, let's break up the revalidation
- * to a point in time in the future to allow other bgp events
- * to take place too.
- */
-struct rpki_revalidate_peer {
- afi_t afi;
- safi_t safi;
- struct peer *peer;
-};
-
-static void bgp_rpki_revalidate_peer(struct thread *thread)
-{
- struct rpki_revalidate_peer *rvp = THREAD_ARG(thread);
-
- /*
- * Here's the expensive bit of gnomish deviousness
- */
- bgp_soft_reconfig_in(rvp->peer, rvp->afi, rvp->safi);
-
- XFREE(MTYPE_BGP_RPKI_REVALIDATE, rvp);
-}
-
-static void revalidate_all_routes(void)
-{
- struct bgp *bgp;
- struct listnode *node;
-
- for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
- struct peer *peer;
- struct listnode *peer_listnode;
-
- for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
- afi_t afi;
- safi_t safi;
-
- FOREACH_AFI_SAFI (afi, safi) {
- struct rpki_revalidate_peer *rvp;
-
- if (!bgp->rib[afi][safi])
- continue;
-
- if (!peer_established(peer))
- continue;
-
- rvp = XCALLOC(MTYPE_BGP_RPKI_REVALIDATE,
- sizeof(*rvp));
- rvp->peer = peer;
- rvp->afi = afi;
- rvp->safi = safi;
-
- thread_add_event(
- bm->master, bgp_rpki_revalidate_peer,
- rvp, 0,
- &peer->t_revalidate_all[afi][safi]);
- }
- }
- }
-}
-
static void rpki_update_cb_sync_rtr(struct pfx_table *p __attribute__((unused)),
const struct pfx_record rec,
const bool added __attribute__((unused)))
{
- if (is_stopping() ||
+ if (rtr_is_stopping ||
atomic_load_explicit(&rtr_update_overflow, memory_order_seq_cst))
return;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 1423529af8..858b2daa3c 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3747,6 +3747,9 @@ int bgp_delete(struct bgp *bgp)
THREAD_OFF(bgp->t_revalidate[afi][safi]);
THREAD_OFF(bgp->t_condition_check);
+ FOREACH_AFI_SAFI (afi, safi)
+ THREAD_OFF(bgp->t_revalidate[afi][safi]);
+
THREAD_OFF(bgp->t_startup);
THREAD_OFF(bgp->t_maxmed_onstartup);
THREAD_OFF(bgp->t_update_delay);
--
2.43.0