Logo

Linux内核

6.13.0-rc6

快速搜索

目录

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

本页

  • 显示源文件

Devlink DPIPE¶

背景¶

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

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

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

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

一个例子是内核的LPM算法,在许多情况下,它与硬件实现大相径庭。配置API是相同的,但是不能依赖转发信息库(FIB)看起来像硬件中的分层路径压缩树(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区域等硬件块是强制性的。

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 驱动 | 页面源