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

openSUSE Build Service is sponsored by