mbox series

[net-next,v2,0/5] tools/net/ynl: Add support for nlctrl netlink family

Message ID 20240306125704.63934-1-donald.hunter@gmail.com (mailing list archive)
Headers show
Series tools/net/ynl: Add support for nlctrl netlink family | expand

Message

Donald Hunter March 6, 2024, 12:56 p.m. UTC
This series adds a new YNL spec for the nlctrl family, plus some fixes
and enhancements for ynl.

Patch 1 fixes an extack decoding bug
Patch 2 gives cleaner netlink error reporting
Patch 3 fixes an array-nest codegen bug
Patch 4 adds nest-type-value support to ynl
Patch 5 contains the nlctrl spec

Changes from v1 -> v2:
 - Added patch 3 to fix codegen bug
 - Removed multi-level array-nest patch
 - Added nest-type-value patch
 - Updated nlctrl spec to align with headers and fix compilation

Donald Hunter (5):
  tools/net/ynl: Fix extack decoding for netlink-raw
  tools/net/ynl: Report netlink errors without stacktrace
  tools/net/ynl: Fix c codegen for array-nest
  tools/net/ynl: Add nest-type-value decoding
  doc/netlink/specs: Add spec for nlctrl netlink family

 Documentation/netlink/specs/nlctrl.yaml | 206 ++++++++++++++++++++++++
 tools/net/ynl/cli.py                    |  18 ++-
 tools/net/ynl/lib/__init__.py           |   4 +-
 tools/net/ynl/lib/ynl.py                |  19 ++-
 tools/net/ynl/ynl-gen-c.py              |   2 +-
 5 files changed, 238 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/netlink/specs/nlctrl.yaml

Comments

Jakub Kicinski March 6, 2024, 6:32 p.m. UTC | #1
On Wed,  6 Mar 2024 12:56:59 +0000 Donald Hunter wrote:
> This series adds a new YNL spec for the nlctrl family, plus some fixes
> and enhancements for ynl.
> 
> Patch 1 fixes an extack decoding bug
> Patch 2 gives cleaner netlink error reporting
> Patch 3 fixes an array-nest codegen bug
> Patch 4 adds nest-type-value support to ynl
> Patch 5 contains the nlctrl spec

Somewhat incredibly the C seems to work, I tested with this sample:

// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <string.h>

#include <ynl.h>

#include "nlctrl-user.h"

int main(int argc, char **argv)
{
	struct nlctrl_getfamily_list *fams;
	struct ynl_error yerr;
	struct ynl_sock *ys;
	char *name;

	ys = ynl_sock_create(&ynl_nlctrl_family, &yerr);
	if (!ys) {
		fprintf(stderr, "YNL: %s\n", yerr.msg);
		return 1;
	}

	printf("Select family ($name; or 0 = dump): ");
	scanf("%ms", &name);

	if (!name || !strcmp(name, "0")) {
		fams = nlctrl_getfamily_dump(ys);
		if (!fams)
			goto err_close;

		ynl_dump_foreach(fams, f)
			printf("%d: %s\n", f->family_id, f->family_name);
		nlctrl_getfamily_list_free(fams);
	} else {
		struct nlctrl_getfamily_req *req;
		struct nlctrl_getfamily_rsp *f;

		req = nlctrl_getfamily_req_alloc();
		nlctrl_getfamily_req_set_family_name(req, name);

		f = nlctrl_getfamily(ys, req);
		nlctrl_getfamily_req_free(req);
		if (!f)
			goto err_close;

		printf("%d: %s\n", f->family_id, f->family_name);
		nlctrl_getfamily_rsp_free(f);
	}
	free(name);

	ynl_sock_destroy(ys);
	return 0;

err_close:
	fprintf(stderr, "YNL: %s\n", ys->err.msg);
	ynl_sock_destroy(ys);
	return 2;
}
Donald Hunter March 6, 2024, 10:14 p.m. UTC | #2
On Wed, 6 Mar 2024 at 18:32, Jakub Kicinski <kuba@kernel.org> wrote:
>
> Somewhat incredibly the C seems to work, I tested with this sample:

Wow, above and beyond for writing a sample. Was it ever in any doubt
that it would work ;-)

> // SPDX-License-Identifier: GPL-2.0
> #include <stdio.h>
> #include <string.h>
>
> #include <ynl.h>
>
> #include "nlctrl-user.h"
>
> int main(int argc, char **argv)
> {
>         struct nlctrl_getfamily_list *fams;
>         struct ynl_error yerr;
>         struct ynl_sock *ys;
>         char *name;
>
>         ys = ynl_sock_create(&ynl_nlctrl_family, &yerr);
>         if (!ys) {
>                 fprintf(stderr, "YNL: %s\n", yerr.msg);
>                 return 1;
>         }
>
>         printf("Select family ($name; or 0 = dump): ");
>         scanf("%ms", &name);
>
>         if (!name || !strcmp(name, "0")) {
>                 fams = nlctrl_getfamily_dump(ys);
>                 if (!fams)
>                         goto err_close;
>
>                 ynl_dump_foreach(fams, f)
>                         printf("%d: %s\n", f->family_id, f->family_name);
>                 nlctrl_getfamily_list_free(fams);
>         } else {
>                 struct nlctrl_getfamily_req *req;
>                 struct nlctrl_getfamily_rsp *f;
>
>                 req = nlctrl_getfamily_req_alloc();
>                 nlctrl_getfamily_req_set_family_name(req, name);
>
>                 f = nlctrl_getfamily(ys, req);
>                 nlctrl_getfamily_req_free(req);
>                 if (!f)
>                         goto err_close;
>
>                 printf("%d: %s\n", f->family_id, f->family_name);
>                 nlctrl_getfamily_rsp_free(f);
>         }
>         free(name);
>
>         ynl_sock_destroy(ys);
>         return 0;
>
> err_close:
>         fprintf(stderr, "YNL: %s\n", ys->err.msg);
>         ynl_sock_destroy(ys);
>         return 2;
> }