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