Download raw body.
bgpd: fix mrt matching for peer groups
Noticed the hard way. If you set a dump directive on a peer inside a group
that peer directive is wrongly applied to all peers and not only the
single peer.
This comes from the fact that the group_id is set even for peer dumps and
this confuses the code in session.c::session_mrt_dump_state() etc.
Fixing this is simple, set group_id only for group matches.
This caused another issue in printconf.c since there the logic is also not
quite right. I tried to use a similar check in print_mrt() as is done in
session.c and added some comment since it is not so obvious.
The diff below should fix those issues.
--
:wq Claudio
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/parse.y,v
diff -u -p -r1.487 parse.y
--- parse.y 6 Dec 2025 09:48:30 -0000 1.487
+++ parse.y 17 Feb 2026 14:16:18 -0000
@@ -4768,7 +4768,7 @@ add_mrtconfig(enum mrt_type type, char *
n->group_id = p->conf.id;
} else {
n->peer_id = p->conf.id;
- n->group_id = p->conf.groupid;
+ n->group_id = 0;
}
}
if (rib) {
Index: printconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/printconf.c,v
diff -u -p -r1.184 printconf.c
--- printconf.c 4 Feb 2026 13:49:23 -0000 1.184
+++ printconf.c 17 Feb 2026 15:30:58 -0000
@@ -1193,9 +1193,15 @@ print_mrt(struct bgpd_config *conf, uint
if (conf->mrt == NULL)
return;
+ /*
+ * If pid == 0 then this needs to match for the any config rule
+ * and in that case gid == 0 as well. If pid != 0 then either
+ * match against peer_id or group_id depending which one is set.
+ */
LIST_FOREACH(m, conf->mrt, entry)
- if ((gid != 0 && m->group_id == gid) ||
- (m->peer_id == pid && m->group_id == gid)) {
+ if ((pid == 0 && m->peer_id == 0 && m->group_id == 0) ||
+ (m->peer_id != 0 && m->peer_id == pid) ||
+ (m->group_id != 0 && m->group_id == gid)) {
printf("%s%sdump ", prep, prep2);
if (m->rib[0])
printf("rib %s ", m->rib);
bgpd: fix mrt matching for peer groups