]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: modify fpm_listener to display data about nhgs 18640/head
authorDonald Sharp <sharpd@nvidia.com>
Thu, 10 Apr 2025 20:57:10 +0000 (16:57 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Thu, 10 Apr 2025 21:14:38 +0000 (17:14 -0400)
Currently the fpm_listener completely ignores NHG's.
Let's start dumping some data about the nexthop groups:

[2025-04-10 16:55:12.939235306] FPM message - Type: 1, Length 52
[2025-04-10 16:55:12.939254252] Nexthop Group ID: 9, Protocol: Zebra(11), Contains 1 nexthops, Family: 2, Scope: 0
[2025-04-10 16:55:12.939260564] FPM message - Type: 1, Length 52
[2025-04-10 16:55:12.939263990] Nexthop Group ID: 10, Protocol: Zebra(11), Contains 1 nexthops, Family: 2, Scope: 0
[2025-04-10 16:55:12.939268659] FPM message - Type: 1, Length 56
[2025-04-10 16:55:12.939271635] Nexthop Group ID: 8, Protocol: Zebra(11), Contains 2 nexthops, Family: 0, Scope: 0

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
zebra/fpm_listener.c

index 70dcaf91a1aefeb8c0f8eb325119c92ada9d553e..7ae9601ef4e3141dc3daa3c4d48a92b0a205c374 100644 (file)
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_link.h>
+#include <linux/nexthop.h>
 
 #include "rt_netlink.h"
 #include "fpm/fpm.h"
 #include "lib/libfrr.h"
+#include "zebra/kernel_netlink.h"
 
 XREF_SETUP();
 
@@ -572,6 +574,67 @@ static int parse_route_msg(struct netlink_msg_ctx *ctx)
        return 1;
 }
 
+/*
+ * parse_nexthop_msg
+ */
+static int parse_nexthop_msg(struct nlmsghdr *hdr)
+{
+       struct nhmsg *nhmsg;
+       struct rtattr *tb[NHA_MAX + 1] = {};
+       int len;
+       uint32_t nhgid = 0;
+       uint8_t nhg_count = 0;
+       const char *err_msg = NULL;
+       char protocol_str[32] = "Unknown";
+
+       nhmsg = NLMSG_DATA(hdr);
+       len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*nhmsg));
+       if (len < 0) {
+               fprintf(stderr, "Bad nexthop message length\n");
+               return 0;
+       }
+
+       if (!parse_rtattrs_(RTM_NHA(nhmsg), len, tb, ARRAY_SIZE(tb), &err_msg)) {
+               fprintf(stderr, "Error parsing nexthop attributes: %s\n", err_msg);
+               return 0;
+       }
+
+       /* Get protocol string */
+       snprintf(protocol_str, sizeof(protocol_str), "%s(%u)",
+                netlink_prot_to_s(nhmsg->nh_protocol), nhmsg->nh_protocol);
+
+       /* Get Nexthop Group ID */
+       if (tb[NHA_ID])
+               nhgid = *(uint32_t *)RTA_DATA(tb[NHA_ID]);
+
+       /* Count nexthops in the group */
+       if (tb[NHA_GROUP]) {
+               struct nexthop_grp *nhg = (struct nexthop_grp *)RTA_DATA(tb[NHA_GROUP]);
+               size_t count = (RTA_PAYLOAD(tb[NHA_GROUP]) / sizeof(*nhg));
+
+               if (count > 0 && (count * sizeof(*nhg)) == RTA_PAYLOAD(tb[NHA_GROUP]))
+                       nhg_count = count;
+       } else if (tb[NHA_OIF] || tb[NHA_GATEWAY]) {
+               /* Single nexthop case */
+               nhg_count = 1;
+       }
+
+       /* Print blackhole status if applicable */
+       if (tb[NHA_BLACKHOLE]) {
+               fprintf(glob->output_file,
+                       "[%s] %s Nexthop Group ID: %u, Protocol: %s, Type: BLACKHOLE, Family: %u\n",
+                       get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid,
+                       protocol_str, nhmsg->nh_family);
+       } else {
+               fprintf(glob->output_file,
+                       "[%s] %s Nexthop Group ID: %u, Protocol: %s, Contains %u nexthops, Family: %u, Scope: %u\n",
+                       get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid,
+                       protocol_str, nhg_count, nhmsg->nh_family, nhmsg->nh_scope);
+       }
+
+       return 1;
+}
+
 /*
  * addr_to_s
  */
@@ -742,6 +805,11 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
                        }
                        break;
 
+               case RTM_NEWNEXTHOP:
+               case RTM_DELNEXTHOP:
+                       parse_nexthop_msg(hdr);
+                       break;
+
                default:
                        fprintf(glob->output_file, "[%s] Ignoring netlink message - Type: %s(%d)\n",
                                get_timestamp(), netlink_msg_type_to_s(hdr->nlmsg_type),