Logo

Linux内核

6.16.0-rc4

快速搜索

目录

  • 开发流程
  • 提交补丁
  • 行为准则
  • 维护者手册
  • 所有开发流程文档
  • 核心 API
  • 驱动程序 API
  • 子系统
    • 核心子系统
    • 人机界面
    • 网络接口
      • 网络
      • NetLabel
      • InfiniBand
      • ISDN
      • MHI
    • 存储接口
    • 其他子系统
  • 锁
  • 许可规则
  • 编写文档
  • 开发工具
  • 测试指南
  • 黑客指南
  • 追踪
  • 故障注入
  • 热补丁
  • Rust
  • 管理
  • 构建系统
  • 报告问题
  • 用户空间工具
  • 用户空间 API
  • 固件
  • 固件和设备树
  • CPU 架构
  • 未分类文档
  • 翻译

本页

  • 显示源代码

Devlink DPIPE¶

背景¶

在执行硬件卸载过程中,许多硬件细节无法呈现。这些细节对于调试非常有用,devlink-dpipe 提供了一种标准化的方式来提供对卸载过程的可见性。

例如,Linux内核使用的路由最长前缀匹配(LPM)算法可能与硬件实现不同。管道调试API(DPIPE)旨在以通用方式向用户提供对ASIC管道的可见性。

硬件卸载过程应该以用户无法区分硬件与软件实现的方式进行。在这个过程中,硬件细节被忽略。实际上,这些细节可能具有很多意义,应该以某种标准方式公开。

当一个人希望将整个网络堆栈的控制路径卸载到交换机ASIC时,这个问题变得更加复杂。由于硬件和软件模型之间的差异,一些过程无法正确表示。

一个例子是内核的LPM算法,在许多情况下,它与硬件实现有很大差异。配置API是相同的,但人们不能依赖转发信息库(FIB)看起来像硬件中的Level Path Compression trie(LPC-trie)。

在许多情况下,仅基于内核转储来分析系统故障可能不够。通过将此数据与有关底层硬件的补充信息结合起来,可以使调试更容易;此外,该信息在调试性能问题时可能很有用。

概述¶

devlink-dpipe 接口弥补了这个差距。硬件的管道被建模为匹配/动作表的图。每个表代表一个特定的硬件块。这种模型并不新鲜,首先被P4语言使用。

传统上,它已被用作硬件配置的替代模型,但 devlink-dpipe 接口将其用于可见性目的,作为一种标准的补充工具。devlink-dpipe 中的系统视图应根据标准配置工具所做的更改而更改。

例如,使用三态内容寻址存储器(TCAM)实现访问控制列表(ACL)是很常见的。TCAM存储器可以分为TCAM区域。复杂的TC过滤器可以有多个具有不同优先级和不同查找键的规则。另一方面,硬件TCAM区域具有预定义的查找键。使用TCAM引擎卸载TC过滤器规则可能导致多个TCAM区域以链式方式互连(这可能会影响数据路径延迟)。为了响应新的TC过滤器,应创建描述这些区域的新表。

模型¶

DPIPE 模型引入了几个对象

  • 头部

  • 表

  • 条目

header 描述数据包格式,并为数据包中的字段提供名称。table 描述硬件块。entry 描述特定表的实际内容。

硬件管道不是端口特定的,而是描述整个ASIC。因此,它与 devlink 基础设施的顶部相关联。

驱动程序可以在运行时注册和注销表,以支持动态行为。这种动态行为对于描述像TCAM区域这样的硬件块是强制性的,TCAM区域可以动态分配和释放。

devlink-dpipe 通常不用于配置。例外情况是特定表的硬件计数。

以下命令用于从用户空间获取 dpipe 对象

  • table_get:接收表的描述。

  • headers_get:接收设备支持的头部。

  • entries_get:接收表的当前条目。

  • counters_set:启用或禁用表上的计数器。

表¶

驱动程序应该为每个表实现以下操作

  • matches_dump:转储支持的匹配项。

  • actions_dump:转储支持的动作。

  • entries_dump:转储表的实际内容。

  • counters_set_update:同步硬件与启用或禁用的计数器。

头部/字段¶

