Netlink 协议规范(YAML 格式)¶
Netlink 协议规范是使用 YAML 编写的 Netlink 协议的完整、机器可读的描述。规范的目标是将 Netlink 解析与用户空间逻辑分离,并最大程度地减少为每个新族、命令、属性编写的手写 Netlink 代码量。Netlink 规范应该是完整的,并且不依赖于任何其他规范或 C 头文件,使其易于在无法直接包含内核头文件的语言中使用。
内核内部使用 YAML 规范来生成
C uAPI 头文件
协议的文档作为 ReST 文件 - 请参阅 Documentation/networking/netlink_spec/index.rst
输入属性验证的策略表
操作表
YAML 规范可以在 Documentation/netlink/specs/
下找到
本文档描述了模式的详细信息。有关实际的入门指南,请参阅 使用 Netlink 协议规范。
所有规范都必须在 ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
许可下获得许可,以便于在用户空间代码中采用。
兼容性级别¶
Netlink 规范有四个模式级别,从新系列使用的最简单级别到涵盖旧系列所有怪癖的最复杂级别。每个下一个级别都继承了上一个级别的属性,这意味着能够解析更复杂的 genetlink
模式的用户也与更简单的模式兼容。这些级别是
genetlink
- 最精简,应由所有新系列使用
genetlink-c
-genetlink
的超集,具有额外的属性,允许自定义定义和枚举类型和值的名称;对于所有不直接与 C uAPI 头文件交互的实现,此模式应等效于genetlink
genetlink-legacy
- 通用 Netlink 全局模式,支持所有旧的 genetlink 系列、奇怪的属性格式、二进制结构等的怪癖。
netlink-raw
- 通用模式,支持通用 Netlink 协议之前的协议,例如NETLINK_ROUTE
模式的定义(在 jsonschema
中)可以在 Documentation/netlink/
下找到。
模式结构¶
YAML 模式具有以下概念部分
全局
定义
属性
操作
多播组
模式中的大多数属性接受(或者实际上需要)一个记录已定义对象的 doc
子属性。
以下部分描述了最新 genetlink
模式的属性。有关如何从名称属性派生 C 名称的信息,请参阅 genetlink-c 的文档。
另请参阅 Documentation/core-api/netlink.rst,了解仅与内核空间相关而不属于用户空间 API 的 Netlink 规范属性的信息。
genetlink¶
全局¶
直接在规范文件的根级别列出的属性。
名称¶
族的名称。名称以唯一的方式标识该族,因为族 ID 是动态分配的。
协议¶
模式级别,默认为 genetlink
,这是新 genetlink
族允许的唯一值。
定义¶
类型和常量定义的数组。
名称¶
类型/常量的名称。
类型¶
以下类型之一
const - 单个、独立的常量
enum - 定义一个整数枚举,每个条目的值递增 1(例如 0、1、2、3)
flags - 定义一个整数枚举,每个条目的值占用一个位,从位 0 开始(例如 1、2、4、8)
值¶
const
的值。
value-start¶
enum
和 flags
的第一个值,允许覆盖 0
(对于 enum
)和起始位(对于 flags
)的默认起始值。对于 flags
,value-start
选择起始位,而不是移位后的值。
不支持稀疏枚举。
条目¶
enum
和 flags
的条目名称数组。
头¶
对于 C 兼容的语言,已经定义此值的头文件。如果定义由多个族共享(例如 IFNAMSIZ
),则 C 兼容语言的代码生成器可能更喜欢添加适当的包含项,而不是呈现新的定义。
attribute-sets¶
此属性包含有关族的 netlink 属性的信息。所有族至少有一个属性集,大多数族有多个。 attribute-sets
是一个数组,每个条目描述一个集合。
请注意,规范是“扁平化的”,并不意味着在视觉上类似于 netlink 消息的格式(与内核注释中看到的某些临时文档格式不同)。在规范中,下级属性集不会内联定义为嵌套,而是定义在一个单独的属性集中,该属性集由容器的 nested-attributes
属性引用。
规范也可能包含部分集合 - 包含 subset-of
属性的集合。此类集合描述了完整集合的一部分,允许缩小哪个属性允许在嵌套中使用或细化验证标准。部分集合只能在嵌套中使用。它们不会以任何方式呈现给 uAPI。
名称¶
唯一标识属性集,操作和嵌套属性通过 name
引用这些集合。
subset-of¶
重新定义另一个集合的一部分(部分集合)。允许缩小字段并更改验证标准,甚至根据它们包含的嵌套来更改属性类型。部分集合中每个属性的 value
与主集合中的值隐式相同。
属性¶
集合中属性的列表。
属性属性¶
名称¶
标识属性,在集合中是唯一的。
类型¶
Netlink 属性类型,请参阅 属性类型。
值¶
数值属性 ID,用于序列化的 Netlink 消息中。可以跳过 value
属性,在这种情况下,属性 ID 将是前一个属性的值加 1(递归地),对于属性集中的第一个属性,则为 1
。
属性(和操作)使用 1
作为第一个条目的默认值(与从 0
开始的定义中的枚举不同),因为条目 0
几乎总是保留为未定义。如果需要,规范可以显式地将值设置为 0
。
请注意,属性的 value
仅在其主集合中定义(而不是在子集中)。
enum¶
对于整数类型,指定属性中的值属于 definitions
部分中的 enum
或 flags
。
enum-as-flags¶
将 enum
视为 flags
,无论其在 definitions
中的类型如何。当需要 enum
和 flags
形式时,definitions
应包含 enum
,并且需要 flags
形式的属性应使用此属性。
nested-attributes¶
标识给定属性中嵌套的属性的属性空间。仅对可能具有子属性的复杂属性有效。
multi-attr(数组)¶
布尔属性,表示该属性可能多次出现。允许属性重复是实现数组的推荐方法(没有额外的嵌套)。
byte-order¶
对于整数类型,指定属性字节序 - little-endian
或 big-endian
。
检查¶
内核使用的输入验证约束。用户空间应使用通用 Netlink 内省查询运行内核的策略,而不是依赖于规范文件中指定的内容。
内核中的验证策略是通过组合类型定义(type
和 nested-attributes
)和 checks
来形成的。
子类型¶
旧系列有表达数组的特殊方式。如果数组元素没有完全定义为属性(在一个真正的属性空间中),则可以使用 sub-type
来定义数组元素的类型。例如,u32 值的 C 数组可以使用 type: binary
和 sub-type: u32
来指定。有关二进制类型和旧数组格式的更多详细信息,请参阅 Netlink 规范对旧通用 Netlink 系列的支持。
display-hint¶
可选的格式指示符,仅用于在显示此类型的值时选择正确的格式化机制。当前支持的提示是 hex
、mac
、fddi
、ipv4
、ipv6
和 uuid
。
操作¶
本节描述了内核和用户空间之间传递的消息。本节中有三种类型的条目 - 操作、通知和事件。
操作描述了最常见的请求 - 响应通信。用户发送请求,内核回复。每个操作可能包含 netlink 用户熟悉的两种模式的任意组合 - do
和 dump
。 do
和 dump
反过来又包含 request
和 response
属性的组合。如果在给定方向上没有传递带有属性的显式消息(例如,不接受过滤器的 dump
,或者内核仅以 netlink 错误代码响应的 SET 操作的 do
),则可以跳过 request
或 response
部分。 request
和 response
部分列出了消息中允许的属性。该列表仅包含属性集中属性的名称,属性集由 attribute-set
属性引用。
通知和事件都指内核发送给多播组成员的异步消息。两者之间的区别在于,通知与其 GET 操作共享其内容(GET 操作的名称在 notify
属性中指定)。此安排通常用于有关对象的通知,其中通知携带完整的对象定义。
事件更具针对性,并且仅携带信息子集而不是完整的对象状态(一个虚构的例子是链接状态更改事件,仅包含接口名称和新的链接状态)。事件包含 event
属性。对于 netlink 而言,事件被认为不太符合惯例,应首选通知。
列表¶
operations
对于 genetlink
的唯一属性,包含操作、通知等的列表。
操作属性¶
名称¶
标识操作。
值¶
数值消息 ID,用于序列化的 Netlink 消息中。应用的枚举规则与 属性值 相同。
attribute-set¶
指定消息中包含的属性集。
do¶
对 doit
请求的规范。应包含 request
、reply
或这两个属性,每个属性都包含一个 消息属性列表。
dump¶
对 dumpit
请求的规范。应包含 request
、reply
或这两个属性,每个属性都包含一个 消息属性列表。
notify¶
将消息指定为通知。包含与通知共享内容的名称的操作名称(可能与包含此属性的操作相同)(do
)。
event¶
事件中属性的规范,包含一个 消息属性列表。event
属性与 notify
互斥。
mcgrp¶
与 event
和 notify
一起使用,指定消息属于哪个多播组。
消息属性列表¶
request
、reply
和 event
属性具有一个 attributes
属性,该属性包含属性名称的列表。
消息还可以定义 pre
和 post
属性,这些属性将在内核中呈现为 pre_doit
和 post_doit
调用(这些属性应被用户空间忽略)。
mcast-groups¶
本节列出了该族的多播组。
列表¶
mcast-groups
对于 genetlink
的唯一属性,包含组的列表。
多播组属性¶
名称¶
唯一标识族中的多播组。与族 ID 类似,多播组 ID 需要在运行时根据名称进行解析。
属性类型¶
本节描述了 genetlink
兼容性级别支持的属性类型。有关其他属性类型,请参阅不同级别的文档。
常见整数类型¶
sint
和 uint
表示有符号和无符号的 64 位整数。如果该值可以容纳在 32 位上,则仅在 netlink 消息中携带 32 位,否则携带完整的 64 位。请注意,有效负载仅与 4B 对齐,因此完整的 64 位值可能未对齐!
在大多数情况下,应首选常见整数类型而不是固定宽度类型。
固定宽度整数类型¶
固定宽度整数类型包括:u8
、u16
、u32
、u64
、s8
、s16
、s32
、s64
。
请注意,应避免使用小于 32 位的类型,因为使用它们不会在 Netlink 消息中节省任何内存(由于对齐)。有关 64 位属性的填充,请参阅 pad。
属性的有效负载是主机顺序的整数,除非 byte-order
另有指定。
64 位值通常由内核对齐,但建议用户空间能够处理未对齐的值。
pad¶
特殊属性类型,用于填充需要大于 netlink 所需的标准 4B 对齐的对齐方式的属性(例如 64 位整数)。在任何属性集中只能有一个 pad
类型的属性,并且在需要时应自动用于填充。
flag¶
没有有效负载的属性,其存在是整个信息。
binary¶
原始二进制数据属性,其内容对于通用代码是不透明的。
string¶
字符字符串。除非 checks
中将 unterminated-ok
设置为 true
,否则该字符串必须以 null 结尾。checks
中的 max-len
指示字符串的最大长度,如果不存在,则字符串的长度是无限制的。
请注意,max-len
不计算终止字符。
nest¶
包含其他(嵌套)属性的属性。nested-attributes
指定内部使用的属性集。