All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
	andrew+netdev@lunn.ch, horms@kernel.org, donald.hunter@gmail.com,
	jacob.e.keller@intel.com, yuyanghuang@google.com,
	sdf@fomichev.me, gnault@redhat.com, nicolas.dichtel@6wind.com,
	petrm@nvidia.com, Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 07/13] tools: ynl: support creating non-genl sockets
Date: Tue,  8 Apr 2025 17:03:54 -0700	[thread overview]
Message-ID: <20250409000400.492371-8-kuba@kernel.org> (raw)
In-Reply-To: <20250409000400.492371-1-kuba@kernel.org>

Classic netlink has static family IDs specified in YAML,
there is no family name -> ID lookup. Support providing
the ID info to the library via the generated struct and
make library use it. Since NETLINK_ROUTE is ID 0 we need
an extra boolean to indicate classic_id is to be used.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/net/ynl/lib/ynl.h          |  3 ++
 tools/net/ynl/lib/ynl.c          | 51 +++++++++++++++++++++-----------
 tools/net/ynl/pyynl/ynl_gen_c.py |  9 ++++--
 3 files changed, 43 insertions(+), 20 deletions(-)

diff --git a/tools/net/ynl/lib/ynl.h b/tools/net/ynl/lib/ynl.h
index 6cd570b283ea..59256e258130 100644
--- a/tools/net/ynl/lib/ynl.h
+++ b/tools/net/ynl/lib/ynl.h
@@ -2,6 +2,7 @@
 #ifndef __YNL_C_H
 #define __YNL_C_H 1
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <linux/genetlink.h>
 #include <linux/types.h>
@@ -48,6 +49,8 @@ struct ynl_family {
 /* private: */
 	const char *name;
 	size_t hdr_len;
+	bool is_classic;
+	__u16 classic_id;
 	const struct ynl_ntf_info *ntf_info;
 	unsigned int ntf_info_size;
 };
diff --git a/tools/net/ynl/lib/ynl.c b/tools/net/ynl/lib/ynl.c
index ce32cb35007d..b9fda1a99453 100644
--- a/tools/net/ynl/lib/ynl.c
+++ b/tools/net/ynl/lib/ynl.c
@@ -663,6 +663,7 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
 	struct sockaddr_nl addr;
 	struct ynl_sock *ys;
 	socklen_t addrlen;
+	int sock_type;
 	int one = 1;
 
 	ys = malloc(sizeof(*ys) + 2 * YNL_SOCKET_BUFFER_SIZE);
@@ -675,7 +676,9 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
 	ys->rx_buf = &ys->raw_buf[YNL_SOCKET_BUFFER_SIZE];
 	ys->ntf_last_next = &ys->ntf_first;
 
