Download raw body.
rpki-client: pass around a container struct instead of a long parameter list
rpki-client: pass around a container struct instead of a long parameter list
rpki-client: pass around a container struct instead of a long parameter list
On Tue, Jul 08, 2025 at 12:44:12PM +0000, Job Snijders wrote:
> I think it is fine to continue to pass around 'everything' into the
> various output functions - even when a particular function doesn't use a
> one or more of the available trees; BUT, it seems tedious that every
> time we add or remove a feature, every output function's signature also
> has to change.
>
> Perhaps it is better to use a struct that contains references to the
> various trees and pass that 'container' around. I believe this kind of
> refactor will help avoid certain churn in future work.
>
> Thoughts?
Please call it struct container or context or so and not struct trees.
Apart from that OK.
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> diff -u -p -r1.243 extern.h
> --- extern.h 30 Jun 2025 14:20:26 -0000 1.243
> +++ extern.h 8 Jul 2025 12:40:46 -0000
> @@ -501,6 +501,14 @@ struct brk {
> RB_HEAD(brk_tree, brk);
> RB_PROTOTYPE(brk_tree, brk, entry, brkcmp);
>
> +struct trees {
> + struct vrp_tree vrps;
> + struct brk_tree brks;
> + struct vap_tree vaps;
> + struct vsp_tree vsps;
> + struct nca_tree ncas;
> +};
> +
> /*
> * A single CRL
> */
> @@ -995,25 +1003,13 @@ extern int outformats;
> #define FORMAT_JSON 0x08
> #define FORMAT_OMETRIC 0x10
>
> -int outputfiles(struct vrp_tree *v, struct brk_tree *b,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> +int outputfiles(struct trees *, struct stats *);
> int outputheader(FILE *, struct stats *);
> -int output_bgpd(FILE *, struct vrp_tree *, struct brk_tree *,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> -int output_bird(FILE *, struct vrp_tree *, struct brk_tree *,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> -int output_csv(FILE *, struct vrp_tree *, struct brk_tree *,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> -int output_json(FILE *, struct vrp_tree *, struct brk_tree *,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> -int output_ometric(FILE *, struct vrp_tree *, struct brk_tree *,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> +int output_bgpd(FILE *, struct trees *, struct stats *);
> +int output_bird(FILE *, struct trees *, struct stats *);
> +int output_csv(FILE *, struct trees *, struct stats *);
> +int output_json(FILE *, struct trees *, struct stats *);
> +int output_ometric(FILE *, struct trees *, struct stats *);
>
> void logx(const char *fmt, ...)
> __attribute__((format(printf, 1, 2)));
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
> diff -u -p -r1.284 main.c
> --- main.c 26 Jun 2025 06:00:32 -0000 1.284
> +++ main.c 8 Jul 2025 12:40:46 -0000
> @@ -561,9 +561,7 @@ queue_add_from_cert(const struct cert *c
> * In all cases, we gather statistics.
> */
> static void
> -entity_process(struct ibuf *b, struct stats *st, struct vrp_tree *tree,
> - struct brk_tree *brktree, struct vap_tree *vaptree,
> - struct vsp_tree *vsptree, struct nca_tree *ncatree)
> +entity_process(struct ibuf *b, struct stats *st, struct trees *trees)
> {
> enum rtype type;
> struct tal *tal;
> @@ -620,10 +618,10 @@ entity_process(struct ibuf *b, struct st
> switch (cert->purpose) {
> case CERT_PURPOSE_TA:
> case CERT_PURPOSE_CA:
> - queue_add_from_cert(cert, ncatree);
> + queue_add_from_cert(cert, &trees->ncas);
> break;
> case CERT_PURPOSE_BGPSEC_ROUTER:
> - cert_insert_brks(brktree, cert);
> + cert_insert_brks(&trees->brks, cert);
> repo_stat_inc(rp, talid, type, STYPE_BGPSEC);
> break;
> default:
> @@ -642,7 +640,7 @@ entity_process(struct ibuf *b, struct st
> if (mft->seqnum_gap)
> repo_stat_inc(rp, talid, type, STYPE_SEQNUM_GAP);
> queue_add_from_mft(mft);
> - cert_remove_nca(ncatree, mft->certid, rp);
> + cert_remove_nca(&trees->ncas, mft->certid, rp);
> mft_free(mft);
> break;
> case RTYPE_CRL:
> @@ -657,7 +655,7 @@ entity_process(struct ibuf *b, struct st
> }
> roa = roa_read(b);
> if (roa->valid)
> - roa_insert_vrps(tree, roa, rp);
> + roa_insert_vrps(&trees->vrps, roa, rp);
> else
> repo_stat_inc(rp, talid, type, STYPE_INVALID);
> roa_free(roa);
> @@ -672,7 +670,7 @@ entity_process(struct ibuf *b, struct st
> }
> aspa = aspa_read(b);
> if (aspa->valid)
> - aspa_insert_vaps(file, vaptree, aspa, rp);
> + aspa_insert_vaps(file, &trees->vaps, aspa, rp);
> else
> repo_stat_inc(rp, talid, type, STYPE_INVALID);
> aspa_free(aspa);
> @@ -686,7 +684,7 @@ entity_process(struct ibuf *b, struct st
> }
> spl = spl_read(b);
> if (spl->valid)
> - spl_insert_vsps(vsptree, spl, rp);
> + spl_insert_vsps(&trees->vsps, spl, rp);
> else
> repo_stat_inc(rp, talid, type, STYPE_INVALID);
> spl_free(spl);
> @@ -989,16 +987,18 @@ main(int argc, char *argv[])
> const char *cachedir = NULL, *outputdir = NULL;
> const char *errs, *name;
> const char *skiplistfile = NULL;
> - struct vrp_tree vrps = RB_INITIALIZER(&vrps);
> - struct vsp_tree vsps = RB_INITIALIZER(&vsps);
> - struct brk_tree brks = RB_INITIALIZER(&brks);
> - struct vap_tree vaps = RB_INITIALIZER(&vaps);
> - struct nca_tree ncas = RB_INITIALIZER(&ncas);
> + struct trees trees;
> struct rusage ru;
> struct timespec start_time, now_time;
>
> clock_gettime(CLOCK_MONOTONIC, &start_time);
>
> + RB_INIT(&trees.vrps);
> + RB_INIT(&trees.brks);
> + RB_INIT(&trees.vaps);
> + RB_INIT(&trees.vsps);
> + RB_INIT(&trees.ncas);
> +
> /* If started as root, priv-drop to _rpki-client */
> if (getuid() == 0) {
> struct passwd *pw;
> @@ -1414,8 +1414,7 @@ main(int argc, char *argv[])
> errx(1, "ibuf_read: connection closed");
> }
> while ((b = io_buf_get(queues[0])) != NULL) {
> - entity_process(b, &stats, &vrps, &brks, &vaps,
> - &vsps, &ncas);
> + entity_process(b, &stats, &trees);
> ibuf_free(b);
> }
> }
> @@ -1508,7 +1507,7 @@ main(int argc, char *argv[])
> }
> repo_stats_collect(sum_repostats, &stats.repo_stats);
>
> - if (outputfiles(&vrps, &brks, &vaps, &vsps, &ncas, &stats))
> + if (outputfiles(&trees, &stats))
> rc = 1;
>
> printf("Processing time %lld seconds "
> Index: output-bgpd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/output-bgpd.c,v
> diff -u -p -r1.33 output-bgpd.c
> --- output-bgpd.c 27 Mar 2025 05:03:09 -0000 1.33
> +++ output-bgpd.c 8 Jul 2025 12:40:46 -0000
> @@ -20,9 +20,7 @@
> #include "extern.h"
>
> int
> -output_bgpd(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
> - struct vap_tree *vaps, struct vsp_tree *vsps, struct nca_tree *ncas,
> - struct stats *st)
> +output_bgpd(FILE *out, struct trees *trees, struct stats *st)
> {
> struct vrp *vrp;
> struct vap *vap;
> @@ -34,7 +32,7 @@ output_bgpd(FILE *out, struct vrp_tree *
> if (fprintf(out, "roa-set {\n") < 0)
> return -1;
>
> - RB_FOREACH(vrp, vrp_tree, vrps) {
> + RB_FOREACH(vrp, vrp_tree, &trees->vrps) {
> char ipbuf[64], maxlenbuf[100];
>
> ip_addr_print(&vrp->addr, vrp->afi, ipbuf, sizeof(ipbuf));
> @@ -58,7 +56,7 @@ output_bgpd(FILE *out, struct vrp_tree *
>
> if (fprintf(out, "\naspa-set {\n") < 0)
> return -1;
> - RB_FOREACH(vap, vap_tree, vaps) {
> + RB_FOREACH(vap, vap_tree, &trees->vaps) {
> if (vap->overflowed)
> continue;
> if (fprintf(out, "\tcustomer-as %d expires %lld "
> Index: output-bird.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/output-bird.c,v
> diff -u -p -r1.23 output-bird.c
> --- output-bird.c 27 Mar 2025 05:03:09 -0000 1.23
> +++ output-bird.c 8 Jul 2025 12:40:46 -0000
> @@ -21,9 +21,7 @@
> #include "extern.h"
>
> int
> -output_bird(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
> - struct vap_tree *vaps, struct vsp_tree *vsps, struct nca_tree *ncas,
> - struct stats *st)
> +output_bird(FILE *out, struct trees *trees, struct stats *st)
> {
> struct vrp *v;
> struct vap *vap;
> @@ -49,7 +47,7 @@ output_bird(FILE *out, struct vrp_tree *
> "\troa4 { table ROAS4; };\n\n") < 0)
> return -1;
>
> - RB_FOREACH(v, vrp_tree, vrps) {
> + RB_FOREACH(v, vrp_tree, &trees->vrps) {
> char buf[64];
>
> if (v->afi == AFI_IPV4) {
> @@ -64,7 +62,7 @@ output_bird(FILE *out, struct vrp_tree *
> "\troa6 { table ROAS6; };\n\n") < 0)
> return -1;
>
> - RB_FOREACH(v, vrp_tree, vrps) {
> + RB_FOREACH(v, vrp_tree, &trees->vrps) {
> char buf[64];
>
> if (v->afi == AFI_IPV6) {
> @@ -85,7 +83,7 @@ output_bird(FILE *out, struct vrp_tree *
> "};\n\n") < 0)
> return -1;
>
> - RB_FOREACH(vap, vap_tree, vaps) {
> + RB_FOREACH(vap, vap_tree, &trees->vaps) {
> if (vap->overflowed)
> continue;
> if (fprintf(out, "\troute aspa %d providers ",
> Index: output-csv.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/output-csv.c,v
> diff -u -p -r1.15 output-csv.c
> --- output-csv.c 27 Mar 2025 05:03:09 -0000 1.15
> +++ output-csv.c 8 Jul 2025 12:40:46 -0000
> @@ -20,16 +20,14 @@
> #include "extern.h"
>
> int
> -output_csv(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
> - struct vap_tree *vaps, struct vsp_tree *vsps, struct nca_tree *ncas,
> - struct stats *st)
> +output_csv(FILE *out, struct trees *trees, struct stats *st)
> {
> struct vrp *v;
>
> if (fprintf(out, "ASN,IP Prefix,Max Length,Trust Anchor,Expires\n") < 0)
> return -1;
>
> - RB_FOREACH(v, vrp_tree, vrps) {
> + RB_FOREACH(v, vrp_tree, &trees->vrps) {
> char buf[64];
>
> ip_addr_print(&v->addr, v->afi, buf, sizeof(buf));
> Index: output-json.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/output-json.c,v
> diff -u -p -r1.53 output-json.c
> --- output-json.c 3 Apr 2025 14:29:44 -0000 1.53
> +++ output-json.c 8 Jul 2025 12:40:46 -0000
> @@ -145,9 +145,7 @@ output_spl(struct vsp_tree *vsps)
> }
>
> int
> -output_json(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
> - struct vap_tree *vaps, struct vsp_tree *vsps, struct nca_tree *ncas,
> - struct stats *st)
> +output_json(FILE *out, struct trees *trees, struct stats *st)
> {
> char buf[64];
> struct vrp *v;
> @@ -158,7 +156,7 @@ output_json(FILE *out, struct vrp_tree *
> outputheader_json(st);
>
> json_do_array("roas");
> - RB_FOREACH(v, vrp_tree, vrps) {
> + RB_FOREACH(v, vrp_tree, &trees->vrps) {
> ip_addr_print(&v->addr, v->afi, buf, sizeof(buf));
>
> json_do_object("roa", 1);
> @@ -172,7 +170,7 @@ output_json(FILE *out, struct vrp_tree *
> json_do_end();
>
> json_do_array("bgpsec_keys");
> - RB_FOREACH(b, brk_tree, brks) {
> + RB_FOREACH(b, brk_tree, &trees->brks) {
> json_do_object("brks", 0);
> json_do_int("asn", b->asid);
> json_do_string("ski", b->ski);
> @@ -184,7 +182,7 @@ output_json(FILE *out, struct vrp_tree *
> json_do_end();
>
> json_do_array("nonfunc_cas");
> - RB_FOREACH(nca, nca_tree, ncas) {
> + RB_FOREACH(nca, nca_tree, &trees->ncas) {
> json_do_object("nca", 1);
> json_do_string("location", nca->location);
> json_do_string("ta", taldescs[nca->talid]);
> @@ -196,10 +194,10 @@ output_json(FILE *out, struct vrp_tree *
> json_do_end();
>
> if (!excludeaspa)
> - output_aspa(vaps);
> + output_aspa(&trees->vaps);
>
> if (experimental)
> - output_spl(vsps);
> + output_spl(&trees->vsps);
>
> return json_do_finish();
> }
> Index: output-ometric.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/output-ometric.c,v
> diff -u -p -r1.14 output-ometric.c
> --- output-ometric.c 3 Apr 2025 14:29:44 -0000 1.14
> +++ output-ometric.c 8 Jul 2025 12:40:46 -0000
> @@ -167,9 +167,7 @@ repo_stats(const struct repo *rp, const
> }
>
> int
> -output_ometric(FILE *out, struct vrp_tree *vrps, struct brk_tree *brks,
> - struct vap_tree *vaps, struct vsp_tree *vsps, struct nca_tree *ncas,
> - struct stats *st)
> +output_ometric(FILE *out, struct trees *trees, struct stats *st)
> {
> struct olabels *ol;
> const char *keys[4] = { "nodename", "domainname", "release", NULL };
> Index: output.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/output.c,v
> diff -u -p -r1.40 output.c
> --- output.c 3 Apr 2025 14:29:44 -0000 1.40
> +++ output.c 8 Jul 2025 12:40:46 -0000
> @@ -63,9 +63,7 @@ static char output_name[PATH_MAX];
> static const struct outputs {
> int format;
> char *name;
> - int (*fn)(FILE *, struct vrp_tree *, struct brk_tree *,
> - struct vap_tree *, struct vsp_tree *, struct nca_tree *,
> - struct stats *);
> + int (*fn)(FILE *, struct trees *, struct stats *);
> } outputs[] = {
> { FORMAT_OPENBGPD, "openbgpd", output_bgpd },
> { FORMAT_BIRD, "bird", output_bird },
> @@ -124,8 +122,7 @@ prune_as0_tals(struct vrp_tree *vrps)
> }
>
> int
> -outputfiles(struct vrp_tree *v, struct brk_tree *b, struct vap_tree *a,
> - struct vsp_tree *p, struct nca_tree *ncas, struct stats *st)
> +outputfiles(struct trees *trees, struct stats *st)
> {
> int i, rc = 0;
>
> @@ -133,7 +130,7 @@ outputfiles(struct vrp_tree *v, struct b
> set_signal_handler();
>
> if (excludeas0)
> - prune_as0_tals(v);
> + prune_as0_tals(&trees->vrps);
>
> for (i = 0; outputs[i].name; i++) {
> FILE *fout;
> @@ -147,7 +144,7 @@ outputfiles(struct vrp_tree *v, struct b
> rc = 1;
> continue;
> }
> - if ((*outputs[i].fn)(fout, v, b, a, p, ncas, st) != 0) {
> + if ((*outputs[i].fn)(fout, trees, st) != 0) {
> warn("output for %s format failed", outputs[i].name);
> fclose(fout);
> output_cleantmp();
>
--
:wq Claudio
rpki-client: pass around a container struct instead of a long parameter list
rpki-client: pass around a container struct instead of a long parameter list
rpki-client: pass around a container struct instead of a long parameter list