Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
bgpd: fix mrt matching for peer groups
To:
tech@openbsd.org
Date:
Tue, 17 Feb 2026 17:43:07 +0100

Download raw body.

Thread
  • Claudio Jeker:

    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);