对旧式 Generic Netlink 族群的 Netlink 规范支持¶
本文档描述了描述构成 genetlink-legacy
协议级别的旧式 Generic Netlink 族群所需的许多附加怪癖和属性。
规范¶
全局变量¶
直接在规范文件根级别列出的属性。
版本¶
Generic Netlink 族群版本,默认为 1。
version
历史上用于引入可能会破坏向后兼容性的族群更改。由于通常不允许破坏兼容性的更改,因此很少使用 version
。
属性类型嵌套¶
新的 Netlink 族群应使用 multi-attr
来定义数组。旧族群(例如 genetlink
控制族群)尝试重用属性类型来携带信息,从而定义数组类型。
作为参考,multi-attr
数组可能如下所示
[ARRAY-ATTR]
[INDEX (optionally)]
[MEMBER1]
[MEMBER2]
[SOME-OTHER-ATTR]
[ARRAY-ATTR]
[INDEX (optionally)]
[MEMBER1]
[MEMBER2]
其中 ARRAY-ATTR
是数组条目类型。
索引数组¶
indexed-array
将整个数组包装在一个额外的属性中(因此将其大小限制为 64kB)。ENTRY
嵌套是特殊的,并且条目的索引作为它们的类型,而不是普通的属性类型。
需要一个 sub-type
来描述 ENTRY
中的类型。nest
sub-type
意味着在 ENTRY
中存在嵌套数组,结构如下所示
[SOME-OTHER-ATTR]
[ARRAY-ATTR]
[ENTRY]
[MEMBER1]
[MEMBER2]
[ENTRY]
[MEMBER1]
[MEMBER2]
其他 sub-type
(如 u32
)意味着在 ENTRY
中只有一个成员,如 sub-type
中所述。结构如下所示
[SOME-OTHER-ATTR]
[ARRAY-ATTR]
[ENTRY u32]
[ENTRY u32]
类型值¶
type-value
是一种使用属性类型来携带有关单个对象的信息的构造(通常在逐个条目转储数组时使用)。
type-value
可以具有多个嵌套级别,例如 genetlink 的策略转储创建以下结构
[POLICY-IDX]
[ATTR-IDX]
[POLICY-INFO-ATTR1]
[POLICY-INFO-ATTR2]
第一级嵌套的策略索引作为其属性类型,它包含一个具有属性索引作为其类型的嵌套。属性索引嵌套内部是策略属性。现代 Netlink 族群应该将其定义为扁平结构,嵌套在这里没有好处。
操作¶
枚举(消息 ID)模型¶
统一¶
现代族群使用 unified
消息 ID 模型,该模型对族群中的所有消息使用单个枚举。请求和响应共享相同的消息 ID。通知来自同一空间的不同 ID。例如,给定以下操作列表
-
name: a
value: 1
do: ...
-
name: b
do: ...
-
name: c
value: 4
notify: a
-
name: d
do: ...
操作 a
的请求和响应将具有 ID 1,b
的请求和响应将具有 ID 2(因为没有显式 value
,它是上一个操作 + 1
)。通知 c
将使用 ID 4,操作 d
将使用 ID 5,依此类推。
定向¶
directional
模型按消息的方向分割 ID 分配。来自和发送到内核的消息不会相互混淆,因此这可以节省 ID 空间(以使编程更加繁琐为代价)。
在这种情况下,应在操作的 request
reply
部分中指定 value
属性(如果操作同时具有 do
和 dump
,则 ID 是共享的,应在 do
中设置 value
)。对于通知,value
在 op 级别提供,但它仅分配一个 reply
(即“来自内核”ID)。让我们看一个例子
-
name: a
do:
request:
value: 2
attributes: ...
reply:
value: 1
attributes: ...
-
name: b
notify: a
-
name: c
notify: a
value: 7
-
name: d
do: ...
在这种情况下,a
在将消息发送到内核时将使用 2,并期望收到 ID 为 1 的消息作为响应。通知 b
分配一个“来自内核”ID,即 2。c
分配“来自内核”ID 7。如果操作 d
未在规范中显式设置 values
,则将为请求分配 3(a
是具有请求部分的先前操作,值为 2),并为响应分配 8(c
是“来自内核”方向的先前操作)。
其他怪癖¶
结构体¶
旧式族群可以定义 C 结构体,既可以用作属性的内容,也可以用作固定消息头。结构体在 definitions
中定义,并在操作或属性中引用。
成员¶
name
- 结构体成员的属性名称
type
- 标量类型之一:u8
、u16
、u32
、u64
、s8
、s16
、s32
、s64
、string
、binary
或bitfield32
。
byte-order
-big-endian
或little-endian
doc
、enum
、enum-as-flags
、display-hint
- 与 属性定义 相同
请注意,YAML 中定义的结构体根据 C 约定隐式打包。例如,以下结构体为 4 字节,而不是 6 字节
struct {
u8 a;
u16 b;
u8 c;
}
任何填充都必须显式添加,并且类似 C 的语言应从成员是否自然对齐来推断是否需要显式填充。
以下是上面来自 YAML 的结构体定义
definitions:
-
name: message-header
type: struct
members:
-
name: a
type: u8
-
name: b
type: u16
-
name: c
type: u8
固定头¶
可以使用 fixed-header
将固定消息头添加到操作。fixed-header
的默认值可以在 operations
中设置,并且可以为每个操作设置或覆盖它。
operations:
fixed-header: message-header
list:
-
name: get
fixed-header: custom-header
attribute-set: message-attrs
属性¶
可以使用具有结构体定义名称的 struct
属性将 binary
属性解释为 C 结构体。struct
属性暗示 sub-type: struct
,因此不必指定子类型。
attribute-sets:
-
name: stats-attrs
attributes:
-
name: stats
type: binary
struct: vport-stats
C 数组¶
旧式族群还使用 binary
属性来封装 C 数组。sub-type
用于标识要提取的标量类型。
attributes:
-
name: ports
type: binary
sub-type: u32
多消息 DO¶
新的 Netlink 族群绝不应使用设置了 NLM_F_MULTI
的多个回复来响应 DO 操作。请改用过滤的转储。
在规范级别,我们可以为 do
定义一个 dumps
属性,可能具有值 combine
和 multi-object
,具体取决于应如何实现解析(解析为单个回复与对象列表,即几乎是一个转储)。