dpdk l3fwd/l2fwd实验

目录

1 l3fwd

1.1 组网配置

1.2 运行结果

2 l2fwd

2.1 组网配置

2.2 运行结果


1 l3fwd

1.1 组网配置

vmware启动上三个host:host1、host2、host3。host之间的网口通过虚拟交换机相连。
在host2上跑dpdk-l3fwd打通host1和host3之间的连接,组网如下:

host1-port0(ens38:192.168.56.167)<---->(port0)
										 |
										 |
									(host2_l3fwd)
										 |
										 |
									  (port1)<---->host3-port0(ens39:192.168.30.192)

host1配置:

root@ubuntu:~# route add -net 192.168.30.192 netmask 255.255.255.255 dev ens38
root@ubuntu:~# arp -s 192.168.30.192 00:0c:29:7b:de:9e

root@ubuntu:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens38
192.168.30.192  0.0.0.0         255.255.255.255 UH    0      0        0 ens38
192.168.56.0    0.0.0.0         255.255.255.0   U     101    0        0 ens38
root@ubuntu:~# ifconfig ens38
ens38: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.167  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::1e3d:1ae7:33a2:6933  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:09:5f:54  txqueuelen 1000  (Ethernet)
        RX packets 12091  bytes 953417 (953.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 14061  bytes 1333363 (1.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@ubuntu:~# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.56.254           ether   00:50:56:ec:59:30   C                     ens38
192.168.56.1             ether   00:50:56:c0:00:03   C                     ens38
192.168.30.192           ether   00:0c:29:7b:de:9e   CM                    ens38
root@ubuntu:~#

host3配置:

[root@localhost ~]# route add -net 192.168.56.167 netmask 255.255.255.255 dev ens39
[root@localhost ~]# arp -s 192.168.56.167 00:0c:29:09:5f:54
[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.15.2    0.0.0.0         UG    100    0        0 ens35
192.168.15.0    0.0.0.0         255.255.255.0   U     100    0        0 ens35
192.168.30.0    0.0.0.0         255.255.255.0   U     101    0        0 ens39
192.168.56.167  0.0.0.0         255.255.255.255 UH    0      0        0 ens39
[root@localhost ~]# ifconfig ens39
ens39: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.30.192  netmask 255.255.255.0  broadcast 192.168.30.255
        inet6 fe80::9c00:f00c:72a1:9a70  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:7b:de:9e  txqueuelen 1000  (Ethernet)
        RX packets 19223  bytes 1426445 (1.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 29057  bytes 3740888 (3.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@localhost ~]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.56.167           ether   00:0c:29:09:5f:54   CM                    ens39
192.168.15.254           ether   00:50:56:e1:16:e6   C                     ens35
192.168.30.254           ether   00:50:56:f1:2e:fa   C                     ens39
192.168.15.2             ether   00:50:56:e5:50:bf   C                     ens35
192.168.30.1             ether   00:50:56:c0:00:01   C                     ens39
[root@localhost ~]#

host2-l3fwd配置:

dpdk-version:20.11.0

启动两个网口:port0连接host1-port0,port1连接host3-port0。

代码修改:1 添加转发路由(lpm);2 添加下一跳mac地址。补丁如下:

diff --git a/dpdk/examples/l3fwd/l3fwd_lpm.c b/dpdk/examples/l3fwd/l3fwd_lpm.c
old mode 100644
new mode 100755
index 3dcf1fef..67180d97
--- a/dpdk/examples/l3fwd/l3fwd_lpm.c
+++ b/dpdk/examples/l3fwd/l3fwd_lpm.c
@@ -44,8 +44,11 @@ struct ipv6_l3fwd_lpm_route {
 
 /* 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735). */
 static const struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = {
-	{RTE_IPV4(198, 18, 0, 0), 24, 0},
-	{RTE_IPV4(198, 18, 1, 0), 24, 1},
+	{RTE_IPV4(192, 168, 56, 167), 24, 0},
+	{RTE_IPV4(192, 168, 30, 192), 24, 1},
+
+//	{RTE_IPV4(198, 18, 0, 0), 24, 0},
+//	{RTE_IPV4(198, 18, 1, 0), 24, 1},
 	{RTE_IPV4(198, 18, 2, 0), 24, 2},
 	{RTE_IPV4(198, 18, 3, 0), 24, 3},
 	{RTE_IPV4(198, 18, 4, 0), 24, 4},
@@ -110,9 +113,14 @@ lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	struct rte_ipv4_hdr *ipv4_hdr;
 	struct rte_ether_hdr *eth_hdr;
 
+	RTE_LOG(ERR, L3FWD, "#### lpm_get_dst_port,pkt->packet_type = 0x%x\n",pkt->packet_type);
+
 	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
 
 		eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
+		
+		RTE_LOG(ERR, L3FWD, "#### v4 lpm_get_dst_port,ether_type = 0x%04x\n",eth_hdr->ether_type);
+
 		ipv4_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1);
 
 		return lpm_get_ipv4_dst_port(ipv4_hdr, portid,
@@ -120,13 +128,19 @@ lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
 
 		eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
+		RTE_LOG(ERR, L3FWD, "#### v6 lpm_get_dst_port,ether_type = 0x%x\n",eth_hdr->ether_type);
 		ipv6_hdr = (struct rte_ipv6_hdr *)(eth_hdr + 1);
 
 		return lpm_get_ipv6_dst_port(ipv6_hdr, portid,
 					     qconf->ipv6_lookup_struct);
 	}
 
-	return portid;
+	eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
+	RTE_LOG(ERR, L3FWD, "#### vx lpm_get_dst_port,ether_type = 0x%x\n",eth_hdr->ether_type);
+
+	return (portid+1)%2;
+
+	//return portid;
 }
 
 /*
@@ -191,11 +205,11 @@ lpm_main_loop(__rte_unused void *dummy)
 	qconf = &lcore_conf[lcore_id];
 
 	if (qconf->n_rx_queue == 0) {
-		RTE_LOG(INFO, L3FWD, "lcore %u has nothing to do\n", lcore_id);
+		RTE_LOG(ERR, L3FWD, "lcore %u has nothing to do\n", lcore_id);
 		return 0;
 	}
 
-	RTE_LOG(INFO, L3FWD, "entering main loop on lcore %u\n", lcore_id);
+	RTE_LOG(ERR, L3FWD, "#### lpm entering main loop on lcore %u\n", lcore_id);
 
 	for (i = 0; i < qconf->n_rx_queue; i++) {
 
@@ -206,6 +220,7 @@ lpm_main_loop(__rte_unused void *dummy)
 			lcore_id, portid, queueid);
 	}
 
+
 	while (!force_quit) {
 
 		cur_tsc = rte_rdtsc();
@@ -240,13 +255,20 @@ lpm_main_loop(__rte_unused void *dummy)
 			if (nb_rx == 0)
 				continue;
 
+			//RTE_LOG(ERR, L3FWD, "#### lpm rte_eth_rx_burst,nb_rx = %u\n", nb_rx);
+
+
 #if defined RTE_ARCH_X86 || defined __ARM_NEON \
 			 || defined RTE_ARCH_PPC_64
 			l3fwd_lpm_send_packets(nb_rx, pkts_burst,
 						portid, qconf);
+			//RTE_LOG(ERR, L3FWD, "#### lpm l3fwd_lpm_send_packets,portid = %u\n", portid);
 #else
 			l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst,
 							portid, qconf);
+
+			//RTE_LOG(ERR, L3FWD, "#### lpm l3fwd_lpm_no_opt_send_packets,portid = %u\n", portid);
+
 #endif /* X86 */
 		}
 	}
diff --git a/dpdk/examples/l3fwd/main.c b/dpdk/examples/l3fwd/main.c
old mode 100644
new mode 100755
index d62dec43..86003708
--- a/dpdk/examples/l3fwd/main.c
+++ b/dpdk/examples/l3fwd/main.c
@@ -1204,6 +1204,14 @@ main(int argc, char **argv)
 		*(uint64_t *)(val_eth + portid) = dest_eth_addr[portid];
 	}
 
+	// 单独指定目的接口的mac
+	// dest_port0: 	00:0c:29:09:5f:54
+	// dest_port1:	00:0c:29:7b:de:9e
+	dest_eth_addr[0] = (0x540000000000 /*<< 40*/) + (0x5f00000000/* << 32*/) + (0x09 << 24) + (0x29 << 16) + (0x0c << 8) + (0x00 << 0);
+	dest_eth_addr[1] = (0x9e0000000000/* << 40*/) + (0xde00000000/* << 32*/) + (0x7b << 24) + (0x29 << 16) + (0x0c << 8) + (0x00 << 0);
+	*(uint64_t *)(val_eth + 0) = dest_eth_addr[0];
+	*(uint64_t *)(val_eth + 1) = dest_eth_addr[1];
+
 	evt_rsrc = l3fwd_get_eventdev_rsrc();
 	/* parse application arguments (after the EAL ones) */
 	ret = parse_args(argc, argv);

1.2 运行结果

1 在host2上运行 dpdk-l3fwd,备注:加上 -P 打开混杂模式,因为host1 和host3配置的静态arp表项mac为host1/3-port0真实地址。 如果不加 -P 需要将host1/host3配置静态arp表mac地址填写的host2-l3fwd 的port0/port1的mac地址也行。这里多说两句,dpdk不支持arp协议解析,可以仿照l2fwd将port0和port1交叉转发,即dpdk-l3fwd中转发arp-request/reply报文,也可以得到正确的host1/3-port0 mac地址,当然此时需要打开dpdk-l3fwd 混杂模式。

[root@localhost examples]# ./dpdk-l3fwd -c2 -n4 -- -p3 -L -P --config="(0,0,1),(1,0,1)" --parse-ptype

2 在host1或者host3上执行ping操作

结果如下:

2 l2fwd

2.1 组网配置

vmware启动上三个host:host1、host2、host3。host之间的网口通过虚拟交换机相连。
在host2上跑dpdk-l2fwd打通host1和host3之间的连接,组网如下:

host1-port0(ens38:192.168.56.172)<---->(port0)
										 |
										 |
									(host2_l2fwd)
										 |
										 |
									  (port1)<---->host3-port0(ens39:192.168.30.192)

host1配置:

root@ubuntu:~# route add -net 192.168.30.192 netmask 255.255.255.255 dev ens38
root@ubuntu:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 ens38
192.168.30.192  0.0.0.0         255.255.255.255 UH    0      0        0 ens38
192.168.56.0    0.0.0.0         255.255.255.0   U     101    0        0 ens38
root@ubuntu:~#
root@ubuntu:~# ping 192.168.30.192
PING 192.168.30.192 (192.168.30.192) 56(84) bytes of data.
64 bytes from 192.168.30.192: icmp_seq=1 ttl=64 time=1035 ms
64 bytes from 192.168.30.192: icmp_seq=2 ttl=64 time=3.31 ms
64 bytes from 192.168.30.192: icmp_seq=3 ttl=64 time=0.692 ms
64 bytes from 192.168.30.192: icmp_seq=4 ttl=64 time=1.62 ms
^C
--- 192.168.30.192 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3047ms
rtt min/avg/max/mdev = 0.692/260.381/1035.899/447.746 ms, pipe 2
root@ubuntu:~# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.30.192           ether   00:0c:29:7b:de:9e   C                     ens38
192.168.56.1             ether   00:50:56:c0:00:03   C                     ens38
192.168.56.254           ether   00:50:56:ec:59:30   C                     ens38

host3配置:

[root@localhost ~]# route add -net 192.168.56.172 netmask 255.255.255.255 dev ens39
[root@localhost ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.15.2    0.0.0.0         UG    100    0        0 ens35
192.168.15.0    0.0.0.0         255.255.255.0   U     100    0        0 ens35
192.168.30.0    0.0.0.0         255.255.255.0   U     101    0        0 ens39
192.168.56.172  0.0.0.0         255.255.255.255 UH    0      0        0 ens39
[root@localhost ~]# tcpdump -i ens39 host 192.168.56.172 -w l2fwd_test.pcap
dropped privs to tcpdump
tcpdump: listening on ens39, link-type EN10MB (Ethernet), capture size 262144 bytes
^C56 packets captured
56 packets received by filter
0 packets dropped by kernel
[root@localhost ~]# pwd
/root
[root@localhost ~]# arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.30.1             ether   00:50:56:c0:00:01   C                     ens39
192.168.56.172           ether   00:0c:29:09:5f:54   C                     ens39
192.168.15.2             ether   00:50:56:e5:50:bf   C                     ens35

host2-l2fwd配置:

dpdk-version:20.11.0

启动两个网口:port0连接host1-port0,port1连接host3-port0。

代码修改:添加下一跳mac地址。补丁如下:

diff --git a/dpdk/examples/l2fwd/main.c b/dpdk/examples/l2fwd/main.c
old mode 100644
new mode 100755
index 3377b083..d310a9fe
--- a/dpdk/examples/l2fwd/main.c
+++ b/dpdk/examples/l2fwd/main.c
@@ -168,10 +168,23 @@ l2fwd_mac_updating(struct rte_mbuf *m, unsigned dest_portid)
 
 	eth = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
 
-	/* 02:00:00:00:00:xx */
+	// 02:00:00:00:00:xx 
 	tmp = &eth->d_addr.addr_bytes[0];
 	*((uint64_t *)tmp) = 0x000000000002 + ((uint64_t)dest_portid << 40);
 
+
+	// 单独指定目的接口的mac
+	// dest_port0: 	00:0c:29:09:5f:54
+	// dest_port1:	00:0c:29:7b:de:9e
+	if(dest_portid == 0){
+		*((uint64_t *)tmp) = (0x540000000000 ) + (0x5f00000000) + (0x09 << 24) + (0x29 << 16) + (0x0c << 8) + (0x00 << 0);
+	}
+	if(dest_portid == 1){
+		*((uint64_t *)tmp) = (0x9e0000000000) + (0xde00000000) + (0x7b << 24) + (0x29 << 16) + (0x0c << 8) + (0x00 << 0);
+	}
+
+
+
 	/* src addr */
 	rte_ether_addr_copy(&l2fwd_ports_eth_addr[dest_portid], &eth->s_addr);
 }

2.2 运行结果

在 host1上执行ping操作,host3上执行抓包动作,在host2执行l2fwd,命令如下:

./dpdk-l2fwd -c 3 -n 2 -- -q 1  -p 3

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老王不让用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值