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(struct rpki_vrf *rpki_vrf);
static bool rpki_debug_conf, rpki_debug_term;
XFREE(MTYPE_BGP_RPKI_REVALIDATE, rrp);
}
-static void bgpd_sync_callback(struct event *thread)
+static void revalidate_single_prefix(struct vrf *vrf, struct prefix prefix, afi_t afi)
{
struct bgp *bgp;
struct listnode *node;
- struct prefix prefix;
- struct pfx_record rec;
- struct rpki_vrf *rpki_vrf = EVENT_ARG(thread);
- struct vrf *vrf = NULL;
-
- event_add_read(bm->master, bgpd_sync_callback, rpki_vrf,
- rpki_vrf->rpki_sync_socket_bgpd, NULL);
-
- if (atomic_load_explicit(&rpki_vrf->rtr_update_overflow,
- memory_order_seq_cst)) {
- while (read(rpki_vrf->rpki_sync_socket_bgpd, &rec,
- sizeof(struct pfx_record)) != -1)
- ;
-
- atomic_store_explicit(&rpki_vrf->rtr_update_overflow, 0,
- memory_order_seq_cst);
- revalidate_all_routes(rpki_vrf);
- return;
- }
-
- int retval = read(rpki_vrf->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;
-
- if (rpki_vrf->vrfname) {
- vrf = vrf_lookup_by_name(rpki_vrf->vrfname);
- if (!vrf) {
- zlog_err("%s(): vrf for rpki %s not found", __func__,
- rpki_vrf->vrfname);
- return;
- }
- }
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
safi_t safi;
}
}
-static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi,
- safi_t safi)
+static void bgpd_sync_callback(struct event *thread)
{
- struct bgp_adj_in *ain;
-
- for (ain = bgp_dest->adj_in; ain; ain = ain->next) {
- struct bgp_path_info *path =
- bgp_dest_get_bgp_path_info(bgp_dest);
- mpls_label_t *label = NULL;
- uint32_t num_labels = 0;
-
- if (path && path->extra) {
- label = path->extra->label;
- num_labels = path->extra->num_labels;
- }
- (void)bgp_update(ain->peer, bgp_dest_get_prefix(bgp_dest),
- ain->addpath_rx_id, ain->attr, afi, safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label,
- num_labels, 1, NULL);
- }
-}
-
-/*
- * 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 {
+ struct prefix prefix;
+ struct pfx_record rec;
+ struct rpki_vrf *rpki_vrf = EVENT_ARG(thread);
+ struct vrf *vrf = NULL;
afi_t afi;
- safi_t safi;
- struct peer *peer;
-};
-
-static void bgp_rpki_revalidate_peer(struct event *thread)
-{
- struct rpki_revalidate_peer *rvp = EVENT_ARG(thread);
+ int retval;
- /*
- * 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(struct rpki_vrf *rpki_vrf)
-{
- struct bgp *bgp;
- struct listnode *node;
- struct vrf *vrf = NULL;
+ event_add_read(bm->master, bgpd_sync_callback, rpki_vrf, rpki_vrf->rpki_sync_socket_bgpd,
+ NULL);
if (rpki_vrf->vrfname) {
vrf = vrf_lookup_by_name(rpki_vrf->vrfname);
if (!vrf) {
- zlog_err("%s(): vrf for rpki %s not found", __func__,
- rpki_vrf->vrfname);
+ zlog_err("%s(): vrf for rpki %s not found", __func__, rpki_vrf->vrfname);
return;
}
}
- for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
- struct peer *peer;
- struct listnode *peer_listnode;
+ if (atomic_load_explicit(&rpki_vrf->rtr_update_overflow, memory_order_seq_cst)) {
+ ssize_t size = 0;
- if (!vrf && bgp->vrf_id != VRF_DEFAULT)
- continue;
- if (vrf && bgp->vrf_id != vrf->vrf_id)
- continue;
+ retval = read(rpki_vrf->rpki_sync_socket_bgpd, &rec, sizeof(struct pfx_record));
+ while (retval != -1) {
+ if (retval != sizeof(struct pfx_record))
+ break;
- for (ALL_LIST_ELEMENTS_RO(bgp->peer, peer_listnode, peer)) {
- afi_t afi;
- safi_t safi;
+ size += retval;
+ pfx_record_to_prefix(&rec, &prefix);
+ afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
+ revalidate_single_prefix(vrf, prefix, afi);
- FOREACH_AFI_SAFI (afi, safi) {
- struct rpki_revalidate_peer *rvp;
+ retval = read(rpki_vrf->rpki_sync_socket_bgpd, &rec,
+ sizeof(struct pfx_record));
+ }
- if (!bgp->rib[afi][safi])
- continue;
+ RPKI_DEBUG("Socket overflow detected (%zu), revalidating affected prefixes", size);
- if (!peer_established(peer->connection))
- continue;
+ atomic_store_explicit(&rpki_vrf->rtr_update_overflow, 0, memory_order_seq_cst);
+ return;
+ }
- rvp = XCALLOC(MTYPE_BGP_RPKI_REVALIDATE,
- sizeof(*rvp));
- rvp->peer = peer;
- rvp->afi = afi;
- rvp->safi = safi;
+ retval = read(rpki_vrf->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);
- event_add_event(
- bm->master, bgp_rpki_revalidate_peer,
- rvp, 0,
- &peer->t_revalidate_all[afi][safi]);
- }
+ afi = (rec.prefix.ver == LRTR_IPV4) ? AFI_IP : AFI_IP6;
+
+ revalidate_single_prefix(vrf, prefix, afi);
+}
+
+static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, safi_t safi)
+{
+ struct bgp_adj_in *ain;
+
+ for (ain = bgp_dest->adj_in; ain; ain = ain->next) {
+ struct bgp_path_info *path = bgp_dest_get_bgp_path_info(bgp_dest);
+ mpls_label_t *label = NULL;
+ uint32_t num_labels = 0;
+
+ if (path && path->extra) {
+ label = path->extra->label;
+ num_labels = path->extra->num_labels;
}
+
+ (void)bgp_update(ain->peer, bgp_dest_get_prefix(bgp_dest), ain->addpath_rx_id,
+ ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
+ label, num_labels, 1, NULL);
}
}