GNU Linux-libre 6.8.9-gnu
[releases.git] / Documentation / userspace-api / netlink / intro-specs.rst
1 .. SPDX-License-Identifier: BSD-3-Clause
2
3 =====================================
4 Using Netlink protocol specifications
5 =====================================
6
7 This document is a quick starting guide for using Netlink protocol
8 specifications. For more detailed description of the specs see :doc:`specs`.
9
10 Simple CLI
11 ==========
12
13 Kernel comes with a simple CLI tool which should be useful when
14 developing Netlink related code. The tool is implemented in Python
15 and can use a YAML specification to issue Netlink requests
16 to the kernel. Only Generic Netlink is supported.
17
18 The tool is located at ``tools/net/ynl/cli.py``. It accepts
19 a 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
26 YAML specs can be found under ``Documentation/netlink/specs/``.
27
28 Example 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
44 The input arguments are parsed as JSON, while the output is only
45 Python-pretty-printed. This is because some Netlink types can't
46 be expressed as JSON directly. If such attributes are needed in
47 the input some hacking of the script will be necessary.
48
49 The spec and Netlink internals are factored out as a standalone
50 library - it should be easy to write Python tools / tests reusing
51 code from ``cli.py``.
52
53 Generating kernel code
54 ======================
55
56 ``tools/net/ynl/ynl-regen.sh`` scans the kernel tree in search of
57 auto-generated files which need to be updated. Using this tool is the easiest
58 way to generate / update auto-generated code.
59
60 By default code is re-generated only if spec is newer than the source,
61 to 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
65 tracked 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
71 kernel source based on fou.yaml.
72
73 The simplest way to generate a new file based on a spec is to add
74 the two marker lines like above to a file, add that file to git,
75 and run the regeneration tool. Grep the tree for ``YNL-GEN``
76 to see other examples.
77
78 The code generation itself is performed by ``tools/net/ynl/ynl-gen-c.py``
79 but it takes a few arguments so calling it directly for each file
80 quickly becomes tedious.
81
82 YNL 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
89 YNL basics
90 ----------
91
92 The YNL library consists of two parts - the generic code (functions
93 prefix by ``ynl_``) and per-family auto-generated code (prefixed
94 with the name of the family).
95
96 To create a YNL socket call ynl_sock_create() passing the family
97 struct (family structs are exported by the auto-generated code).
98 ynl_sock_destroy() closes the socket.
99
100 YNL requests
101 ------------
102
103 Steps for issuing YNL requests are best explained on an example.
104 All the functions and types in this example come from the auto-generated
105 code (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
134 YNL dumps
135 ---------
136
137 Performing dumps follows similar pattern as requests.
138 Dumps return a list of objects terminated by a special marker,
139 or NULL on error. Use ``ynl_dump_foreach()`` to iterate over
140 the result.
141
142 YNL notifications
143 -----------------
144
145 YNL lib supports using the same socket for notifications and
146 requests. In case notifications arrive during processing of a request
147 they are queued internally and can be retrieved at a later time.
148
149 To subscribed to notifications use ``ynl_subscribe()``.
150 The notifications have to be read out from the socket,
151 ``ynl_socket_get_fd()`` returns the underlying socket fd which can
152 be plugged into appropriate asynchronous IO API like ``poll``,
153 or ``select``.
154
155 Notifications can be retrieved using ``ynl_ntf_dequeue()`` and have
156 to be freed using ``ynl_ntf_free()``. Since we don't know the notification
157 type upfront the notifications are returned as ``struct ynl_ntf_base_type *``
158 and user is expected to cast them to the appropriate full type based
159 on the ``cmd`` member.