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