以类似于 P4 的方式,头部和字段用于描述表的行为。标准协议头部和特定 ASIC 元数据之间略有不同。协议头部应在 devlink 核心 API 中声明。另一方面,ASIC 元数据是驱动程序特定的,应在驱动程序中定义。此外,每个驱动程序特定的 devlink 文档文件都应记录它实现的驱动程序特定的 dpipe 头部。头部和字段由枚举标识。

为了提供进一步的可见性,一些 ASIC 元数据字段可以映射到内核对象。例如,内部路由器接口索引可以直接映射到网络设备 ifindex。由不同虚拟路由和转发(VRF)表使用的 FIB 表索引可以映射到内部路由表索引。

匹配¶

匹配保持原始状态并接近硬件操作。由于这正是我们希望完整描述的过程,因此不支持像 LPM 这样的匹配类型。匹配示例

  • field_exact:完全匹配特定字段。

  • field_exact_mask:在屏蔽后完全匹配特定字段。

  • field_range:匹配特定范围。

为了识别特定字段,应指定头部和字段的 ID。此外,应指定头部索引,以便区分数据包中同一类型的多个头部(隧道)。

动作¶

与匹配类似,动作保持原始状态并接近硬件操作。例如

  • field_modify:修改字段值。

  • field_inc:增加字段值。

  • push_header:添加头部。

  • pop_header:删除头部。

条目¶

可以根据需要转储特定表的条目。每个条目都由一个索引标识,其属性由匹配/动作值和特定计数器的列表描述。通过转储表内容,可以解决表之间的交互。

抽象示例¶

以下是 Mellanox Spectrum ASIC 的 L3 部分的抽象模型示例。这些块按照它们在管道中出现的顺序描述。以下示例中的表大小不是实际的硬件大小,仅用于演示目的。

LPM¶

LPM 算法可以实现为哈希表列表。每个哈希表包含具有相同前缀长度的路由。列表的根是/32,如果未命中,硬件将继续到下一个哈希表。搜索的深度将影响数据路径延迟。

如果命中,该条目包含有关管道下一阶段的信息,该阶段解析 MAC 地址。下一阶段可以是直接连接路由的本地主机表,也可以是下一跳的邻接表。meta.lpm_prefix 字段用于连接两个 LPM 表。

table lpm_prefix_16 {
  size: 4096,
  counters_enabled: true,
  match: { meta.vr_id: exact,
           ipv4.dst_addr: exact_mask,
           ipv6.dst_addr: exact_mask,
           meta.lpm_prefix: exact },
  action: { meta.adj_index: set,
            meta.adj_group_size: set,
            meta.rif_port: set,
            meta.lpm_prefix: set },
}

本地主机¶

在本地路由的情况下,LPM 查找已经解析了出口路由器接口(RIF),但确切的 MAC 地址未知。本地主机表是一个哈希表,它将输出接口 ID 与目标 IP 地址组合作为键。结果是 MAC 地址。

table local_host {
  size: 4096,
  counters_enabled: true,
  match: { meta.rif_port: exact,
           ipv4.dst_addr: exact},
  action: { ethernet.daddr: set }
}

邻接¶

在远程路由的情况下,此表执行 ECMP。LPM 查找导致 ECMP 组大小和索引,该索引用作此表中的全局偏移量。同时,生成数据包的哈希。基于 ECMP 组大小和数据包的哈希,生成本地偏移量。多个 LPM 条目可以指向同一个邻接组。

table adjacency {
  size: 4096,
  counters_enabled: true,
  match: { meta.adj_index: exact,
           meta.adj_group_size: exact,
           meta.packet_hash_index: exact },
  action: { ethernet.daddr: set,
            meta.erif: set }
}

ERIF¶

如果出口 RIF 和目标 MAC 已被先前的表解析,则此表执行多个操作,例如 TTL 减少和 MTU 检查。然后做出转发/丢弃的决定,并根据数据包的类型(广播、单播、多播)更新端口 L3 统计信息。

table erif {
  size: 800,
  counters_enabled: true,
  match: { meta.rif_port: exact,
           meta.is_l3_unicast: exact,
           meta.is_l3_broadcast: exact,
           meta.is_l3_multicast, exact },
  action: { meta.l3_drop: set,
            meta.l3_forward: set }
}
©内核开发社区。| 由 Sphinx 5.3.0 和 Alabaster 0.7.16 提供支持 | 页面源