1.. SPDX-License-Identifier: BSD-3-Clause 2 3================================================================= 4Netlink specification support for legacy Generic Netlink families 5================================================================= 6 7This document describes the many additional quirks and properties 8required to describe older Generic Netlink families which form 9the ``genetlink-legacy`` protocol level. 10 11The spec is a work in progress, some of the quirks are just documented 12for future reference. 13 14Specification (defined) 15======================= 16 17Attribute type nests 18-------------------- 19 20New Netlink families should use ``multi-attr`` to define arrays. 21Older families (e.g. ``genetlink`` control family) attempted to 22define array types reusing attribute type to carry information. 23 24For reference the ``multi-attr`` array may look like this:: 25 26 [ARRAY-ATTR] 27 [INDEX (optionally)] 28 [MEMBER1] 29 [MEMBER2] 30 [SOME-OTHER-ATTR] 31 [ARRAY-ATTR] 32 [INDEX (optionally)] 33 [MEMBER1] 34 [MEMBER2] 35 36where ``ARRAY-ATTR`` is the array entry type. 37 38array-nest 39~~~~~~~~~~ 40 41``array-nest`` creates the following structure:: 42 43 [SOME-OTHER-ATTR] 44 [ARRAY-ATTR] 45 [ENTRY] 46 [MEMBER1] 47 [MEMBER2] 48 [ENTRY] 49 [MEMBER1] 50 [MEMBER2] 51 52It wraps the entire array in an extra attribute (hence limiting its size 53to 64kB). The ``ENTRY`` nests are special and have the index of the entry 54as their type instead of normal attribute type. 55 56type-value 57~~~~~~~~~~ 58 59``type-value`` is a construct which uses attribute types to carry 60information about a single object (often used when array is dumped 61entry-by-entry). 62 63``type-value`` can have multiple levels of nesting, for example 64genetlink's policy dumps create the following structures:: 65 66 [POLICY-IDX] 67 [ATTR-IDX] 68 [POLICY-INFO-ATTR1] 69 [POLICY-INFO-ATTR2] 70 71Where the first level of nest has the policy index as it's attribute 72type, it contains a single nest which has the attribute index as its 73type. Inside the attr-index nest are the policy attributes. Modern 74Netlink families should have instead defined this as a flat structure, 75the nesting serves no good purpose here. 76 77Operations 78========== 79 80Enum (message ID) model 81----------------------- 82 83unified 84~~~~~~~ 85 86Modern families use the ``unified`` message ID model, which uses 87a single enumeration for all messages within family. Requests and 88responses share the same message ID. Notifications have separate 89IDs from the same space. For example given the following list 90of operations: 91 92.. code-block:: yaml 93 94 - 95 name: a 96 value: 1 97 do: ... 98 - 99 name: b 100 do: ... 101 - 102 name: c 103 value: 4 104 notify: a 105 - 106 name: d 107 do: ... 108 109Requests and responses for operation ``a`` will have the ID of 1, 110the requests and responses of ``b`` - 2 (since there is no explicit 111``value`` it's previous operation ``+ 1``). Notification ``c`` will 112use the ID of 4, operation ``d`` 5 etc. 113 114directional 115~~~~~~~~~~~ 116 117The ``directional`` model splits the ID assignment by the direction of 118the message. Messages from and to the kernel can't be confused with 119each other so this conserves the ID space (at the cost of making 120the programming more cumbersome). 121 122In this case ``value`` attribute should be specified in the ``request`` 123``reply`` sections of the operations (if an operation has both ``do`` 124and ``dump`` the IDs are shared, ``value`` should be set in ``do``). 125For notifications the ``value`` is provided at the op level but it 126only allocates a ``reply`` (i.e. a "from-kernel" ID). Let's look 127at an example: 128 129.. code-block:: yaml 130 131 - 132 name: a 133 do: 134 request: 135 value: 2 136 attributes: ... 137 reply: 138 value: 1 139 attributes: ... 140 - 141 name: b 142 notify: a 143 - 144 name: c 145 notify: a 146 value: 7 147 - 148 name: d 149 do: ... 150 151In this case ``a`` will use 2 when sending the message to the kernel 152and expects message with ID 1 in response. Notification ``b`` allocates 153a "from-kernel" ID which is 2. ``c`` allocates "from-kernel" ID of 7. 154If operation ``d`` does not set ``values`` explicitly in the spec 155it will be allocated 3 for the request (``a`` is the previous operation 156with a request section and the value of 2) and 8 for response (``c`` is 157the previous operation in the "from-kernel" direction). 158 159Other quirks (todo) 160=================== 161 162Structures 163---------- 164 165Legacy families can define C structures both to be used as the contents of 166an attribute and as a fixed message header. Structures are defined in 167``definitions`` and referenced in operations or attributes. Note that 168structures defined in YAML are implicitly packed according to C 169conventions. For example, the following struct is 4 bytes, not 6 bytes: 170 171.. code-block:: c 172 173 struct { 174 u8 a; 175 u16 b; 176 u8 c; 177 } 178 179Any padding must be explicitly added and C-like languages should infer the 180need for explicit padding from whether the members are naturally aligned. 181 182Here is the struct definition from above, declared in YAML: 183 184.. code-block:: yaml 185 186 definitions: 187 - 188 name: message-header 189 type: struct 190 members: 191 - 192 name: a 193 type: u8 194 - 195 name: b 196 type: u16 197 - 198 name: c 199 type: u8 200 201Fixed Headers 202~~~~~~~~~~~~~ 203 204Fixed message headers can be added to operations using ``fixed-header``. 205The default ``fixed-header`` can be set in ``operations`` and it can be set 206or overridden for each operation. 207 208.. code-block:: yaml 209 210 operations: 211 fixed-header: message-header 212 list: 213 - 214 name: get 215 fixed-header: custom-header 216 attribute-set: message-attrs 217 218Attributes 219~~~~~~~~~~ 220 221A ``binary`` attribute can be interpreted as a C structure using a 222``struct`` property with the name of the structure definition. The 223``struct`` property implies ``sub-type: struct`` so it is not necessary to 224specify a sub-type. 225 226.. code-block:: yaml 227 228 attribute-sets: 229 - 230 name: stats-attrs 231 attributes: 232 - 233 name: stats 234 type: binary 235 struct: vport-stats 236 237C Arrays 238-------- 239 240Legacy families also use ``binary`` attributes to encapsulate C arrays. The 241``sub-type`` is used to identify the type of scalar to extract. 242 243.. code-block:: yaml 244 245 attributes: 246 - 247 name: ports 248 type: binary 249 sub-type: u32 250 251Multi-message DO 252---------------- 253 254New Netlink families should never respond to a DO operation with multiple 255replies, with ``NLM_F_MULTI`` set. Use a filtered dump instead. 256 257At the spec level we can define a ``dumps`` property for the ``do``, 258perhaps with values of ``combine`` and ``multi-object`` depending 259on how the parsing should be implemented (parse into a single reply 260vs list of objects i.e. pretty much a dump). 261