我将使用一个小型存储库来存储 DPDK 的进度和测试程序,DPDK 是一个对于快速数据包处理非常有用的内核旁路库。
该存储库使用我的 DPDK Common 项目,以使事情变得更简单。
警告- 随着时间的推移,我仍在添加更多示例,并且我需要测试新功能/方法。
如果您想使用默认选项构建 DPDK,假设您有ninja
和meson
等要求,以下内容应该可以工作。
git clone https://github.com/DPDK/dpdk.git
cd dpdk/
meson build
cd build
ninja
sudo ninja install
sudo ldconfig
DPDK 中所有需要的头文件都将存储在/usr/local/include/
内。
您可以使用以下方式接收ninja
和meson
。
sudo apt update
sudo apt install python3 python3-pip
sudo pip3 install meson # Pip3 is used because 'apt' has an outdated version of Meson usually.
sudo apt install ninja-build
您可以使用git
和make
在此存储库中构建源文件。
git clone --recursive https://github.com/gamemann/The-DPDK-Examples.git
cd The-DPDK-Examples/
make
默认情况下,可执行文件将在build/
目录中构建。
此存储库中的所有 DPDK 应用程序都支持 DPDK 的 EAL 参数。这些可以在这里找到。
例如,这对于指定要配置的 l 核和端口的数量很有用。
在此 DPDK 应用程序中,到达 UDP 目标端口 8080 的任何数据包都将被丢弃。否则,如果数据包的以太网标头类型是 IPv4 或 VLAN,它将交换源/目标 MAC 和 IP 地址以及 UDP 源/目标端口,然后将数据包发送出 TX 路径(基本上是从数据包的来源处转发数据包) 。
除了 EAL 参数之外,还专门为此应用提供了以下参数。
-p --portmask => The port mask to configure (e.g. 0xFFFF).
-P --portmap => The port map to configure (in '(x, y),(b,z)' format).
-q --queues => The amount of RX and TX queues to setup per port (default and recommended value is 1).
-x --promisc => Whether to enable promiscuous on all enabled ports.
-s --stats => If specified, will print real-time packet counter stats to stdout.
这是一个例子:
./dropudp8080 -l 0-1 -n 1 -- -q 1 -p 0xff -s
在此 DPDK 应用程序中,创建了一个简单的路由哈希表,其中键是目标 IP 地址,值是要转发到的 MAC 地址。
路由按以下格式从/etc/l3fwd/routes.txt
文件中读取。
<ip address> <mac address in xx:xx:xx:xx:xx:xx>
下面是一个例子。
10.50.0.4 ae:21:14:4b:3a:6d
10.50.0.5 d6:45:f3:b1:a4:3d
处理数据包时,我们确保它是 IPv4 或 VLAN 数据包(在本例中,我们将数据包数据偏移四个字节,以便我们可以毫无问题地处理数据包的其余部分)。然后,我们以目标 IP 作为路由哈希表上的键进行查找。如果查找成功,源 MAC 地址将替换为目标 MAC 地址(数据包将从它们到达的同一端口发出,因为我们创建了 TX 缓冲区和队列),并且目标 MAC 地址将替换为 IP 的 MAC 地址是从上面提到的路由文件分配的。否则,数据包将被丢弃,并且数据包丢弃计数器会递增。
除了 EAL 参数之外,还专门为此应用提供了以下参数。
-p --portmask => The port mask to configure (e.g. 0xFFFF).
-P --portmap => The port map to configure (in '(x, y),(b,z)' format).
-q --queues => The amount of RX and TX queues to setup per port (default and recommended value is 1).
-x --promisc => Whether to enable promiscuous on all enabled ports.
-s --stats => If specified, will print real-time packet counter stats to stdout.
这是一个例子:
./simple_l3fwd -l 0-1 -n 1 -- -q 1 -p 0xff -s
在此应用程序中,如果源 IP 等于或超过命令行中指定的每秒数据包数或每秒字节数,则数据包将被丢弃。否则,以太网和 IP 地址与 TCP/UDP 端口一起交换,并且数据包从 TX 路径转发回。
数据包统计信息也包含在-s
标志中。
支持以下命令行选项。
-p --portmask => The port mask to configure (e.g. 0xFFFF).
-P --portmap => The port map to configure (in '(x, y),(b,z)' format).
-q --queues => The amount of RX and TX queues to setup per port (default and recommended value is 1).
-x --promisc => Whether to enable promiscuous on all enabled ports.
-s --stats => If specified, will print real-time packet counter stats to stdout.
--pps => The packets per second to limit each source IP to.
--bps => The bytes per second to limit each source IP to.
这是一个例子:
./ratelimit -l 0-1 -n 1 -- -q 1 -p 0xff -s
注意- 该应用程序通过我在 DPDK Common 项目中创建的自定义函数check_and_del_lru_from_hash_table()
支持 LRU 回收。使用此函数时,请确保在包含 DPDK Common 头文件之前定义USE_HASH_TABLES
。
这是一个小型应用程序,为哈希表实现手动 LRU 方法。一段时间以来,我一直在尝试让 LRU 表在这些库中工作。但是,我在实际初始化表方面取得了零成功。
因此,我决定继续使用这些库并实现我自己的 LRU 功能。我基本上使用rte_hash_get_key_with_position()
函数来检索要删除的最旧的密钥。但是,新条目似乎插入到最近删除的位置,因此您必须不断增加位置值直至表的最大条目数。也就是说,一旦位置值超过最大表条目数,您需要将其设置回 0。
不需要命令行选项,但仍然支持 EAL 参数。不过,它们不会有什么不同。
这是一个例子:
./ratelimit