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¶
全局变量¶
直接在规范文件的根级别列出的属性。
name¶
族的名称。名称以唯一的方式标识族,因为族 ID 是动态分配的。
protocol¶
模式级别,默认为 genetlink
,这是新 genetlink
族唯一允许的值。
定义¶
类型和常量定义的数组。
name¶
类型/常量的名称。
type¶
以下类型之一
const - 单个独立的常量
enum - 定义一个整数枚举,每个条目的值递增 1(例如 0、1、2、3)
flags - 定义一个整数枚举,每个条目的值占用一个位,从位 0 开始(例如 1、2、4、8)
value¶
const
的值。
value-start¶
enum
和 flags
的第一个值,允许覆盖默认的起始值 0
(对于 enum
)和起始位(对于 flags
)。对于 flags
,value-start
选择起始位,而不是移位后的值。
不支持稀疏枚举。
entries¶
enum
和 flags
的条目名称的数组。
header¶
对于 C 兼容的语言,已经定义此值的头文件。如果定义由多个族共享(例如 IFNAMSIZ
),则 C 兼容语言的代码生成器可能更喜欢添加适当的包含,而不是呈现新的定义。
attribute-sets¶
此属性包含有关该族的 netlink 属性的信息。所有族都至少有一个属性集,大多数族都有多个。attribute-sets
是一个数组,每个条目描述一个单独的集合。
请注意,规范是“扁平化的”,并不意味着在视觉上类似于 netlink 消息的格式(与内核注释中看到的某些临时文档格式不同)。在规范中,从属属性集不是以内联方式定义为嵌套,而是在单独的属性集中定义,该属性集通过容器的 nested-attributes
属性引用。
规范还可以包含部分集合 - 包含 subset-of
属性的集合。此类集合描述完整集合的一部分,允许缩小嵌套中允许的属性范围或细化验证标准。部分集合只能在嵌套中使用。它们不会以任何方式呈现给 uAPI。
name¶
唯一标识属性集,操作和嵌套属性通过 name
引用集合。
subset-of¶
重新定义另一个集合的一部分(部分集合)。允许缩小字段范围并更改验证标准,甚至更改属性的类型,具体取决于它们包含的嵌套。部分集合中每个属性的 value
隐式地与主集合中的相同。
attributes¶
集合中属性的列表。
属性属性¶
name¶
标识该属性,在集合中是唯一的。
type¶
Netlink 属性类型,请参阅 属性类型。
value¶
数值属性 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
。
checks¶
内核使用的输入验证约束。用户空间应使用通用 Netlink 自省查询正在运行的内核的策略,而不是依赖于规范文件中指定的内容。
内核中的验证策略是通过组合类型定义(type
和 nested-attributes
)和 checks
来形成的。
sub-type¶
传统系列具有表达数组的特殊方式。如果数组的成员未完全定义为属性(在真正的属性空间中),则可以使用 sub-type
来定义数组成员的类型。例如,可以使用 type: binary
和 sub-type: u32
来指定 u32 值的 C 数组。有关二进制类型和旧式数组格式的更多详细信息,请参阅 Netlink 对旧式通用 Netlink 系列的规范支持。
display-hint¶
可选的格式指示符,仅用于在显示此类型的值时选择正确的格式化机制。当前支持的提示包括 hex
、mac
、fddi
、ipv4
、ipv6
和 uuid
。
operations¶
本节描述了内核和用户空间之间传递的消息。本节中有三种类型的条目 - 操作、通知和事件。
操作描述了最常见的请求-响应通信。用户发送请求,内核回复。每个操作可能包含 Netlink 用户熟悉的两种模式的任意组合 - do
和 dump
。do
和 dump
反过来又包含 request
和 response
属性的组合。如果在给定方向上没有传递带有属性的显式消息(例如,不接受过滤器的 dump
,或者内核仅使用 netlink 错误代码响应的 SET 操作的 do
),则可以跳过 request
或 response
部分。request
和 response
部分列出了消息中允许的属性。该列表仅包含由 attribute-set
属性引用的集合中的属性名称。
通知和事件都指内核发送给多播组成员的异步消息。两者之间的区别在于,通知与其 GET 操作共享其内容(GET 操作的名称在 notify
属性中指定)。此安排通常用于关于对象的通知,其中通知携带完整的对象定义。
事件更集中,并且仅携带信息子集,而不是完整的对象状态(一个虚构的示例是仅包含接口名称和新链接状态的链接状态更改事件)。事件包含 event
属性。对于 netlink 来说,事件被认为不太规范,应首选通知。
list¶
operations
对于 genetlink
的唯一属性,保存操作、通知等的列表。
操作属性¶
name¶
标识操作。
value¶
数值消息 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¶
本节列出该系列的多播组。
list¶
mcast-groups
对于 genetlink
的唯一属性,保存组列表。
多播组属性¶
name¶
唯一标识系列中的多播组。与系列 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
指定内部使用的属性集。