Devlink 陷阱¶
背景¶
能够卸载内核数据路径并执行桥接和路由等功能的设备,还必须能够将特定数据包发送到内核(即 CPU)进行处理。
例如,充当组播感知网桥的设备必须能够将 IGMP 成员报告发送到内核,以便由网桥模块进行处理。 如果不处理此类数据包,网桥模块就永远无法填充其 MDB。
再举一个例子,考虑一个充当路由器的设备,该设备接收到了 TTL 为 1 的 IP 数据包。在路由数据包时,设备必须将其发送到内核,以便内核也对其进行路由并生成 ICMP 超时错误数据报。 如果不让内核自己路由此类数据包,则像 traceroute
这样的实用程序将永远无法工作。
将某些数据包发送到内核进行处理的基本能力称为“数据包捕获”。
概述¶
devlink-trap
机制允许有能力的设备驱动程序向 devlink
注册其支持的数据包陷阱,并向 devlink
报告捕获的数据包以进行进一步分析。
收到捕获的数据包后,devlink
将执行每个陷阱的数据包和字节计数,并可能通过 netlink 事件将数据包报告给用户空间,以及所有提供的元数据(例如,陷阱原因、时间戳、输入端口)。 这对于丢弃陷阱(请参阅 陷阱类型)尤其有用,因为它允许用户进一步了解原本不可见的数据包丢弃情况。
下图提供了 devlink-trap
的总体概述
Netlink event: Packet w/ metadata
Or a summary of recent drops
^
|
Userspace |
+---------------------------------------------------+
Kernel |
|
+-------+--------+
| |
| drop_monitor |
| |
+-------^--------+
|
| Non-control traps
|
+----+----+
| | Kernel's Rx path
| devlink | (non-drop traps)
| |
+----^----+ ^
| |
+-----------+
|
+-------+-------+
| |
| Device driver |
| |
+-------^-------+
Kernel |
+---------------------------------------------------+
Hardware |
| Trapped packet
|
+--+---+
| |
| ASIC |
| |
+------+
陷阱类型¶
devlink-trap
机制支持以下数据包陷阱类型
drop
:被捕获的数据包被底层设备丢弃。数据包仅由devlink
处理,而不注入到内核的 Rx 路径。可以更改陷阱操作(请参阅 陷阱操作)。
exception
:由于异常(例如,TTL 错误、缺少邻居条目),捕获的数据包未按底层设备的预期转发,并被捕获到控制平面以进行解析。数据包由devlink
处理并注入到内核的 Rx 路径。不允许更改此类陷阱的操作,因为它很容易破坏控制平面。
control
:数据包被设备捕获,因为这些是控制平面正确运行所需的控制数据包。例如,ARP 请求和 IGMP 查询数据包。数据包被注入到内核的 Rx 路径,但不会报告给内核的丢弃监视器。不允许更改此类陷阱的操作,因为它很容易破坏控制平面。
陷阱操作¶
devlink-trap
机制支持以下数据包陷阱操作
trap
:数据包的唯一副本被发送到 CPU。
drop
:数据包被底层设备丢弃,副本不发送到 CPU。
mirror
:数据包由底层设备转发,并将副本发送到 CPU。
通用数据包陷阱¶
通用数据包陷阱用于描述捕获定义明确的数据包或由于定义明确的条件而捕获的数据包(例如,TTL 错误)的陷阱。 多个设备驱动程序可以共享此类陷阱,并且必须将它们的描述添加到下表中
名称 |
类型 |
描述 |
|
|
捕获设备决定由于组播源 MAC 而丢弃的传入数据包 |
|
|
捕获设备决定在 VLAN 标签不匹配的情况下丢弃的传入数据包:入口网桥端口未配置 PVID,并且数据包未标记或优先级标记 |
|
|
捕获设备决定在数据包标记有入口网桥端口上未配置的 VLAN 时丢弃的传入数据包 |
|
|
捕获设备决定在入口网桥端口的 STP 状态不是“转发”的情况下丢弃的传入数据包 |
|
|
捕获设备决定在需要泛洪(例如,未知单播、未注册组播)且没有数据包应泛洪到的端口的情况下丢弃的数据包 |
|
|
捕获设备决定在第 2 层转发后,唯一应通过其传输数据包的端口是接收数据包的端口的情况下丢弃的数据包 |
|
|
捕获设备决定在数据包命中黑洞路由的情况下丢弃的数据包 |
|
|
捕获应由设备转发的单播数据包,其 TTL 减为 0 或更小 |
|
|
捕获设备决定由于无法将其加入已满的传输队列而丢弃的数据包 |
|
|
捕获设备决定由于需要进行第 3 层查找,但不是 IP 或 MPLS 数据包而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且具有单播目标 IP 和组播目标 MAC 而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且其目标 IP 是环回地址(即 127.0.0.0/8 和 ::1/128)而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且其源 IP 是组播(即 224.0.0.0/8 和 ff::/8)而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且其源 IP 是环回地址(即 127.0.0.0/8 和 ::1/128)而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且其 IP 标头已损坏:校验和错误、IP 版本错误或 Internet 标头长度 (IHL) 太短而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且其源 IP 是有限广播(即 255.255.255.255/32)而丢弃的数据包 |
|
|
捕获设备决定由于需要进行路由且其 IPv6 组播目标 IP 具有保留范围(即 ffx0::/16)而丢弃的 IPv6 数据包 |
|
|
捕获设备决定由于需要进行路由且其 IPv6 组播目标 IP 具有接口本地范围(即 ffx1::/16)而丢弃的 IPv6 数据包 |
|
|
捕获应该由设备路由,但大于出口接口 MTU 的数据包 |
|
|
捕获在路由后没有匹配的 IP 邻居的数据包 |
|
|
捕获在组播路由期间未能通过反向路径转发 (RPF) 检查的组播 IP 数据包 |
|
|
捕获命中拒绝路由(即“不可访问”、“禁止”)的数据包 |
|
|
捕获未匹配任何路由的单播 IPv4 数据包 |
|
|
捕获未匹配任何路由的单播 IPv6 数据包 |
|
|
捕获设备决定由于不应该被路由而丢弃的数据包。例如,IGMP 查询可以在第 2 层由设备泛洪并到达路由器。此类数据包不应被路由,而应被丢弃 |
|
|
捕获设备决定由于解封装期间失败(例如,数据包太短、VXLAN 标头中设置了保留位)而丢弃的 NVE 和 IPinIP 数据包 |
|
|
捕获设备决定由于其覆盖源 MAC 是组播而丢弃的 NVE 数据包 |
|
|
捕获在入口流操作丢弃处理期间丢弃的数据包 |
|
|
捕获在出口流操作丢弃过程中丢弃的数据包 |
|
|
捕获 STP 数据包 |
|
|
捕获 LACP 数据包 |
|
|
捕获 LLDP 数据包 |
|
|
捕获 IGMP 成员查询数据包 |
|
|
捕获 IGMP 版本 1 成员报告数据包 |
|
|
捕获 IGMP 版本 2 成员报告数据包 |
|
|
捕获 IGMP 版本 3 成员报告数据包 |
|
|
捕获 IGMP 版本 2 离开组数据包 |
|
|
捕获 MLD 组播侦听器查询数据包 |
|
|
捕获 MLD 版本 1 组播侦听器报告数据包 |
|
|
捕获 MLD 版本 2 组播侦听器报告数据包 |
|
|
捕获 MLD 版本 1 组播侦听器完成数据包 |
|
|
捕获 IPv4 DHCP 数据包 |
|
|
捕获 IPv6 DHCP 数据包 |
|
|
捕获 ARP 请求数据包 |
|
|
捕获 ARP 响应数据包 |
|
|
捕获到达覆盖网络的 NVE 解封装的 ARP 数据包。例如,当需要解析的地址是本地地址时,这是必需的 |
|
|
捕获 IPv6 邻居请求数据包 |
|
|
捕获 IPv6 邻居通告数据包 |
|
|
捕获 IPv4 BFD 数据包 |
|
|
捕获 IPv6 BFD 数据包 |
|
|
捕获 IPv4 OSPF 数据包 |
|
|
捕获 IPv6 OSPF 数据包 |
|
|
捕获 IPv4 BGP 数据包 |
|
|
捕获 IPv6 BGP 数据包 |
|
|
捕获 IPv4 VRRP 数据包 |
|
|
捕获 IPv6 VRRP 数据包 |
|
|
捕获 IPv4 PIM 数据包 |
|
|
捕获 IPv6 PIM 数据包 |
|
|
捕获需要通过接收它们的同一第 3 层接口路由的单播数据包。此类数据包由内核路由,但也会导致内核潜在地生成 ICMP 重定向数据包 |
|
|
捕获命中本地路由并需要本地传递的单播数据包 |
|
|
捕获应通过不属于与入口接口相同的设备(例如,交换机 ASIC)的外部接口(例如,管理接口)路由的数据包 |
|
|
捕获需要路由且目标 IP 地址具有链路本地范围(即 fe80::/10)的单播 IPv6 数据包。该捕获允许设备驱动程序避免编程链路本地路由,但仍然接收用于本地传递的数据包 |
|
|
捕获目标 IP 地址为“所有节点地址”(即 ff02::1)的 IPv6 数据包 |
|
|
捕获目标 IP 地址为“所有路由器地址”(即 ff02::2)的 IPv6 数据包 |
|
|
捕获 IPv6 路由器请求数据包 |
|
|
捕获 IPv6 路由器通告数据包 |
|
|
捕获 IPv6 重定向消息数据包 |
|
|
捕获需要路由并包含路由器警报选项的 IPv4 数据包。此类数据包需要本地传递到设置了 IP_ROUTER_ALERT 套接字选项的原始套接字 |
|
|
捕获需要路由并在其逐跳扩展头中包含路由器警报选项的 IPv6 数据包。此类数据包需要本地传递到设置了 IPV6_ROUTER_ALERT 套接字选项的原始套接字 |
|
|
捕获 PTP 时间关键事件消息(同步、延迟请求、Pdelay_Req 和 Pdelay_Resp) |
|
|
捕获 PTP 常规消息(通告、后续、延迟响应、Pdelay_Resp_Follow_Up、管理和信令) |
|
|
捕获在流操作采样过程中采样的数据包(例如,通过 tc 的采样操作) |
|
|
捕获在流操作捕获过程中记录的数据包(例如,通过 tc 的捕获操作) |
|
|
捕获由于 RED(随机早期检测)算法而丢弃的数据包(即早期丢弃) |
|
|
捕获由于 VXLAN 标头解析错误而丢弃的数据包,这可能是由于数据包截断或未设置 I 标志。 |
|
|
捕获由于 LLC+SNAP 标头解析错误而丢弃的数据包 |
|
|
捕获由于 VLAN 标头解析错误而丢弃的数据包。可能包括意外的数据包截断。 |
|
|
捕获由于 PPPoE+PPP 标头解析错误而丢弃的数据包。这可能包括发现会话 ID 为 0xFFFF(这是保留的,不使用)、PPPoE 长度大于接收的帧或此类标头上的任何常见错误 |
|
|
捕获由于 MPLS 标头解析错误而丢弃的数据包,其中可能包括意外的标头截断 |
|
|
捕获由于 ARP 标头解析错误而丢弃的数据包 |
|
|
捕获由于第一个 IP 标头解析错误而丢弃的数据包。此数据包捕获可能包括未通过 IP 校验和检查、标头长度检查(最小 20 个字节)的数据包,这些数据包可能遭受数据包截断,因此总长度字段超过接收的数据包长度等 |
|
|
捕获由于最后一个 IP 标头(IP over IP 隧道中的内部标头)解析错误而丢弃的数据包。此处执行与 ip_1_parsing 捕获相同的常见错误检查 |
|
|
捕获由于 GRE 标头解析错误而丢弃的数据包 |
|
|
捕获由于 UDP 标头解析错误而丢弃的数据包。此数据包捕获可能包括校验和错误、检测到不正确的 UDP 长度(小于 8 个字节)或检测到标头截断。 |
|
|
捕获由于 TCP 标头解析错误而丢弃的数据包。这可能包括 TCP 校验和错误、SYN、FIN 和/或 RESET 的不正确组合等。 |
|
|
捕获由于 IPSEC 标头解析错误而丢弃的数据包 |
|
|
捕获由于 SCTP 标头解析错误而丢弃的数据包。这意味着使用了端口号 0 或标头被截断。 |
|
|
捕获由于 DCCP 标头解析错误而丢弃的数据包 |
|
|
捕获由于 GTP 标头解析错误而丢弃的数据包 |
|
|
捕获由于 ESP 标头解析错误而丢弃的数据包 |
|
|
捕获设备在遇到黑洞下一跳时决定丢弃的数据包 |
|
|
捕获设备决定丢弃的传入数据包,因为目标 MAC 未在 MAC 表中配置,并且接口未处于混杂模式 |
|
|
捕获 IEEE 802.1X 中指定的“局域网上的可扩展身份验证协议”(EAPOL)数据包 |
|
|
捕获设备决定丢弃的数据包,因为它们未能通过锁定的网桥端口检查。也就是说,通过锁定端口接收的数据包,其 {SMAC, VID} 与指向该端口的 FDB 条目不对应 |
特定于驱动程序的包捕获¶
设备驱动程序可以注册特定于驱动程序的包捕获,但必须明确记录这些捕获。此类捕获可能对应于特定于设备的异常,并有助于调试由这些异常导致的数据包丢弃。以下列表包括指向各种设备驱动程序注册的特定于驱动程序的捕获的描述的链接
通用包捕获组¶
通用包捕获组用于聚合逻辑上相关的包捕获。这些组允许用户批量操作,例如设置所有成员捕获的捕获操作。此外,如果每个捕获的统计信息太窄,则 devlink-trap
可以报告每个组的聚合数据包和字节统计信息。这些组的描述必须添加到下表中
名称 |
描述 |
|
包含设备在第 2 层转发(即网桥)期间丢弃的数据包的包捕获 |
|
包含设备在第 3 层转发期间丢弃的数据包的包捕获 |
|
包含设备在第 3 层转发期间遇到异常(例如,TTL 错误)的数据包的包捕获 |
|
包含设备由于入队决策而丢弃的数据包的包捕获 |
|
包含设备在隧道封装/解封装期间丢弃的数据包的包捕获 |
|
包含设备在 ACL 处理期间丢弃的数据包的包捕获 |
|
包含 STP 数据包的包捕获 |
|
包含 LACP 数据包的包捕获 |
|
包含 LLDP 数据包的包捕获 |
|
包含多播侦听所需的 IGMP 和 MLD 数据包的包捕获 |
|
包含 DHCP 数据包的包捕获 |
|
包含邻居发现数据包(例如,ARP、IPv6 ND)的包捕获 |
|
包含 BFD 数据包的包捕获 |
|
包含 OSPF 数据包的包捕获 |
|
包含 BGP 数据包的包捕获 |
|
包含 VRRP 数据包的包捕获 |
|
包含 PIM 数据包的包捕获 |
|
包含单播环回数据包的包捕获(即 |
|
包含在路由后应本地传递但不匹配更具体的包捕获(例如, |
|
包含应通过不属于与入口接口相同的设备(例如,交换机 ASIC)的外部接口(例如,管理接口)路由的数据包的包捕获 |
|
包含各种 IPv6 控制数据包(例如,路由器通告)的包捕获 |
|
包含 PTP 时间关键事件消息(同步、延迟请求、Pdelay_Req 和 Pdelay_Resp)的包捕获 |
|
包含 PTP 常规消息(通告、后续、延迟响应、Pdelay_Resp_Follow_Up、管理和信令)的包捕获 |
|
包含设备在 ACL 处理期间采样的数据包的包捕获 |
|
包含设备在 ACL 处理期间捕获(记录)的数据包的包捕获 |
|
包含设备在解析期间标记为错误的数据包的包捕获 |
|
包含针对 IEEE 802.1X 中指定的“局域网可扩展身份验证协议”(EAPOL)数据包的数据包捕获。 |
数据包捕获策略器¶
如前所述,底层设备可以捕获某些数据包到 CPU 进行处理。在大多数情况下,底层设备能够处理的数据包速率比 CPU 能够处理的数据包速率高几个数量级。
因此,为了防止底层设备使 CPU 过载,设备通常包含数据包捕获策略器,这些策略器能够将捕获的数据包限制到 CPU 可以处理的速率。
devlink-trap
机制允许有能力的设备驱动程序向 devlink
注册它们支持的数据包捕获策略器。设备驱动程序可以选择在初始化期间将这些策略器与支持的数据包捕获组(请参阅 通用数据包捕获组)关联,从而向用户空间公开其默认的控制平面策略。
设备驱动程序应允许用户空间更改策略器的参数(例如,速率、突发大小),以及策略器和捕获组之间的关联,方法是实现相关的回调函数。
如果可能,设备驱动程序应实现一个回调函数,允许用户空间检索策略器因违反其配置的策略而丢弃的数据包数量。
测试¶
请参阅 tools/testing/selftests/drivers/net/netdevsim/devlink_trap.sh
,其中包含涵盖核心基础设施的测试。应为任何新功能添加测试用例。
设备驱动程序应将其测试重点放在特定于设备的功能上,例如触发支持的数据包捕获。