DPDK Sample Applications User Guides(41)Test Pipeline应用程序

官方文档查看地址:
http://doc.dpdk.org/guides/sample_app_ug/test_pipeline.html
PDF下载地址:
https://www.intel.com/content/www/us/en/embedded/technology/packet-processing/dpdk/dpdk-sample-applications-user-guide.html?eu-cookie-notice

本篇难度系数:
翻译:☆☆☆☆☆
理解:★★☆☆☆

41.测试管道的应用程序
测试管道应用程序演示了DPDK包框架工具套件的使用。其目的是演示单表DPDK管道的性能

41.1.概述
应用程序使用三个CPU核心:

  • Core A(“RX Core”)接收来自NIC端口的流量,并通过SW队列向Core B提供流量。
  • Core B(“Pipeline Core”)实现了一个单表DPDK管道,其类型可以通过特定的命令行参数进行选择。Core B通过软件队列接收来自Core A的流量,根据表条目中配置的被输入包命中的操作对其进行处理,并通过另一组软件队列将其提供给Core C。
  • Core C(“TX Core”)通过软件队列接收来自Core B的流量,并将其发送到NIC端口进行传输。
    在这里插入图片描述

41.2.编译应用程序

要编译示例应用程序,请参见 Compiling the Sample Applications
应用程序位于$RTE_SDK/app/test-pipline目录中。

41.3.运行应用程序

41.3.1应用程序命令行
应用程序执行命令行为:

./test-pipeline [EAL options] -- -p PORTMASK --TABLE_TYPE

c或-l EAL CPU coremask/corelist选项必须恰好包含3个CPU内核。核心掩码中的第一个CPU内核分配给核心A,第二个CPU分配给核心B,第三个CPU分配给核心C。
PORTMASK 端口掩码参数必须包含2或4个端口。

41.3.2表类型和行为
表1描述了使用的表类型及其填充方式。哈希表预先填充了1600万个键。对于哈希表,可以选择以下参数:

  • 可配置密钥大小实现或固定(专用)密钥大小实现(例如hash-8-ext或hash-spec-8-ext)。对于8字节和16字节的密钥大小,期望密钥大小专用实现提供更好的性能,而对于较大的密钥大小,期望密钥大小非专用实现提供更好的性能;
  • 密钥大小(例如散列-spec-8-ext或散列-spec-16-ext)。可用选项有8、16和32字节;
  • 表类型(例如hash-spec-16-ext或hash-spec-16-lru)。可用的选项是ext(可扩展桶)或lru(最近最少使用)。
#TABLE_TYPEDescription of Core B TablePre-added Table Entries
1noneCore B is not implementing a DPDK pipeline. Core B is implementing a pass-through from its input set of software queues to its output set of software queues.N/A
2stubStub table. Core B is implementing the same pass-through functionality as described for the “none” option by using the DPDK Packet Framework by using one stub table for each input NIC port.N/A
3hash-[spec]-8-lruLRU hash table with 8-byte key size and 16 million entries.16 million entries are successfully added to the hash table with the following key format:[4-byte index, 4 bytes of 0]The action configured for all table entries is “Sendto output port”, with the output port index uniformly distributed for the range of output ports.The default table rule (used in the case of a lookup miss) is to drop the packet.At run time, core A is creating the following lookup key and storing it into the packet meta data for core B to use for table lookup:[destination IPv4 address, 4 bytes of 0]
4hash-[spec]-8-extExtendable bucket hash table with 8-byte key size and 16 million entries.Same as hash-[spec]-8-lru table entries, above.
5hash-[spec]-16-lruLRU hash table with 16-byte key size and 16 million entries.16 million entries are successfully added to the hash table with the following key format:[4-byte index, 12 bytes of 0]The action configured for all table entries is “Send to output port”, with the output port index uniformly distributed for the range of output ports.The default table rule (used in the case of a lookup miss) is to drop the packet.At run time, core A is creating the following lookup key and storing it into the packet meta data for core B to use for table lookup:[destination IPv4 address, 12 bytes of 0]
6hash-[spec]-16-extExtendable bucket hash table with 16-byte key size and 16 million entries.Same as hash-[spec]-16-lru table entries, above.
7hash-[spec]-32-lruLRU hash table with 32-byte key size and 16 million entries.16 million entries are successfully added to the hash table with the following key format:[4-byte index, 28 bytes of 0].The action configured for all table entries is “Send to output port”, with the output port index uniformly distributed for the range of output ports.The default table rule (used in the case of a lookup miss) is to drop the packet.At run time, core A is creating the following lookup key and storing it into the packet meta data for Lpmcore B to use for table lookup:[destination IPv4 address, 28 bytes of 0]
8hash-[spec]-32-extExtendable bucket hash table with 32-byte key size and 16 million entries.Same as hash-[spec]-32-lru table entries, above.
9lpmLongest Prefix Match (LPM) IPv4 table.In the case of two ports, two routes are added to the table:[0.0.0.0/9 => send to output port 0][0.128.0.0/9 => send to output port 1]In case of four ports, four entries are added to the table:[0.0.0.0/10 => send to output port 0][0.64.0.0/10 => send to output port 1][0.128.0.0/10 => send to output port 2][0.192.0.0/10 => send to output port 3]The default table rule (used in the case of a lookup miss) is to drop the packet.At run time, core A is storing the IPv4 destination within the packet meta data to be later used by core B as the lookup key.
10aclAccess Control List (ACL) tableIn the case of two ports, two ACL rules are added to the table:[priority = 0 (highest),IPv4 source = ANY,IPv4 destination = 0.0.0.0/9,L4 protocol = ANY,TCP source port = ANY,TCP destination port = ANY=> send to output port 0][priority = 0 highest),IPv4 source = ANY,IPv4 destination = 0.128.0.0/9,L4 protocol = ANY,TCP source port = ANY,TCP destination port = ANY=> send to output port 0].The default table rule (used in the case of a lookup miss) is to drop the packet.

