tools: ynl: generate code for rt-addr and add a sample
authorJakub Kicinski <kuba@kernel.org>
Thu, 10 Apr 2025 01:46:57 +0000 (18:46 -0700)
committerJakub Kicinski <kuba@kernel.org>
Fri, 11 Apr 2025 03:14:41 +0000 (20:14 -0700)
YNL C can now generate code for simple classic netlink families.
Include rt-addr in the Makefile for generation and add a sample.

  $ ./tools/net/ynl/samples/rt-addr
              lo: 127.0.0.1
       wlp0s20f3: 192.168.1.101
              lo: ::
       wlp0s20f3: fe80::6385:be6:746e:8116
            vpn0: fe80::3597:d353:b5a7:66dd

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Donald Hunter <donald.hunter@gmail.com>
Link: https://patch.msgid.link/20250410014658.782120-13-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/net/ynl/Makefile.deps
tools/net/ynl/generated/Makefile
tools/net/ynl/samples/.gitignore
tools/net/ynl/samples/rt-addr.c [new file with mode: 0644]

index f3269ce39e5b7393c4e5cac18bf4c5b1b4e9c1d9..e55d94211df6c67a15f8d3f65a4bf480d2ec5036 100644 (file)
@@ -29,4 +29,5 @@ CFLAGS_nfsd:=$(call get_hdr_inc,_LINUX_NFSD_NETLINK_H,nfsd_netlink.h)
 CFLAGS_ovs_datapath:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
 CFLAGS_ovs_flow:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
 CFLAGS_ovs_vport:=$(call get_hdr_inc,__LINUX_OPENVSWITCH_H,openvswitch.h)
+CFLAGS_rt-addr:=$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h)
 CFLAGS_tcp_metrics:=$(call get_hdr_inc,_LINUX_TCP_METRICS_H,tcp_metrics.h)
index 21f9e299dc75990b42cddb149341e49867a08e4e..67ce3b8988ef08d4cfd0d374e6fe2c67bbea9fdc 100644 (file)
@@ -25,7 +25,7 @@ SPECS_DIR:=../../../../Documentation/netlink/specs
 GENS_PATHS=$(shell grep -nrI --files-without-match \
                'protocol: netlink' \
                $(SPECS_DIR))
-GENS=$(patsubst $(SPECS_DIR)/%.yaml,%,${GENS_PATHS})
+GENS=$(patsubst $(SPECS_DIR)/%.yaml,%,${GENS_PATHS}) rt-addr
 SRCS=$(patsubst %,%-user.c,${GENS})
 HDRS=$(patsubst %,%-user.h,${GENS})
 OBJS=$(patsubst %,%-user.o,${GENS})
index dda6686257a7cbac8496d5159d421e095e6edd51..2bc8721d61441dcb51663fbfd2f593aaa08ebb0c 100644 (file)
@@ -2,4 +2,5 @@ ethtool
 devlink
 netdev
 ovs
-page-pool
\ No newline at end of file
+page-pool
+rt-addr
diff --git a/tools/net/ynl/samples/rt-addr.c b/tools/net/ynl/samples/rt-addr.c
new file mode 100644 (file)
index 0000000..0f4851b
--- /dev/null
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <stdio.h>
+#include <string.h>
+
+#include <ynl.h>
+
+#include <arpa/inet.h>
+#include <net/if.h>
+
+#include "rt-addr-user.h"
+
+static void rt_addr_print(struct rt_addr_getaddr_rsp *a)
+{
+       char ifname[IF_NAMESIZE];
+       char addr_str[64];
+       const char *addr;
+       const char *name;
+
+       name = if_indextoname(a->_hdr.ifa_index, ifname);
+       if (name)
+               printf("%16s: ", name);
+
+       switch (a->_present.address_len) {
+       case 4:
+               addr = inet_ntop(AF_INET, a->address,
+                                addr_str, sizeof(addr_str));
+               break;
+       case 16:
+               addr = inet_ntop(AF_INET6, a->address,
+                                addr_str, sizeof(addr_str));
+               break;
+       default:
+               addr = NULL;
+               break;
+       }
+       if (addr)
+               printf("%s", addr);
+       else
+               printf("[%d]", a->_present.address_len);
+
+       printf("\n");
+}
+
+int main(int argc, char **argv)
+{
+       struct rt_addr_getaddr_list *rsp;
+       struct rt_addr_getaddr_req *req;
+       struct ynl_error yerr;
+       struct ynl_sock *ys;
+
+       ys = ynl_sock_create(&ynl_rt_addr_family, &yerr);
+       if (!ys) {
+               fprintf(stderr, "YNL: %s\n", yerr.msg);
+               return 1;
+       }
+
+       req = rt_addr_getaddr_req_alloc();
+       if (!req)
+               goto err_destroy;
+
+       rsp = rt_addr_getaddr_dump(ys, req);
+       rt_addr_getaddr_req_free(req);
+       if (!rsp)
+               goto err_close;
+
+       if (ynl_dump_empty(rsp))
+               fprintf(stderr, "Error: no addresses reported\n");
+       ynl_dump_foreach(rsp, addr)
+               rt_addr_print(addr);
+       rt_addr_getaddr_list_free(rsp);
+
+       ynl_sock_destroy(ys);
+       return 0;
+
+err_close:
+       fprintf(stderr, "YNL: %s\n", ys->err.msg);
+err_destroy:
+       ynl_sock_destroy(ys);
+       return 2;
+}