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