Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
Note: File does not exist in v5.14.15.
  1.. SPDX-License-Identifier: BSD-3-Clause
  2
  3=====================================
  4Using Netlink protocol specifications
  5=====================================
  6
  7This document is a quick starting guide for using Netlink protocol
  8specifications. For more detailed description of the specs see :doc:`specs`.
  9
 10Simple CLI
 11==========
 12
 13Kernel comes with a simple CLI tool which should be useful when
 14developing Netlink related code. The tool is implemented in Python
 15and can use a YAML specification to issue Netlink requests
 16to the kernel. Only Generic Netlink is supported.
 17
 18The tool is located at ``tools/net/ynl/cli.py``. It accepts
 19a handul of arguments, the most important ones are:
 20
 21 - ``--spec`` - point to the spec file
 22 - ``--do $name`` / ``--dump $name`` - issue request ``$name``
 23 - ``--json $attrs`` - provide attributes for the request
 24 - ``--subscribe $group`` - receive notifications from ``$group``
 25
 26YAML specs can be found under ``Documentation/netlink/specs/``.
 27
 28Example use::
 29
 30  $ ./tools/net/ynl/cli.py --spec Documentation/netlink/specs/ethtool.yaml \
 31        --do rings-get \
 32	--json '{"header":{"dev-index": 18}}'
 33  {'header': {'dev-index': 18, 'dev-name': 'eni1np1'},
 34   'rx': 0,
 35   'rx-jumbo': 0,
 36   'rx-jumbo-max': 4096,
 37   'rx-max': 4096,
 38   'rx-mini': 0,
 39   'rx-mini-max': 4096,
 40   'tx': 0,
 41   'tx-max': 4096,
 42   'tx-push': 0}
 43
 44The input arguments are parsed as JSON, while the output is only
 45Python-pretty-printed. This is because some Netlink types can't
 46be expressed as JSON directly. If such attributes are needed in
 47the input some hacking of the script will be necessary.
 48
 49The spec and Netlink internals are factored out as a standalone
 50library - it should be easy to write Python tools / tests reusing
 51code from ``cli.py``.
 52
 53Generating kernel code
 54======================
 55
 56``tools/net/ynl/ynl-regen.sh`` scans the kernel tree in search of
 57auto-generated files which need to be updated. Using this tool is the easiest
 58way to generate / update auto-generated code.
 59
 60By default code is re-generated only if spec is newer than the source,
 61to force regeneration use ``-f``.
 62
 63``ynl-regen.sh`` searches for ``YNL-GEN`` in the contents of files
 64(note that it only scans files in the git index, that is only files
 65tracked by git!) For instance the ``fou_nl.c`` kernel source contains::
 66
 67  /*	Documentation/netlink/specs/fou.yaml */
 68  /* YNL-GEN kernel source */
 69
 70``ynl-regen.sh`` will find this marker and replace the file with
 71kernel source based on fou.yaml.
 72
 73The simplest way to generate a new file based on a spec is to add
 74the two marker lines like above to a file, add that file to git,
 75and run the regeneration tool. Grep the tree for ``YNL-GEN``
 76to see other examples.
 77
 78The code generation itself is performed by ``tools/net/ynl/ynl-gen-c.py``
 79but it takes a few arguments so calling it directly for each file
 80quickly becomes tedious.
 81
 82YNL lib
 83=======
 84
 85``tools/net/ynl/lib/`` contains an implementation of a C library
 86(based on libmnl) which integrates with code generated by
 87``tools/net/ynl/ynl-gen-c.py`` to create easy to use netlink wrappers.
 88
 89YNL basics
 90----------
 91
 92The YNL library consists of two parts - the generic code (functions
 93prefix by ``ynl_``) and per-family auto-generated code (prefixed
 94with the name of the family).
 95
 96To create a YNL socket call ynl_sock_create() passing the family
 97struct (family structs are exported by the auto-generated code).
 98ynl_sock_destroy() closes the socket.
 99
100YNL requests
101------------
102
103Steps for issuing YNL requests are best explained on an example.
104All the functions and types in this example come from the auto-generated
105code (for the netdev family in this case):
106
107.. code-block:: c
108
109   // 0. Request and response pointers
110   struct netdev_dev_get_req *req;
111   struct netdev_dev_get_rsp *d;
112
113   // 1. Allocate a request
114   req = netdev_dev_get_req_alloc();
115   // 2. Set request parameters (as needed)
116   netdev_dev_get_req_set_ifindex(req, ifindex);
117
118   // 3. Issues the request
119   d = netdev_dev_get(ys, req);
120   // 4. Free the request arguments
121   netdev_dev_get_req_free(req);
122   // 5. Error check (the return value from step 3)
123   if (!d) {
124	// 6. Print the YNL-generated error
125	fprintf(stderr, "YNL: %s\n", ys->err.msg);
126        return -1;
127   }
128
129   // ... do stuff with the response @d
130
131   // 7. Free response
132   netdev_dev_get_rsp_free(d);
133
134YNL dumps
135---------
136
137Performing dumps follows similar pattern as requests.
138Dumps return a list of objects terminated by a special marker,
139or NULL on error. Use ``ynl_dump_foreach()`` to iterate over
140the result.
141
142YNL notifications
143-----------------
144
145YNL lib supports using the same socket for notifications and
146requests. In case notifications arrive during processing of a request
147they are queued internally and can be retrieved at a later time.
148
149To subscribed to notifications use ``ynl_subscribe()``.
150The notifications have to be read out from the socket,
151``ynl_socket_get_fd()`` returns the underlying socket fd which can
152be plugged into appropriate asynchronous IO API like ``poll``,
153or ``select``.
154
155Notifications can be retrieved using ``ynl_ntf_dequeue()`` and have
156to be freed using ``ynl_ntf_free()``. Since we don't know the notification
157type upfront the notifications are returned as ``struct ynl_ntf_base_type *``
158and user is expected to cast them to the appropriate full type based
159on the ``cmd`` member.