使用DPDK和NVIDIA DOCA库开发应用程序

在这篇文章中,我将带您了解 frr doca 数据平面插件的创建过程,并向您展示如何使用全新的 doca flow 库卸载 pbr 规则。在上一篇文章中,您了解了使用 dpdk rte_flow 库创建 frr 数据平面插件,以加速 bluefield 上的 pbr 规则。
向 zebra 添加 doca 数据平面插件
我仍然使用 dpdk api 进行硬件初始化,但随后使用 doca flow api 来设置数据平面流管道。为此,我必须将 dpdk (libdpdk.pc)和 doca flow(doca-flow.pc)共享库链接到 doca 数据平面插件。
root@dpu-arm:~# export pkg_config_path=$pkg_config_path:/opt/mellanox/dpdk/lib/aarch 64-linux-gnu/pkgconfig root@dpu-arm:~# pkg-config --libs doca-flow -ldoca_flow root@dpu-arm:~# pkg-config --cflags doca-flow -dallow_experimental_api -include rte_config.h -mcpu=cortex-a72 -dallow_experimental_api -i/opt/mellanox/dpdk/include/dpdk -i/opt/mellanox/dpdk/include/dpdk/../aarch64-linux-gnu/dpdk -i/opt/mellanox/dpdk/include/dpdk -i/usr/include/libnl3 root@dpu-arm:~# 我在 frr makefile (configure.ac)中为 dpdk 和 doca flow添加了pkg check-and-define宏。
if test $enable_dp_doca = yes; then pkg_check_modules([doca], [libdpdk doca-flow], [ ac_define([have_doca], [1], [enable doca backend]) doca=true ], [ ac_msg_error([configuration specifies --enable-dp-doca but doca libs were not found]) ]) fi 我将 dpdk 和 doca flow 库 及 cflags都包含在zebra-dp-doca make宏(zebra/subdir.am)中。
zebra_zebra_dplane_doca_la_cflags = $(doca_cflags) zebra_zebra_dplane_doca_la_libadd = $(doca_libs) 使用/etc/frr/daemons启动 frr 服务时,可以启用 doca 数据平面插件。
zebra_options= -m dplane_doca -a 127.0.0.1 硬件初始化和端口映射 使用 dpdk api 、rte_eal_init和rte_eth_dev_info_get初始化硬件,并设置 zebra 接口到 dpdk 端口映射。此工作流与上一节中的 dpdk 数据平面插件相同。
root@dpu-arm:~# vtysh -c show dplane doca port total ports: 6 cores: 8 port device ifname ifindex sw,domain,port 0 0000:03:00.0 p0 4 0000:03:00.0,0,65535 1 0000:03:00.0 pf0hpf 6 0000:03:00.0,0,4095 2 0000:03:00.0 pf0vf0 15 0000:03:00.0,0,4096 3 0000:03:00.0 pf0vf1 16 0000:03:00.0,0,4097 4 0000:03:00.1 p1 5 0000:03:00.1,1,65535 5 0000:03:00.1 pf1hpf 7 0000:03:00.1,1,20479 root@dpu-arm:~# doca flow初始化 为了使用doca-flow编写 pbr 规则,我必须初始化doca-flow和doca-flow-port数据库。此初始化是在使用rte_eal_init初始化硬件后完成的。
我使用 doca_flow_init 通过配置流和队列计数来初始化doca-flow库。
struct doca_flow_cfg flow_cfg; memset(&flow_cfg, 0, sizeof(flow_cfg)); flow_cfg.total_sessions = zd_doca_flow_max; flow_cfg.queues = doca_ctx->nb_cores; doca_flow_init (&flow_cfg, &err); 当我使用 dpdk 设置硬件端口时,我必须使用dpdk_port-id将它们安装到doca-flow-port数据库中。
struct doca_flow_port_cfg port_cfg; memset(&port_cfg, 0, sizeof(port_cfg)); port_cfg.port_id = dpdk_port_id; port_cfg.type = doca_flow_port_dpdk_by_id; snprintf(port_id_str, zd_port_str_max, %u, port_cfg.port_id); port_cfg.devargs = port_id_str; doca_port = doca_flow_port_start (&port_cfg, &err); 使用 doca-flow api 编写 pbr 规则 通过一系列用于匹配、动作、转发和监控属性的数据结构来对 doca 流进行编程。
struct doca_flow_match match, match_mask; struct doca_flow_actions actions; struct doca_flow_fwd fwd; struct doca_flow_monitor monitor; 流匹配 这被指定为匹配和匹配掩码。匹配掩码是可选的,如果未指定,则由doca-flow库自动填充。
memset(&match, 0, sizeof(match)); memset(&match_mask, 0, sizeof(match_mask)); match.out_src_ip.type = doca_flow_ip4_addr; match.out_src_ip.ipv4_addr = src_ip; match_mask.out_src_ip.ipv4_addr = src_ip_mask; match.out_dst_ip.type = doca_flow_ip4_addr; match.out_dst_ip.ipv4_addr = dst_ip; match_mask.out_src_ip.ipv4_addr = dst_ip_mask; match.out_l4_type = ip_proto; match.out_src_port = rte_be16 (l4_src_port); match_mask.out_src_port = uint16_max; match.out_dst_port = rte_be16 (l4_dst_port); match_mask.out_dst_port = uint16_max; 我跳过了填充eth或eth-mask等字段。这是因为doca-flow库可以基于其他匹配字段dst_ip或src_ip自动将此类字段填充到rte_ether_type_ipv4或rte_ether_type_ipv6。
流动作 为了路由数据包,我必须将目标 mac 地址更改为网关( leaf2 ) mac ,减少 ttl ,并更改源 mac 地址。这一点最初在上一篇文章中讨论, 使用 nvidia bluefield dpu 和 dpdk 开发应用程序 .
memset(&actions, 0, sizeof(actions)); actions.dec_ttl = true; memcpy(actions.mod_src_mac, uplink_mac, doca_ether_addr_len); memcpy(actions.mod_dst_mac, gw_mac, doca_ether_addr_len); 流转发 然后,我将输出端口设置为上行链路。
memset(&fwd, 0, sizeof(fwd)); fwd.type = doca_flow_fwd_port; fwd.port_id = out_port_id; 流监控 我设置了流量计数器进行故障排除。
memset(&monitor, 0, sizeof(monitor)); monitor.flags |= doca_flow_monitor_count; doca 流管道和入口 流程创建分为两步:
创建流管道。
将流条目添加到流管道。
第一步是为查找阶段创建软件模板。第二步使用模板在硬件中的流进行编程。
当您必须对许多类似的流进行编程时,管道非常有用。对于这种情况,可以设置单个匹配模板(管道),并指示在创建流条目时必须更新哪个匹配字段(例如,第 4 层目标端口)。后续的流条目只需要 填充与管道(第 4 层目标端口)不同的匹配字段。
对于 pbr ,每个流模式都是唯一的,所以我使用已经填充的流属性为每个 pbr 规则创建了一个单独的管道和条目。
struct doca_flow_pipe_cfg pipe_cfg; pipe_cfg.name = pbr; pipe_cfg.port = in_dport->doca_port; pipe_cfg.match = &match; pipe_cfg.match_mask = &match_mask; pipe_cfg.actions = &actions; pipe_cfg.monitor = &monitor; pipe_cfg.is_root = true; flow_pipe = doca_flow_create_pipe (&pipe_cfg, &fwd, null, &err); flow_entry = doca_flow_pipe_add_entry (0, flow_pipe, &match, &actions, &monitor, &fwd, &err); 流删除 流管道和条目创建 api 返回管道和流指针,这些指针必须被缓存以供后续删除。
doca_flow_pipe_rm_entry( 0, flow_entry); doca_flow_destroy_pipe (port_id, flow_pipe); 流统计 在创建流时,我设置了doca_flow_monitor_count标志。我使用doca_flow_query查询了流统计数据。
struct doca_flow_query query ; // hit counters – query.total_pkts and query.total_bytes memset(&query, 0, sizeof(query)); doca_flow_query (flow_entry, &query); 验证硬件加速 frr-pbr 规则配置和流量生成与dpdk-plugin相同。流量按预期由 dpu 硬件转发,并可使用流计数器进行验证。
root@dpu-arm:~# vtysh -c show dplane doca pbr flow rules if pf0vf0 seq 1 pri 300 src ip match: 172.20.0.8/32 dst ip match: 172.30.0.8/32 ip protocol match: 17 dst port match: 53 tableid: 10000 action: nh: 192.168.20.250 intf: p0 action: mac: 00:00:5e:00:01:fa doca flow: installed 0xffff28005150 doca stats: packets 202 bytes 24644 root@dpu-arm:~# 还可以使用硬件条目进行验证:
root@dpu-arm:~# ~/mlx_steering_dump/mlx_steering_dump_parser.py -p `pidof zebra` - f /tmp/dpdkdump domain 0xe294002, table 0xaaab07648b10, matcher 0xffff28012c30, rule 0xffff28014040 match: outer_l3_type: 0x1, outer_ip_dst_addr: 172.30.0.8, outer_l4_type: 0x2, metadata_reg_c_0: 0x00030000, outer_l4_dport: 0x0035, outer_ip_src_addr: 172.20.0.8 action: modify_hdr(hdr(dec_ip4_ttl)), rewrite index 0x0 & vport, num 0xffff & ctr(hits(352), bytes(42944)), index 0x806200 通过使用 doca-flow ,frr 现在具有了第二个数据平面插件,可用于 pbr 规则的硬件加速。
应用程序开发要点
在本系列文章中,您了解了如何使用rte_flow或doca_flow通过四个步骤对 dpu 网络应用程序进行硬件加速:
将 doca / dpdk 库链接到应用程序。
初始化硬件。
设置应用程序到硬件端口的映射。
用于引导流量的流编程。
随着越来越多的元素卸载到dpu 上,及源代码行( sloc )的增加,开发过程可能会变得复杂。而这正是 doca 抽象库可以帮助解决的:
doca 附带了几个内置库,如doca-dpi、 grpc 、 firefly 时间同步等。这些库支持应用程序的快速即插即用。
doca 构建(如doca_pipe)使您能够模板化管道,消除样板代码并优化流插入。
即将推出的 doca 库,如硬件加速的 lpm (最长前缀匹配),使构建交换机管道变得更容易。这与您在本系列文章中看到的示例应用程序 frr 尤其相关, frr 通常用于使用 bgp 构建 lpm 路由表(或 rib )。
借助 doca ,您还可以在融合加速器上的 gpu 和 dpu 上实现令人激动的开发体验。
关于作者
anuradha karuppiah 是 nvidia 网络的首席软件工程师。 anuradha 使用 frr (自由范围路由软件套件)设计和实现 evpn 解决方案。


教你怎样用麻将牌制作能用的计算机,你说不定可以艳惊四座
can通信与uart通信的难度区别
梯云电梯物联网系统的实现原理
富士康的数字化转型 为中国制造数字化转型搭梯子
基于89C51单片机、RAM和8251实现无线电台通信卡的设计
使用DPDK和NVIDIA DOCA库开发应用程序
超大互动触摸桌方案解析,可实现多人多点控制
基于COMSOL平行流道液冷板对电池散热性能的影响
高通宣布成为2021PEL和平精英职业联赛官方战略合作伙伴
SiC和GaN系统设计工程师不再迷茫
ne555调光电路图大全(五款模拟电路设计原理图详解)
光缆室内布线选择应用
如何理解工控系统中的安全威胁
诺基亚8什么时候上市?诺基亚8发布会最新消息:官方邀请函发出,诺基亚8下月正式发布
餐饮业油烟在线监测仪的作用是什么
美国一所高中建立价值1700多万美元的太阳能墙
台积电复盘 产线恢复生产
尼得科动力系统研发出混合动力电动汽车离合器控制模块新产品
半导体制冷技术应用--肿瘤免疫化学发光检测仪
万元超轻佳能全画幅微单EOS RP 性价比超高