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