在這篇文章中,我將帶您了解 FRR DOCA 數(shù)據(jù)平面插件的創(chuàng)建過(guò)程,并向您展示如何使用全新的 DOCAflow 庫(kù)卸載 PBR 規(guī)則。在上一篇文章中,您了解了使用 DPDK rte_flow 庫(kù)創(chuàng)建 FRR 數(shù)據(jù)平面插件,以加速 BlueField 上的 PBR 規(guī)則。
向 Zebra 添加 DOCA 數(shù)據(jù)平面插件
我仍然使用 DPDK API 進(jìn)行硬件初始化,但隨后使用 DOCAflow API 來(lái)設(shè)置數(shù)據(jù)平面流管道。為此,我必須將 DPDK (libdpdk.pc)和 DOCAflow(doca-flow.pc)共享庫(kù)鏈接到 DOCA 數(shù)據(jù)平面插件。
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 和 DOCAflow添加了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 和 DOCAflow
庫(kù)及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
啟動(dòng) FRR 服務(wù)時(shí),可以啟用 DOCA 數(shù)據(jù)平面插件。
zebra_options= " -M dplane_doca -A 127.0.0.1"
硬件初始化和端口映射
使用 DPDK API 、rte_eal_init
和rte_eth_dev_info_get
初始化硬件,并設(shè)置 Zebra 接口到 DPDK 端口映射。此工作流與上一節(jié)中的 DPDK 數(shù)據(jù)平面插件相同。
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:~#
DOCAflow初始化
為了使用doca-flow
編寫(xiě) PBR 規(guī)則,我必須初始化doca-flow
和doca-flow-port
數(shù)據(jù)庫(kù)。此初始化是在使用rte_eal_init
初始化硬件后完成的。
我使用doca_flow_init通過(guò)配置流和隊(duì)列計(jì)數(shù)來(lái)初始化doca-flow
庫(kù)。
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);
當(dāng)我使用 DPDK 設(shè)置硬件端口時(shí),我必須使用dpdk_port-id
將它們安裝到doca-flow-port
數(shù)據(jù)庫(kù)中。
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 編寫(xiě) PBR 規(guī)則
通過(guò)一系列用于匹配、動(dòng)作、轉(zhuǎn)發(fā)和監(jiān)控屬性的數(shù)據(jù)結(jié)構(gòu)來(lái)對(duì) DOCA 流進(jìn)行編程。
struct doca_flow_match match, match_mask; struct doca_flow_actions actions; struct doca_flow_fwd fwd; struct doca_flow_monitor monitor;
流匹配
這被指定為匹配和匹配掩碼。匹配掩碼是可選的,如果未指定,則由doca-flow
庫(kù)自動(dòng)填充。
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;
我跳過(guò)了填充eth
或eth-mask
等字段。這是因?yàn)?code style="border-width:0px;vertical-align:baseline;padding:0px;margin:0px;background-color:rgb(244,244,244);">doca-flow庫(kù)可以基于其他匹配字段dst_ip
或src_ip
自動(dòng)將此類(lèi)字段填充到RTE_ETHER_TYPE_IPV4
或RTE_ETHER_TYPE_IPV6
。
流動(dòng)作
為了路由數(shù)據(jù)包,我必須將目標(biāo) MAC 地址更改為網(wǎng)關(guān)( leaf2 ) MAC ,減少 TTL ,并更改源 MAC 地址。這一點(diǎn)最初在上一篇文章中討論,使用 NVIDIA BlueField DPU 和 DPDK 開(kāi)發(fā)應(yīng)用程序.
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);
流轉(zhuǎn)發(fā)
然后,我將輸出端口設(shè)置為上行鏈路。
memset(&fwd, 0, sizeof(fwd)); fwd.type = DOCA_FLOW_FWD_PORT; fwd.port_id = out_port_id;
流監(jiān)控
我設(shè)置了流量計(jì)數(shù)器進(jìn)行故障排除。
memset(&monitor, 0, sizeof(monitor)); monitor.flags |= DOCA_FLOW_MONITOR_COUNT;
DOCA流管道和入口
流程創(chuàng)建分為兩步:
創(chuàng)建流管道。
將流條目添加到流管道。
第一步是為查找階段創(chuàng)建軟件模板。第二步使用模板在硬件中的流進(jìn)行編程。
當(dāng)您必須對(duì)許多類(lèi)似的流進(jìn)行編程時(shí),管道非常有用。對(duì)于這種情況,可以設(shè)置單個(gè)匹配模板(管道),并指示在創(chuàng)建流條目時(shí)必須更新哪個(gè)匹配字段(例如,第 4 層目標(biāo)端口)。后續(xù)的流條目只需要 填充與管道(第 4 層目標(biāo)端口)不同的匹配字段。
對(duì)于 PBR ,每個(gè)流模式都是唯一的,所以我使用已經(jīng)填充的流屬性為每個(gè) PBR 規(guī)則創(chuàng)建了一個(gè)單獨(dú)的管道和條目。
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);
流刪除
流管道和條目創(chuàng)建 API 返回管道和流指針,這些指針必須被緩存以供后續(xù)刪除。
doca_flow_pipe_rm_entry( 0, flow_entry); doca_flow_destroy_pipe (port_id, flow_pipe);
流統(tǒng)計(jì)
在創(chuàng)建流時(shí),我設(shè)置了DOCA_FLOW_MONITOR_COUNT
標(biāo)志。我使用doca_flow_query
查詢(xún)了流統(tǒng)計(jì)數(shù)據(jù)。
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);
驗(yàn)證硬件加速
FRR-PBR 規(guī)則配置和流量生成與dpdk-plugin
相同。流量按預(yù)期由 DPU 硬件轉(zhuǎn)發(fā),并可使用流計(jì)數(shù)器進(jìn)行驗(yàn)證。
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:~#
還可以使用硬件條目進(jìn)行驗(yàn)證:
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
通過(guò)使用doca-flow
,F(xiàn)RR 現(xiàn)在具有了第二個(gè)數(shù)據(jù)平面插件,可用于 PBR 規(guī)則的硬件加速。
應(yīng)用程序開(kāi)發(fā)要點(diǎn)
在本系列文章中,您了解了如何使用rte_flow或doca_flow通過(guò)四個(gè)步驟對(duì) DPU 網(wǎng)絡(luò)應(yīng)用程序進(jìn)行硬件加速:
將 DOCA / DPDK 庫(kù)鏈接到應(yīng)用程序。
初始化硬件。
設(shè)置應(yīng)用程序到硬件端口的映射。
用于引導(dǎo)流量的流編程。
隨著越來(lái)越多的元素卸載到DPU 上,及源代碼行( SLOC )的增加,開(kāi)發(fā)過(guò)程可能會(huì)變得復(fù)雜。而這正是 DOCA 抽象庫(kù)可以幫助解決的:
DOCA 附帶了幾個(gè)內(nèi)置庫(kù),如doca-dpi、 gRPC 、 Firefly 時(shí)間同步等。這些庫(kù)支持應(yīng)用程序的快速即插即用。
DOCA 構(gòu)建(如doca_pipe)使您能夠模板化管道,消除樣板代碼并優(yōu)化流插入。
即將推出的 DOCA 庫(kù),如硬件加速的 LPM (最長(zhǎng)前綴匹配),使構(gòu)建交換機(jī)管道變得更容易。這與您在本系列文章中看到的示例應(yīng)用程序 FRR 尤其相關(guān), FRR 通常用于使用 BGP 構(gòu)建 LPM 路由表(或 RIB )。
借助 DOCA ,您還可以在融合加速器上的 GPU 和 DPU 上實(shí)現(xiàn)令人激動(dòng)的開(kāi)發(fā)體驗(yàn)。
關(guān)于作者
Anuradha Karuppiah 是 NVIDIA 網(wǎng)絡(luò)的首席軟件工程師。 Anuradha 使用 FRR (自由范圍路由軟件套件)設(shè)計(jì)和實(shí)現(xiàn) EVPN 解決方案。
審核編輯:郭婷
-
NVIDIA
+關(guān)注
關(guān)注
14文章
4994瀏覽量
103166
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論