41.3.3输入流量
无论core B管道使用哪种表类型,都可以使用相同的输入流量来命中所有具有均匀分布的表条目,这导致在输出NIC端口集上发送的数据包分布均匀。输入流量配置文件为TCP/IPv4包,其中:

  • 目标IP地址为A.B.C.D A固定为0,B、C、D随机
  • 源IP地址固定为0.0.0.0
  • 目标TCP端口固定为0
  • 源TCP端口固定为0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用C++编程语言编写DPDK应用程序与使用C语言类似,只是在代码的组织和语法上有一些差异。下面是一个简单的示例,展示了如何使用C++编写一个DPDK应用程序来接收和处理数据包: ```cpp #include <iostream> #include <rte_eal.h> #include <rte_ethdev.h> #include <rte_mbuf.h> #define RX_RING_SIZE 128 #define NUM_MBUFS 8191 #define MBUF_CACHE_SIZE 250 #define BURST_SIZE 32 int main(int argc, char *argv[]) { int ret; // 初始化DPDK环境 ret = rte_eal_init(argc, argv); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to initialize DPDK environment\n"); } // 获取可用的网卡数量 int num_ports = rte_eth_dev_count_avail(); if (num_ports == 0) { rte_exit(EXIT_FAILURE, "No available Ethernet ports\n"); } // 配置第一个网卡 ret = rte_eth_dev_configure(0, 1, 1, NULL); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to configure Ethernet port\n"); } // 分配和初始化内存池 struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS, MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) { rte_exit(EXIT_FAILURE, "Failed to create memory pool\n"); } // 启动第一个网卡 ret = rte_eth_dev_start(0); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to start Ethernet port\n"); } // 设置接收队列 ret = rte_eth_rx_queue_setup(0, 0, RX_RING_SIZE, rte_eth_dev_socket_id(0), NULL, mbuf_pool); if (ret < 0) { rte_exit(EXIT_FAILURE, "Failed to setup RX queue\n"); } // 接收和处理数据包 while (true) { struct rte_mbuf *bufs[BURST_SIZE]; const uint16_t nb_rx = rte_eth_rx_burst(0, 0, bufs, BURST_SIZE); for (uint16_t i = 0; i < nb_rx; ++i) { // 处理接收到的数据包 // ... // 释放缓冲区 rte_pktmbuf_free(bufs[i]); } } return 0; } ``` 上述示例中,我们使用了C++的标准库头文件,并使用了DPDK提供的C API函数和数据结构。在编写DPDK应用程序时,需要包含适当的DPDK头文件,并按照DPDK的编程模型进行操作。此外,还需要注意资源的分配和释放,如内存池和缓冲区的创建和释放。 需要注意的是,上述示例仅用于演示目的,实际的DPDK应用程序可能需要更复杂的逻辑和功能,如数据包解析、协议处理、流量控制等。开发人员可以根据自己的需求在此基础上进行扩展和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值