From: Claudio Jeker Subject: bgpd: more shuffling of functions for filterset change To: tech@openbsd.org Date: Tue, 3 Feb 2026 11:29:06 +0100 This is another diff that just moves bits around to simplify the big filterset diff I have next. Introduce rde_filter_copy() that takes care of copying a filter rule with all depenencies to a new object. Also check that peer_apply_out_filter() does not return an old list for new peers. Move rde_l3vpn_import() to rde_filter.c since it works on a struct filter_set to match against communities. This is needed since the new code will use a different thing for sets. -- :wq Claudio ? obj Index: bgpd.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v diff -u -p -r1.529 bgpd.h --- bgpd.h 29 Dec 2025 07:48:31 -0000 1.529 +++ bgpd.h 3 Feb 2026 10:19:02 -0000 @@ -1583,7 +1583,8 @@ int pftable_commit(void); void filterset_free(struct filter_set_head *); int filterset_cmp(struct filter_set *, struct filter_set *); void filterset_move(struct filter_set_head *, struct filter_set_head *); -void filterset_copy(struct filter_set_head *, struct filter_set_head *); +void filterset_copy(const struct filter_set_head *, + struct filter_set_head *); const char *filterset_name(enum action_types); int filterset_send(struct imsgbuf *, struct filter_set_head *); void filterset_recv(struct imsg *, struct filter_set_head *); Index: rde.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v diff -u -p -r1.680 rde.c --- rde.c 29 Dec 2025 07:48:31 -0000 1.680 +++ rde.c 3 Feb 2026 10:19:02 -0000 @@ -71,7 +71,6 @@ void rde_dump_ctx_throttle(pid_t, int) void rde_dump_ctx_terminate(pid_t); void rde_dump_mrt_new(struct mrt *, pid_t, int); -int rde_l3vpn_import(struct rde_community *, struct l3vpn *); static void rde_commit_pftable(void); void rde_reload_done(void); static void rde_softreconfig_in_done(void *, uint8_t); @@ -3446,18 +3445,6 @@ rde_dump_mrt_new(struct mrt *mrt, pid_t /* * kroute specific functions */ -int -rde_l3vpn_import(struct rde_community *comm, struct l3vpn *rd) -{ - struct filter_set *s; - - TAILQ_FOREACH(s, &rd->import, entry) { - if (community_match(comm, &s->action.community, 0)) - return (1); - } - return (0); -} - void rde_send_kroute_flush(struct rib *rib) { Index: rde.h =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde.h,v diff -u -p -r1.338 rde.h --- rde.h 3 Feb 2026 10:10:35 -0000 1.338 +++ rde.h 3 Feb 2026 10:19:02 -0000 @@ -548,6 +548,8 @@ void prefix_evaluate_nexthop(struct pr /* rde_filter.c */ void rde_apply_set(struct filter_set_head *, struct rde_peer *, struct rde_peer *, struct filterstate *, u_int8_t); +int rde_l3vpn_import(struct rde_community *, struct l3vpn *); +struct filter_rule *rde_filter_copy(const struct filter_rule *); void rde_filterstate_init(struct filterstate *); void rde_filterstate_prep(struct filterstate *, struct prefix *); void rde_filterstate_copy(struct filterstate *, struct filterstate *); Index: rde_filter.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_filter.c,v diff -u -p -r1.138 rde_filter.c --- rde_filter.c 3 Dec 2025 14:16:21 -0000 1.138 +++ rde_filter.c 3 Feb 2026 10:19:02 -0000 @@ -169,6 +169,18 @@ rde_apply_set(struct filter_set_head *sh } } +int +rde_l3vpn_import(struct rde_community *comm, struct l3vpn *rd) +{ + struct filter_set *s; + + TAILQ_FOREACH(s, &rd->import, entry) { + if (community_match(comm, &s->action.community, 0)) + return (1); + } + return (0); +} + /* return 1 when prefix matches filter_prefix, 0 if not */ static int rde_prefix_match(struct filter_prefix *fp, struct bgpd_addr *prefix, @@ -411,6 +423,18 @@ rde_filter_equal(struct filter_head *a, return (1); } +struct filter_rule * +rde_filter_copy(const struct filter_rule *fr) +{ + struct filter_rule *new; + + if ((new = malloc(sizeof(*new))) == NULL) + fatal(NULL); + *new = *fr; + filterset_copy(&fr->set, &new->set); + return new; +} + void rde_filterstate_init(struct filterstate *state) { @@ -563,7 +587,8 @@ filterset_move(struct filter_set_head *s * copy filterset from source to dest. dest will be initialized first. */ void -filterset_copy(struct filter_set_head *source, struct filter_set_head *dest) +filterset_copy(const struct filter_set_head *source, + struct filter_set_head *dest) { struct filter_set *s, *t; Index: rde_peer.c =================================================================== RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v diff -u -p -r1.65 rde_peer.c --- rde_peer.c 28 Dec 2025 17:52:44 -0000 1.65 +++ rde_peer.c 3 Feb 2026 10:19:02 -0000 @@ -182,7 +182,8 @@ peer_add(uint32_t id, struct peer_config fatal(NULL); adjout_peer_init(peer); - peer_apply_out_filter(peer, rules); + if (peer_apply_out_filter(peer, rules) != NULL) + fatalx("peer add: peer_apply_out_filter failed"); /* * Assign an even random unique transmit path id. @@ -223,11 +224,7 @@ peer_apply_out_filter(struct rde_peer *p if (rde_filter_skip_rule(peer, fr)) continue; - if ((new = malloc(sizeof(*new))) == NULL) - fatal(NULL); - memcpy(new, fr, sizeof(*new)); - filterset_copy(&fr->set, &new->set); - + new = rde_filter_copy(fr); TAILQ_INSERT_TAIL(peer->out_rules, new, entry); }