Commit 504acff0ba for frr
commit 504acff0ba272a87534630c05c74457177e94c67
Author: Minghan Chan <mhchann082@gmail.com>
Date: Wed Oct 14 09:31:09 2026 +0800
bgpd: search every instance for a peer-group with vrf all
"show bgp vrf all ... neighbors WORD received-routes" and the other
per-neighbor show commands that accept "vrf all" pass a NULL instance
to peer_lookup_in_view(). The address, interface-name and hostname
lookups there take NULL to mean every instance, but the peer-group
lookup added by c4d4682ae1 ("bgpd: Handle peer-group also when showing
advertised routes") dereferences it. bgpd crashes on any name that is
not an interface or a hostname, whether or not a peer-group by that
name exists.
Without an instance, look the group up in every instance as the other
lookups do. Skip groups that have no members while doing so, so that
an empty group in one instance does not hide a group of the same name
with members in another.
Fixes: https://github.com/FRRouting/frr/issues/23542
Signed-off-by: Minghan Chan <mhchann082@gmail.com>
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index b30483ca83..324754ad84 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -9907,13 +9907,37 @@ void bgp_terminate(void)
#endif
}
+/*
+ * First member of peer-group @name. A NULL @bgp means "vrf all": search every
+ * instance, as the other peer lookups do, and skip groups that have no members
+ * so that an empty group of the same name does not hide a populated one.
+ */
+static struct peer *peer_group_lookup_member(struct bgp *bgp, const char *name)
+{
+ struct peer_group *group;
+ struct listnode *node;
+ struct peer *peer;
+
+ if (bgp) {
+ group = peer_group_lookup(bgp, name);
+ return group ? listnode_head(group->peer) : NULL;
+ }
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) {
+ peer = peer_group_lookup_member(bgp, name);
+ if (peer)
+ return peer;
+ }
+
+ return NULL;
+}
+
struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
const char *ip_str, bool use_json)
{
int ret;
struct peer *peer;
union sockunion su;
- struct peer_group *group;
/* Get peer sockunion. */
ret = str2sockunion(ip_str, &su);
@@ -9922,11 +9946,8 @@ struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
if (!peer) {
peer = peer_lookup_by_hostname(bgp, ip_str);
- if (!peer) {
- group = peer_group_lookup(bgp, ip_str);
- if (group)
- peer = listnode_head(group->peer);
- }
+ if (!peer)
+ peer = peer_group_lookup_member(bgp, ip_str);
if (!peer) {
if (use_json) {