转载 : http://aidaiz.com/dpdk_l2fwd/
DPDK-l2fwd详解
L2 forwarding sample application在DPDK(Data Plane Development Kit)的基础上实现了第二层(链路层)的数据包转发。
Title: dpdk-l2fwd详解
Author: Yunyao Zhang(张云尧)
E-mail: aidaizyy@gmail.com
Last Modified: 2015-04-15
概要
版本:DPDK-1.8.0
本例中实现了相邻端口之间的相互转发。
比如一共4个端口可用,那么端口1收到数据后会转发给端口2,端口2收到数据后会转发给端口1,端口3和端口4也会相互转发。
编译
设置环境变量
|
|
进入示例目录
|
|
编译
|
|
运行
|
|
-
EAL options
- DPDK EAL的默认参数,必须参数为-c COREMASK -n NUM。
- COREMASK:一个十六进制位掩码表示分配的逻辑内核数量。
- NUM:一个十进制整数表示内存通道数量。
-
-p PORTMASK
PORTMASK:一个十六进制位掩码表示分配的端口数量。 -
-q NQ
NQ:表示分配给每个逻辑内核的收发队列数量。 -
-T t
t: 表示打印统计数据到屏幕上的时间间隔,默认为10秒。
|
|
表示,分配给4个逻辑内核,每个内核分别有4个收发队列,而一共分配了16个端口。
详解
初始化EAL(Environment Abstraciton Layer)
|
|
参数传递
|
|
EAL参数传递已经在rte_eal_init()函数中完成了,这里主要传递“–”后面的参数。
传递参数之后,得到三个变量。
- l2fwd_enabled_port_mask:可用端口位掩码
- l2fwd_rx_queue_per_lcore:每个逻辑内核的收取队列数量
- timer_period:打印统计数据的时间间隔
创建内存池
|
|
- “mbuf_pool”:内存池的名称
- NB_MBUF:内存池中存储mbuf的数量
- MBUF_SIZE: mbuf的大小
- 32:内存池缓存的大小
端口处理
|
|
|
|
可用端口位掩码表示,左数第n位如果为1,表示端口n可用,如果左数第n位如果为0,表示端口n不可用。
要得到第x位为1还是0,我们的方法是将1左移x位,得到一个只在x位为1,其他位都为0的数,再与位掩码相与。结果为1,那么第x位为1,结果位0,那么第x位为0.
设置每个端口的目的端口
这里设置数据包进入端口后,转发给相邻的端口。
每两个端口为一对,相互转发。
|
|
初始化端口的配置信息
为每个端口分配到相应的逻辑内核
每个端口只对应一个逻辑内核
每个逻辑内核对应l2fwd_rx_queue_per_lcore个端口
|
|
初始化每个端口
|
|
检查每个端口的连接状态
|
|
在每个逻辑内核上启动线程,开始转发
|
|
收包
|
|
转发
替换源MAC地址和目的MAC地址
|
|
将数据包推送至发送队列,如果发送队列存够MAX_PKT_BURST,即每次最大收取包的数量,就会发包
|
|
每隔一定时间也会发包
|
|
这两种情况都会产生发包,无论是发送队列存够阈值MAX_PKT_BURST,或者,时间差超过阈值brain_tsc,都会把发送队列上MAX_PKT_BURST个数据包推送出去,如果不足MAX_PKT_BURST,则把发送队列上全部数据包推送出去。
发包函数
|
|
在函数rte_eth_tx_burst()中:
- port:端口号。
- queueid:端口中的发送队列号。本例中每个端口都只有一个发送队列,所以固定为0。
- m_table:**rte_mbuf数据
- n:发送包的数量
转载请注明原作者和出处。