2层转发,即对应OSI模型中的数据链路层,该层以Mac帧进行传输,运行在2层的比较有代表性的设备就是交换机了。
当交换机收到数据时,它会检查它的目的MAC地址,然后把数据从目的主机所在的接口转发出去。
交换机之所以能实现这一功能,是因为交换机内部有一个MAC地址表,MAC地址表记录了网络中所有MAC地址与该交换机各端口的对应信息。某一数据帧需要转发时,交换机根据该数据帧的目的MAC地址来查找MAC地址表,从而得到该地址对应的端口,即知道具有该MAC地址的设备是连接在交换机的哪个端口上,然后交换机把数据帧从该端口转发出去。
1.交换机根据收到数据帧中的源MAC地址建立该地址同交换机端口的映射,并将其写入MAC地址表中。
2.交换机将数据帧中的目的MAC地址同已建立的MAC地址表进行比较,以决定由哪个端口进行转发。
3.如数据帧中的目的MAC地址不在MAC地址表中,则向所有端口转发。这一过程称为泛洪(flood)。
4.接到广播帧或组播帧的时候,它立即转发到除接收端口之外的所有其他端口。
该实例中代码写死的网卡为promiscuous混杂模式,我的虚拟机的两个网卡是直连的,拓扑如下:
因此,dpdk-l2fwd中,port 0收到包会转发给port 1,port 1收到包也会转发给相邻端口port 0,下图port 0混杂模式收到29694508个包然后会把这些包都sent给port 1,port 1同样收到其他包后也会转发给port 0。
因此,dpdk l2 fwd这个例子展示了两个网卡在mac层成功的转发了数据包,后续我们会阅读源码并调试程序来看,dpdk是如何实现这一功能的。
pktgen-dpdk是用于对DPDK进行高速数据包测试的工具
使用的命令行参数如下:
-c : 用于指定运行程序的CPU内核掩码。
-n : 用来指定内存通道。
-s : 如果你想用pktgen发送pcap文件 例如 [-s P:PCAP_file] -s 0 : 1.pcap 0表示在第0个网卡,1.pcap及文件名
-P : 启动所有网卡,并进入混杂模式,想指定特定网卡 用 -p mask
-m : 指定lcore和port的映射关系 [1].0, [2].1 core1->port0 core2->port2
由于pktgen是基于dpdk进行开发的,因此选取的pktgen的版本和dpdk的版本一定是相互兼容的,我这边版本如下:
pktgen version:
pktgen-dpdk-pktgen-21.03.1
dpdk version:
20.11.4-rc1
安装过程严格按照install.md即可:
//1. 先升级一下gcc版本
sudo yum install centos-release-scl
sudo yum install devtoolset-7-gcc*
scl enable devtoolset-7 bash
which gcc
gcc -version
//2. 安装libpcap
yum install libpcap
yum install dnf-plugins-core
yum install libpcap-devel
//3. 环境变量设置
export RTE_SDK=
export RTE_TARGET=x86_64-native-linux-gcc
//4. make
这样就可以通过参数配置,指定port去发包了,下面我通过port0发包10000pkts/s,由于port0和port1直连,可以看到port 1收包10000pkts/s。
//core0为主控负责命令行接受,流量显示,消息调度
//core1->port0 core2->port1
./pktgen -l 0-2 -n 3 -- -P -m "[1].0, [2].1"
set 0 dst mac 00:0c:29:93:e6:be
set 0 count 10000
start 0
gdb并打印一些关键信息,加深l2fwd源码理解
解析l2fwd转发的一些命令行配置,我这边配置的是set args -- -q 1 -p 0x3即:
l2fwd_rx_queue_per_lcore:每个逻辑核负责处理一个rx队列,后续可以看到网卡配置时一个网卡配置一个rx队列和tx队列,因此这个参数可以理解为一个逻辑核负责处理一个网卡。
l2fwd_enabled_port_mask:可用的的网卡port的掩码
timer_period:多长时间将统计信息输出到stdout中,缺省为10s
两两一组互为转发,因为我这边就两个port0和port1:
port 0 转给port 1, port 1 转给port 0
这里面用到了rte_eth_devices[portid]-&