Commit edc3b7cdc9 for frr
commit edc3b7cdc913a2d652553f41fae75554b2356ef0
Author: Yuqing Zhao <galadriel.zyq@alibaba-inc.com>
Date: Mon Sep 14 19:04:13 2026 +0800
zebra: Add resolved-via attribute to fpm_listener dump
FPM nexthop-group messages can carry the NHA_FPM_RESOLVED_VIA
attribute, the id of the nexthop group that resolved a nexthop.
The fpm_listener's attribute table only covered the kernel's NHA_*
values, so the attribute was treated as unknown and dropped.
Decode and store the attribute, and print it in the SIGUSR1 dump as
", ResolvedVia: %u", so the FPM topotests can verify the values zebra
sends over the FPM pipe.
Signed-off-by: Yuqing Zhao <galadriel.zyq@alibaba-inc.com>
diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c
index fa802b2007..ceb219ace1 100644
--- a/zebra/fpm_listener.c
+++ b/zebra/fpm_listener.c
@@ -85,6 +85,8 @@ struct fpm_nhg {
uint8_t scope; /* Scope */
bool is_blackhole; /* Is this a blackhole nexthop? */
uint8_t num_nexthops; /* Number of nexthops in the group */
+ /* Resolving nexthop group ID, if the resolved-via attr was received */
+ uint32_t resolved_via;
/* Individual nexthops in the group */
struct {
@@ -657,7 +659,7 @@ static void handle_nexthop_update(struct nlmsghdr *hdr, struct nhmsg *nhmsg, str
static int parse_nexthop_msg(struct nlmsghdr *hdr)
{
struct nhmsg *nhmsg;
- struct rtattr *tb[NHA_MAX + 1] = {};
+ struct rtattr *tb[NHA_FPM_MAX] = {};
int len;
uint32_t nhgid = 0;
uint16_t nhg_count = 0;
@@ -936,6 +938,7 @@ static void handle_nexthop_update(struct nlmsghdr *hdr, struct nhmsg *nhmsg, str
struct fpm_nhg *existing;
struct fpm_nhg lookup = { 0 };
uint32_t nhgid = 0;
+ uint32_t resolved_via = 0;
uint16_t nhg_count = 0;
/* Get Nexthop Group ID */
@@ -944,6 +947,11 @@ static void handle_nexthop_update(struct nlmsghdr *hdr, struct nhmsg *nhmsg, str
else
return; /* Can't process without an ID */
+ /* Get resolving nexthop group ID, if present */
+ if (tb[NHA_FPM_RESOLVED_VIA] &&
+ RTA_PAYLOAD(tb[NHA_FPM_RESOLVED_VIA]) >= sizeof(resolved_via))
+ resolved_via = *(uint32_t *)RTA_DATA(tb[NHA_FPM_RESOLVED_VIA]);
+
/* Count nexthops in the group */
if (tb[NHA_GROUP]) {
size_t count = (RTA_PAYLOAD(tb[NHA_GROUP]) / sizeof(struct nexthop_group));
@@ -971,6 +979,7 @@ static void handle_nexthop_update(struct nlmsghdr *hdr, struct nhmsg *nhmsg, str
existing->scope = nhmsg->nh_scope;
existing->is_blackhole = tb[NHA_BLACKHOLE] ? true : false;
existing->num_nexthops = nhg_count;
+ existing->resolved_via = resolved_via;
/* Update individual nexthop IDs and weights */
if (tb[NHA_GROUP]) {
@@ -999,6 +1008,7 @@ static void handle_nexthop_update(struct nlmsghdr *hdr, struct nhmsg *nhmsg, str
nhg->scope = nhmsg->nh_scope;
nhg->is_blackhole = tb[NHA_BLACKHOLE] ? true : false;
nhg->num_nexthops = nhg_count;
+ nhg->resolved_via = resolved_via;
/* Store individual nexthop IDs and weights */
if (tb[NHA_GROUP]) {
@@ -1159,6 +1169,9 @@ static void sigusr1_handler(int signum)
nhg->num_nexthops ? nhg->num_nexthops : 1,
nhg->is_blackhole ? "BLACKHOLE" : "");
+ if (nhg->resolved_via)
+ fprintf(out, ", ResolvedVia: %u", nhg->resolved_via);
+
/* Display individual nexthops if any */
if (nhg->num_nexthops > 0 && !nhg->is_blackhole) {
if (nhg->nexthops[0].id == 0) {