目录
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 = ð->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], ð->s_addr);
}
2.2 运行结果
在 host1上执行ping操作,host3上执行抓包动作,在host2执行l2fwd,命令如下:
./dpdk-l2fwd -c 3 -n 2 -- -q 1 -p 3