-	ys->socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+	sock_type = yf->is_classic ? yf->classic_id : NETLINK_GENERIC;
+
+	ys->socket = socket(AF_NETLINK, SOCK_RAW, sock_type);
 	if (ys->socket < 0) {
 		__perr(yse, "failed to create a netlink socket");
 		goto err_free_sock;
@@ -708,8 +711,9 @@ ynl_sock_create(const struct ynl_family *yf, struct ynl_error *yse)
 	ys->portid = addr.nl_pid;
 	ys->seq = random();
 
-
-	if (ynl_sock_read_family(ys, yf->name)) {
+	if (yf->is_classic) {
+		ys->family_id = yf->classic_id;
+	} else if (ynl_sock_read_family(ys, yf->name)) {
 		if (yse)
 			memcpy(yse, &ys->err, sizeof(*yse));
 		goto err_close_sock;
@@ -791,13 +795,21 @@ static int ynl_ntf_parse(struct ynl_sock *ys, const struct nlmsghdr *nlh)
 	struct ynl_parse_arg yarg = { .ys = ys, };
 	const struct ynl_ntf_info *info;
 	struct ynl_ntf_base_type *rsp;
-	struct genlmsghdr *gehdr;
+	__u32 cmd;
 	int ret;
 
-	gehdr = ynl_nlmsg_data(nlh);
-	if (gehdr->cmd >= ys->family->ntf_info_size)
+	if (ys->family->is_classic) {
+		cmd = nlh->nlmsg_type;
+	} else {
+		struct genlmsghdr *gehdr;
+
+		gehdr = ynl_nlmsg_data(nlh);
+		cmd = gehdr->cmd;
+	}
+
+	if (cmd >= ys->family->ntf_info_size)
 		return YNL_PARSE_CB_ERROR;
-	info = &ys->family->ntf_info[gehdr->cmd];
+	info = &ys->family->ntf_info[cmd];
 	if (!info->cb)
 		return YNL_PARSE_CB_ERROR;
 
@@ -811,7 +823,7 @@ static int ynl_ntf_parse(struct ynl_sock *ys, const struct nlmsghdr *nlh)
 		goto err_free;
 
 	rsp->family = nlh->nlmsg_type;
-	rsp->cmd = gehdr->cmd;
+	rsp->cmd = cmd;
 
 	*ys->ntf_last_next = rsp;
 	ys->ntf_last_next = &rsp->next;
@@ -863,18 +875,23 @@ int ynl_error_parse(struct ynl_parse_arg *yarg, const char *msg)
 static int
 ynl_check_alien(struct ynl_sock *ys, const struct nlmsghdr *nlh, __u32 rsp_cmd)
 {
-	struct genlmsghdr *gehdr;
+	if (ys->family->is_classic) {
+		if (nlh->nlmsg_type != rsp_cmd)
+			return ynl_ntf_parse(ys, nlh);
+	} else {
+		struct genlmsghdr *gehdr;
 
-	if (ynl_nlmsg_data_len(nlh) < sizeof(*gehdr)) {
-		yerr(ys, YNL_ERROR_INV_RESP,
-		     "Kernel responded with truncated message");
-		return -1;
+		if (ynl_nlmsg_data_len(nlh) < sizeof(*gehdr)) {
+			yerr(ys, YNL_ERROR_INV_RESP,
+			     "Kernel responded with truncated message");
+			return -1;
+		}
+
+		gehdr = ynl_nlmsg_data(nlh);
+		if (gehdr->cmd != rsp_cmd)
+			return ynl_ntf_parse(ys, nlh);
 	}
 
-	gehdr = ynl_nlmsg_data(nlh);
-	if (gehdr->cmd != rsp_cmd)
-		return ynl_ntf_parse(ys, nlh);
-
 	return 0;
 }
 
diff --git a/tools/net/ynl/pyynl/ynl_gen_c.py b/tools/net/ynl/pyynl/ynl_gen_c.py
index a1427c537030..9e00aac4801c 100755
--- a/tools/net/ynl/pyynl/ynl_gen_c.py
+++ b/tools/net/ynl/pyynl/ynl_gen_c.py
@@ -971,9 +971,6 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
     def resolve(self):
         self.resolve_up(super())
 
-        if self.yaml.get('protocol', 'genetlink') not in {'genetlink', 'genetlink-c', 'genetlink-legacy'}:
-            raise Exception("Codegen only supported for genetlink")
-
         self.c_name = c_lower(self.ident_name)
         if 'name-prefix' in self.yaml['operations']:
             self.op_prefix = c_upper(self.yaml['operations']['name-prefix'])
@@ -1020,6 +1017,9 @@ from lib import SpecFamily, SpecAttrSet, SpecAttr, SpecOperation, SpecEnumSet, S
     def new_operation(self, elem, req_value, rsp_value):
         return Operation(self, elem, req_value, rsp_value)
 
+    def is_classic(self):
+        return self.proto == 'netlink-raw'
+
     def _mark_notify(self):
         for op in self.msgs.values():
             if 'notify' in op:
@@ -2730,6 +2730,9 @@ _C_KW = {
 
     cw.block_start(f'{symbol} = ')
     cw.p(f'.name\t\t= "{family.c_name}",')
+    if family.is_classic():
+        cw.p(f'.is_classic\t= true,')
+        cw.p(f'.classic_id\t= {family.get("protonum")},')
     if family.fixed_header:
         cw.p(f'.hdr_len\t= sizeof(struct genlmsghdr) + sizeof(struct {c_lower(family.fixed_header)}),')
     else:
-- 
2.49.0


  parent reply	other threads:[~2025-04-09  0:04 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-09  0:03 [PATCH net-next 00/13] tools: ynl: c: basic netlink-raw support Jakub Kicinski
2025-04-09  0:03 ` [PATCH net-next 01/13] netlink: specs: rename rtnetlink specs in accordance with family name Jakub Kicinski
2025-04-09  4:49   ` Jacob Keller
2025-04-09 12:15     ` Donald Hunter
2025-04-09 14:15       ` Jakub Kicinski
2025-04-09 14:36         ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 02/13] netlink: specs: rt-route: specify fixed-header at operations level Jakub Kicinski
2025-04-09  4:50   ` Jacob Keller
2025-04-09 12:16   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 03/13] netlink: specs: rt-addr: remove the fixed members from attrs Jakub Kicinski
2025-04-09  4:53   ` Jacob Keller
2025-04-09  4:58     ` Jacob Keller
2025-04-09 12:19   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 04/13] netlink: specs: rt-route: " Jakub Kicinski
2025-04-09  4:58   ` Jacob Keller
2025-04-09 12:20   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 05/13] netlink: specs: rt-addr: add C naming info Jakub Kicinski
2025-04-09  4:54   ` Jacob Keller
2025-04-09 12:21   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 06/13] netlink: specs: rt-route: " Jakub Kicinski
2025-04-09  4:54   ` Jacob Keller
2025-04-09 12:21   ` Donald Hunter
2025-04-09  0:03 ` Jakub Kicinski [this message]
2025-04-09  4:56   ` [PATCH net-next 07/13] tools: ynl: support creating non-genl sockets Jacob Keller
2025-04-09 12:25   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 08/13] tools: ynl-gen: don't consider requests with fixed hdr empty Jakub Kicinski
2025-04-09  4:57   ` Jacob Keller
2025-04-09  0:03 ` [PATCH net-next 09/13] tools: ynl: don't use genlmsghdr in classic netlink Jakub Kicinski
2025-04-09  4:59   ` Jacob Keller
2025-04-09 12:26   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 10/13] tools: ynl-gen: consider dump ops without a do "type-consistent" Jakub Kicinski
2025-04-09  5:01   ` Jacob Keller
2025-04-09 12:38   ` Donald Hunter
2025-04-09 13:52     ` Jakub Kicinski
2025-04-09 21:58       ` Jacob Keller
2025-04-09  0:03 ` [PATCH net-next 11/13] tools: ynl-gen: use family c-name in notifications Jakub Kicinski
2025-04-09  5:01   ` Jacob Keller
2025-04-09 12:38   ` Donald Hunter
2025-04-09  0:03 ` [PATCH net-next 12/13] tools: ynl: generate code for rt-addr and add a sample Jakub Kicinski
2025-04-09  5:04   ` Jacob Keller
2025-04-09 15:01     ` Jakub Kicinski
2025-04-09 12:50   ` Donald Hunter
2025-04-09  0:04 ` [PATCH net-next 13/13] tools: ynl: generate code for rt-route " Jakub Kicinski
2025-04-09  5:05   ` Jacob Keller
2025-04-09 12:49   ` Donald Hunter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250409000400.492371-8-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=donald.hunter@gmail.com \
    --cc=edumazet@google.com \
    --cc=gnault@redhat.com \
    --cc=horms@kernel.org \
    --cc=jacob.e.keller@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=nicolas.dichtel@6wind.com \
    --cc=pabeni@redhat.com \
    --cc=petrm@nvidia.com \
    --cc=sdf@fomichev.me \
    --cc=yuyanghuang@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.