
Cilium 的 SRv6 VRF 映射排查手册深入解析cilium-dbg bpf srv6 vrf命令与底层 BPF 数据平面【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium本篇指南聚焦于 Cilium 的 Segment Routing over IPv6SRv6功能中cilium-dbg bpf srv6 vrf命令的完整用法。该命令用于列出当前节点 BPF 数据平面中已加载的 SRv6 VRF 映射VRF mapping条目是排查 SRv6 策略转发、验证 VRF 与源 IP/目的网段绑定关系的关键调试工具。阅读完本文你将掌握该命令的语法、全部参数、输出字段含义并理解其背后从 BPF Map 定义、数据路径查表到 Go 侧遍历输出的完整实现链路。命令概览一条命令看清 SRv6 VRF 绑定cilium-dbg bpf srv6 vrf是 Cilium 调试套件cilium-dbg中管理 SRv6 路由规则系列命令cilium-dbg bpf srv6下的子命令之一其职责在官方命令参考 cilium-dbg_bpf_srv6_vrf.md 中定义为List SRv6 VRF mappings列出 SRv6 VRF 映射。SRv6 允许在 IPv6 数据平面中通过 Segment Routing HeaderSRH显式指定报文转发路径。Cilium 将 SRv6 的转发决策拆分为两个阶段VRF 映射阶段和策略policy阶段。VRF 映射决定了哪个源 IP 哪个目的网段属于哪个 VRF 域以 VRF ID 标识而后续的 SRv6 策略表再依据 VRF ID 与目的网段查找对应的 SIDSegment Identifier。cilium-dbg bpf srv6 vrf就是直接读取第一个阶段对应 BPF Map 内容的入口。语法与参数详解命令语法cilium-dbg bpf srv6 vrf [flags]该命令不需要任何位置参数直接执行即可列出本节点上的全部 SRv6 VRF 映射条目。专属选项选项说明-h, --help显示vrf子命令的帮助信息-o, --output string指定输出格式可选json、yaml或jsonpath{}--output选项并非该子命令独有而是由command.AddOutputOption(bpfSRv6VRFListCmd)在命令初始化时统一挂载见 cilium-dbg/cmd/bpf_srv6_vrf.go因此所有cilium-dbg bpf srv6下的子命令vrf、policy、sid都支持结构化输出便于脚本化采集与后续自动化解析。继承自父命令的全局选项与其他cilium-dbg子命令一致vrf还继承了一组全局选项选项说明--config string配置文件路径默认为$HOME/.cilium.yaml-D, --debug开启调试消息-H, --host string服务端 API 的 URI用于连接指定节点的 Cilium 代理--log-driver strings日志端点例如syslog--log-opt map日志驱动选项例如formatjson其中-H, --host让你可以在任意安装了cilium-dbg的主机上远程查看集群中某个特定节点的 SRv6 VRF 映射这对多节点集群排障尤为实用。相关命令vrf是cilium-dbg bpf srv6的三个子命令之一完整命令树如下cilium-dbg bpf srv6 ├── policy # List SRv6 policy entries列出 SRv6 策略条目 ├── sid # List SRv6 SID entries列出 SRv6 SID 条目 └── vrf # List SRv6 VRF mappings列出 SRv6 VRF 映射父命令 cilium-dbg bpf srv6 本身只承载-h, --help选项作用仅是分组兄弟命令policy的输出字段为VRF ID、Destination CIDR、SIDcilium-dbg_bpf_srv6_policy.md与vrf命令的结果通过VRF ID关联三者共同覆盖了 SRv6 转发链路的全部三张 BPF 表。输出字段解析如何读懂一条 VRF 映射默认表格输出格式由 cilium-dbg/cmd/bpf_srv6_vrf.go 中的printSRv6VRFList实现使用 tabwriter 对齐列头与含义如下列名含义对应底层数据结构Source IP触发该 VRF 映射的源 IP 地址VRFKey.SourceIPnetip.AddrDestination CIDR匹配的目的网段前缀VRFKey.DestCIDRnetip.PrefixVRF ID该映射关联的 VRF 标识符VRFValue.IDuint32Go 侧用于承载结果的中间结构定义如下cilium-dbg/cmd/bpf_srv6_vrf.gotype srv6VRF struct { SourceIP string DestCIDR string ID uint32 }当映射表为空时命令向 stderr 输出No entries found.当指定的 BPF Map 尚未创建时输出Cannot find SRv6 VRF mapping maps。需要注意VRF 映射仅在节点启用了 SRv6 能力EnableSRv6时才会创建因此未启用 SRv6 的节点上执行本命令通常会看到找不到映射的提示而非空列表。结构化输出示例使用-o json时输出形如[ { SourceIP: 192.168.0.1, DestCIDR: 10.0.0.0/8, ID: 1 } ]使用-o yaml时输出对应 YAML 列表使用-o jsonpath{range .items[*]}{.SourceIP}{end}等表达式则可精确提取指定字段。这一输出由command.PrintOutput统一处理cilium-dbg/cmd/bpf_srv6_vrf.go。底层原理一VRF 映射的 BPF Map 结构vrf命令直接读取的是两块按地址族区分的 BPF Map定义见 pkg/maps/srv6map/vrf.gocilium_srv6_vrf_v4—— 承载 IPv4 源 IP/目的网段的 VRF 映射cilium_srv6_vrf_v6—— 承载 IPv6 源 IP/目的网段的 VRF 映射。两张表均以BPF_MAP_TYPE_LPM_TRIE最长前缀匹配实现最大条目数为常量maxVRFEntries 16384并设置了BPF_F_NO_PREALLOC | BPF_F_RDONLY_PROG标志仅内核可写、程序可读用户态不可随意写入同时通过SRV6_VRF_MAP_SIZE宏下发为 datapath 编译期定义。BPF 侧的 Map 声明位于 bpf/lib/srv6_maps.h其中 key 结构为struct srv6_vrf_key4 { struct bpf_lpm_trie_key lpm; __u32 src_ip; /* 源 IP */ __u32 dst_cidr; /* 目的网段 */ };选择 LPM_TRIE 的原因在于 key 中的目的地址是网段而非单一地址查找时必须按最长前缀匹配到最精确的目的 CIDR。整个 key 由静态前缀部分源 IP 全量 可变前缀部分目的网段掩码拼接而成Go 侧VRFKey4/VRFKey6中的PrefixLen字段正是32 位 VRF 静态前缀 目的 CIDR 掩码位数的组合遍历时通过getDestCIDR()还原出真正的netip.Prefix参见 pkg/maps/srv6map/vrf.go 中vrf4StaticPrefixBits/vrf6StaticPrefixBits的定义与计算逻辑。VRF 映射的 value 极为精简仅为一个uint32的 VRF IDtype VRFValue struct { ID uint32 }BPF 侧 value 同样为__u32可见一张 VRF 映射条目的开销非常小16384 条上限足够覆盖大规模租户/租户组划分场景。底层原理二数据路径中的查表调用链VRF 映射并非仅供调试查看它在报文转发路径上承担关键职责。在 bpf/lib/srv6.h 中定义了数据路径查表函数srv6_lookup_vrf4(__be32 sip, __be32 dip) /* 查 cilium_srv6_vrf_v4 */ srv6_lookup_vrf6(const struct in6_addr *sip, const struct in6_addr *dip) /* 查 cilium_srv6_vrf_v6 */二者以SRV6_VRF_IPV4_PREFIX静态前缀 32或SRV6_VRF_IPV6_PREFIX静态前缀 128构造 LPM key 后执行map_lookup_elem命中则返回 VRF ID 指针。在 bpf/lib/nodeport.h 中可以看到完整的调用链vrf_id srv6_lookup_vrf4(ip4-saddr, ip4-daddr); // 若命中再以 vrf_id 与目的地址查策略表 sid srv6_lookup_policy4(*vrf_id, ip4-daddr);也就是说数据路径的决策顺序为源 IP, 目的网段→ VRF ID →VRF ID, 目的网段→ SID → 封装 SRH 转发。cilium-dbg bpf srv6 vrf看到的正是这一链条中第一张表的快照与cilium-dbg bpf srv6 policy、cilium-dbg bpf srv6 sidcilium-dbg_bpf_srv6_sid.md的输出可以对照还原整条转发路径。底层原理三命令实现与 Map 生命周期从源码角度看该命令的执行流程清晰可循cilium-dbg/cmd/bpf_srv6_vrf.gocommon.RequireRootPrivilege(...)校验 root 权限——读取 bpffs 上的内核 Map 需要相应权限调用srv6map.OpenVRFMaps(log)pkg/maps/srv6map/vrf.go通过bpf.MapPath打开 pinned 在 bpffs 上的cilium_srv6_vrf_v4与cilium_srv6_vrf_v6依次对两张表调用IterateWithCallback把 key/value 解析为统一的VRFKey{SourceIP, DestCIDR}VRFValue{ID}结构该迭代逻辑同时处理 IPv4/IPv6 差异见VRFMap4/VRFMap6的IterateWithCallback实现若指定了--output则输出 JSON/YAML/JSONPath否则按 tabwriter 表格打印Source IP / Destination CIDR / VRF ID。Map 的创建与生命周期由 Hive 模块管理pkg/maps/srv6map/cell.go中newVRFMaps提供两个 Map 输出并在dc.EnableSRv6未开启时返回空输出开启时在生命周期OnStart阶段执行OpenOrCreate()完成创建与 pin 绑定pkg/maps/srv6map/vrf.go。测试验证命令背后逻辑的可信度仓库在 pkg/maps/srv6map/vrf_test.go 中提供了TestPrivilegedVRFMapsHive特权测试覆盖了该功能的核心链路在EnableSRV6: true的配置下通过 Hive 启动 Map 创建断言cilium_srv6_vrf_v4与cilium_srv6_vrf_v6均成功 pin 到 bpffs断言节点编译宏中包含SRV6_VRF_MAP_SIZE向 v4 表写入(192.168.0.1, 10.0.0.0/8) → ID 1、向 v6 表写入(fd01::1, fd00::/16) → ID 2后通过IterateWithCallback遍历验证 key源 IP 目的前缀与 valueVRF ID均能正确还原。该测试直接验证了cilium-dbg bpf srv6 vrf命令所依赖的 Map 打开、迭代、前缀还原逻辑是理解命令行为最可靠的佐证。常见排查场景确认 SRv6 是否生效执行cilium-dbg bpf srv6 vrf若提示找不到映射说明节点未启用 SRv6EnableSRv6为 false应先检查 Agent 配置验证 VRF 归属查看某源 IP 与目的网段被划分到哪个 VRF ID与cilium-dbg bpf srv6 policy输出对照确认该 VRF 是否配置了对应的策略与 SID多节点对比借助-H参数分别查询各节点的 VRF 映射排查集群内 SRv6 配置不一致导致的转发异常自动化巡检使用-o json或-o yaml将映射导出与期望配置做差异比对。总而言之cilium-dbg bpf srv6 vrf虽是一条简单的查询命令但其背后串联了 BPF LPM_TRIE 映射定义、数据路径最长前缀匹配、Hive 生命周期管理与结构化输出等完整链路。掌握它就掌握了观察 Cilium SRv6 数据平面第一级转发表的最佳入口。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考