On Tue, Jan 17, 2023 at 03:11:26PM +0100, Claudio Jeker wrote:
> This diff adds all the plumbing to push the ASPA table from the RTR
> process into the RDE. It is still missing important bits but the table
> itself should load and `bgpctl show sets` will show what was loaded.
>
> After that the reload logic needs to be added and the filters need to
> be extended to check the ASPA validation state.
Please commit the diff at the end to fix regress when you land this
(needed because of the new getmonotime() call in aspa_table_prep()).
This generally reads fine. There is a crash in rde_aspa_reload(),
see comments inline. If you agree with my suggested fix, this is ok tb
> Index: bgpd/rde.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
> retrieving revision 1.586
> diff -u -p -r1.586 rde.c
> --- bgpd/rde.c 16 Jan 2023 10:37:08 -0000 1.586
> +++ bgpd/rde.c 17 Jan 2023 10:35:14 -0000
> @@ -83,6 +83,7 @@ static void rde_softreconfig_sync_reeva
> static void rde_softreconfig_sync_fib(struct rib_entry *, void *);
> static void rde_softreconfig_sync_done(void *, uint8_t);
> static void rde_roa_reload(void);
> +static void rde_aspa_reload(void);
> int rde_update_queue_pending(void);
> void rde_update_queue_runner(void);
> void rde_update6_queue_runner(uint8_t);
> @@ -109,7 +110,7 @@ static struct imsgbuf *ibuf_rtr;
> static struct imsgbuf *ibuf_main;
> static struct bgpd_config *conf, *nconf;
> static struct rde_prefixset rde_roa, roa_new;
> -static struct rde_aspa *rde_aspa /* , *aspa_new */;
> +static struct rde_aspa *rde_aspa, *aspa_new;
>
> volatile sig_atomic_t rde_quit = 0;
> struct filter_head *out_rules, *out_rules_tmp;
> @@ -641,6 +642,15 @@ badnetdel:
> imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
> imsg.hdr.pid, -1, &cset, sizeof(cset));
>
> + memset(&cset, 0, sizeof(cset));
> + cset.type = ASPA_SET;
> + strlcpy(cset.name, "RPKI ASPA", sizeof(cset.name));
> + aspa_table_stats(rde_aspa, &cset);
> +
> + imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_SET, 0,
> + imsg.hdr.pid, -1, &cset, sizeof(cset));
> +
The line above is extra and adds trailing tabs
> +
> SIMPLEQ_FOREACH(aset, &conf->as_sets, entry) {
> memset(&cset, 0, sizeof(cset));
> cset.type = ASNUM_SET;
> @@ -1065,9 +1075,11 @@ rde_dispatch_imsg_parent(struct imsgbuf
> void
> rde_dispatch_imsg_rtr(struct imsgbuf *ibuf)
> {
> - struct imsg imsg;
> - struct roa roa;
> - int n;
> + static struct aspa_set *aspa;
> + struct imsg imsg;
> + struct roa roa;
> + struct aspa_prep ap;
> + int n;
>
> while (ibuf) {
> if ((n = imsg_get(ibuf, &imsg)) == -1)
> @@ -1094,9 +1106,66 @@ rde_dispatch_imsg_rtr(struct imsgbuf *ib
> log_addr(&p), roa.prefixlen);
> }
> break;
> + case IMSG_RECONF_ASPA_PREP:
> + if (imsg.hdr.len - IMSG_HEADER_SIZE !=
> + sizeof(ap))
Could unwrap this line
[...]
> @@ -3972,6 +4042,32 @@ rde_roa_reload(void)
> rib_byid(RIB_ADJ_IN), rde_roa_softreload,
> rde_roa_softreload_done, NULL) == -1)
> fatal("%s: rib_dump_new", __func__);
> +}
> +
> +static void
> +rde_aspa_reload(void)
> +{
> + struct rde_aspa *aspa_old;
> +
> + if (aspa_update_pending) {
> + log_info("ASPA softreload skipped, old still running");
> + return;
> + }
> +
> + aspa_old = rde_aspa;
> + rde_aspa = aspa_new;
> + aspa_new = NULL;
> +
> + /* check if aspa changed */
> + if (aspa_table_equal(rde_aspa, aspa_old)) {
The integration test crashes because rde_aspa == NULL && aspa_old == NULL.
A possible fix is to add
if (ra == NULL || old == NULL)
return;
to aspa_table_unchanged().
> + aspa_table_unchanged(rde_aspa, aspa_old);
> + aspa_table_free(aspa_old); /* old aspa no longer needed */
> + return;
> + }
> +
Trailing tab
> + aspa_table_free(aspa_old); /* old aspa no longer needed */
> + log_debug("ASPA change: reloading Adj-RIB-In");
> + /* XXX MISSING */
> }
>
> /*
[...]
> Index: bgpd/rde_aspa.c
> ===================================================================
[...]
> +/*
> + * Return true if the two rde_aspa tables are contain the same data.
> + */
> +int
> +aspa_table_equal(const struct rde_aspa *ra, const struct rde_aspa *rb)
> +{
> + uint32_t i;
> +
> + /* allow NULL pointers to be passed */
8 spaces -> tab
> + if (ra == NULL && rb == NULL)
> + return 1;
> + if (ra == NULL || rb == NULL)
> + return 0;
> +
> + if (ra->maxset != rb->maxset ||
> + ra->maxdata != rb->maxdata)
> + return 0;
> + for (i = 0; i < ra->maxset; i++)
> + if (ra->sets[i].as != rb->sets[i].as)
> + return 0;
> + if (memcmp(ra->data, rb->data, ra->maxdata * sizeof(ra->data[0])) != 0)
> + return 0;
> +
> + return 1;
> +}
> +
> +void
> +aspa_table_unchanged(struct rde_aspa *ra, const struct rde_aspa *old)
> +{
As mentioned above, you may want to add
if (ra == NULL || old == NULL)
return;
> + ra->lastchange = old->lastchange;
> }
Index: unittests/Makefile
===================================================================
RCS file: /cvs/src/regress/usr.sbin/bgpd/unittests/Makefile,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile
--- unittests/Makefile 11 Jan 2023 13:55:08 -0000 1.10
+++ unittests/Makefile 17 Jan 2023 14:56:11 -0000
@@ -39,4 +39,6 @@ SRCS_rde_community_test= rde_community_t
SRCS_rde_decide_test= rde_decide_test.c rde_decide.c rde_attr.c util.c
+SRCS_rde_aspa_test+= rde_aspa_test.c timer.c
+
.include <bsd.regress.mk>