From: Claudio Jeker Subject: Re: rpki-client: pass around a container struct instead of a long parameter list To: Job Snijders Cc: tech@openbsd.org Date: Tue, 8 Jul 2025 14:52:20 +0200 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