首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在DPDK /TX回调示例应用程序中没有出现流量

在DPDK /TX回调示例应用程序中没有出现流量
EN

Stack Overflow用户
提问于 2018-09-11 13:46:28
回答 2查看 1.7K关注 0票数 1

我是DPDK地区的大一新生。我从DPDK主页提供的示例应用程序开始。我被困在这个例子中- DPDK /TX回调示例应用程序。条件是很长一段时间内不会出现任何流量(但输出)。我想原因是我无法将流量发送到DPDK端口。

我首先显示我的设置一步一步。一开始的nic信息

然后,我拒绝了eth2eth3

代码语言:javascript
复制
sudo ifconfig eth2 down
sudo ifconfig eth3 down

接下来,使用usertools/dpdk-setup.sh构建DPDK源(i686-native-linuxapp-gcc),插入IGB模块,为非NUMA系统设置巨型映射,将设备绑定到IGB模块。这是我的设备设置和漏电列表:

一切准备都做好了。我开始构建示例应用程序。使用以下命令

代码语言:javascript
复制
export RTE_SDK=~/dpdk/dpdk-18.08
export RTE_TARGET=i686-native-linuxapp-gcc
cd examples/rxtx_callbacks/
make

一切正常,输出编译信息:

代码语言:javascript
复制
mininet@mininet-vm:~/dpdk/dpdk-18.08/examples/rxtx_callbacks$ make
  CC main.o
  LD rxtx_callbacks
  INSTALL-APP rxtx_callbacks
  INSTALL-MAP rxtx_callbacks.map

然后,我开始使用以下方法运行示例应用程序:

代码语言:javascript
复制
sudo ./build/rxtx_callbacks -l1 -n4

执行日志是:

代码语言:javascript
复制
mininet@mininet-vm:~/dpdk/dpdk-18.08/examples/rxtx_callbacks$ sudo ./build/rxtx_callbacks -l1 -n4
EAL: Detected 2 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Probing VFIO support...
EAL: PCI device 0000:00:08.0 on NUMA socket 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:09.0 on NUMA socket 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:0a.0 on NUMA socket 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:11.0 on NUMA socket 0
EAL:   probe driver: 8086:100f net_e1000_em
Port 0 MAC: 08 00 27 9d f9 5a
Port 1 MAC: 08 00 27 7f e8 8a

随着时间的推移,什么都不会发生。但是,我发现执行结果应该如下所示:

代码语言:javascript
复制
root@ubuntu:/home/chang/dpdk/examples/rxtx_callbacks/build# ./rxtx_callbacks -l 1 -n 4 
EAL: Detected 8 lcore(s)
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Multi-process socket /var/run/.rte_unix
EAL: Probing VFIO support...
EAL: PCI device 0000:02:01.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:02.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:03.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
EAL: PCI device 0000:02:04.0 on NUMA socket -1
EAL:   Invalid NUMA socket, default to 0
EAL:   probe driver: 8086:100f net_e1000_em
Port 0 MAC: 00 0c 29 f7 4d 25
Port 1 MAC: 00 0c 29 f7 4d 2f

Core 1 forwarding packets. [Ctrl+C to quit]
Latency = 629 cycles
Latency = 787 cycles
^C

我试图找到结果,我在lcore_main()函数中添加了一个lcore_main(),如下所示:

代码语言:javascript
复制
for (;;) {
        RTE_ETH_FOREACH_DEV(port) {
                struct rte_mbuf *bufs[BURST_SIZE];
                /* printf("receive a packet\n"); */
                const uint16_t nb_rx = rte_eth_rx_burst(port, 0,
                                bufs, BURST_SIZE);
                if (unlikely(nb_rx == 0))
                        continue;
                printf("send a packet\n");
                const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,
                                bufs, nb_rx);
                if (unlikely(nb_tx < nb_rx)) {
                        uint16_t buf;

                        for (buf = nb_tx; buf < nb_rx; buf++)
                                rte_pktmbuf_free(bufs[buf]);
                }
        }
}

我发现没有收到,因为它应该通过检查- if (unlikely(nb_rx == 0))。因此,我尝试用Linux (不是DPDK)提供的pktgen自己发送数据包。但是失败了。我会展示我的踪迹。

代码语言:javascript
复制
#!/bin/sh

modprobe pktgen

function pgset() {
    local result

    echo $1 > $PGDEV

    result=`cat $PGDEV | fgrep "Result: OK:"`
    if [ "$result" = "" ]; then
         cat $PGDEV | fgrep Result:
    fi
}

function pg() {
    echo inject > $PGDEV
    cat $PGDEV
}

# Config Start Here -----------------------------------------------------------


# thread config
# Each CPU has own thread. Two CPU example. We add eth1.

PGDEV=/proc/net/pktgen/kpktgend_0
  echo "Removing all devices"
 pgset "rem_device_all"
  echo "Adding eth1"
 pgset "add_device eth1"
  echo "Setting max_before_softirq 10000"
 pgset "max_before_softirq 10000"


# device config
# delay 0 means maximum speed.

CLONE_SKB="clone_skb 1000000"
# NIC adds 4 bytes CRC
PKT_SIZE="pkt_size 60"

# COUNT 0 means forever
#COUNT="count 0"
COUNT="count 10000000"
DELAY="delay 0"

PGDEV=/proc/net/pktgen/eth1
  echo "Configuring $PGDEV"
 pgset "$COUNT"
 pgset "$CLONE_SKB"
 pgset "$PKT_SIZE"
 pgset "$DELAY"
 pgset "dst 127.0.0.1"
 # here! the mac address given by the sample application
 pgset "dst_mac  08:00:27:9d:f9:5a" 

# Time to run
PGDEV=/proc/net/pktgen/pgctrl

 echo "Running... ctrl^C to stop"
 pgset "start"
 echo "Done"

# Result can be vieved in /proc/net/pktgen/eth1

不过,什么都没发生。也许,将数据包发送到dpdk端口的方式是错误的。因为dpdk端口位于第二层,所以像ping这样的第三层工具是无用的。示例应用程序一直被卡住,我非常绝望。你能分享一些想法来解决我的问题吗?

谨致问候。

EDIT1:

@Amedeo的答复是可行的,但是,我只能向RX/TX回调应用程序发送一些数据包(几个包而不是流量)。我试过使用Linux提供的,但是接口dtap0 无法接收pktgen生成的流量。下面是我的实验课。

首先,所有准备工作都与上述相同。但是,我使用以下命令运行示例应用程序

代码语言:javascript
复制
 sudo ./build/rxtx_callbacks -l1 -n4 --vdev=net_tap0

而不是

代码语言:javascript
复制
 sudo ./build/rxtx_callbacks -l1 -n4

在运行示例应用程序之后,我可以在ifconfig中看到一个新的nic项。

哦,我需要提到的是,我已经拒绝了eth1,因此eth1eth2eth3都是用于DPDK的。执行输出如下所示:

代码语言:javascript
复制
EAL: Detected 2 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Probing VFIO support...
EAL: PCI device 0000:00:08.0 on NUMA socket 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:09.0 on NUMA socket 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:0a.0 on NUMA socket 0
EAL:   probe driver: 8086:100e net_e1000_em
EAL: PCI device 0000:00:11.0 on NUMA socket 0
EAL:   probe driver: 8086:100f net_e1000_em
rte_pmd_tap_probe(): Initializing pmd_tap for net_tap0 as dtap0
Port 0 MAC: 08 00 27 93 2b 19
Port 1 MAC: 08 00 27 9d f9 5a
Port 2 MAC: 08 00 27 7f e8 8a
Port 3 MAC: fe 02 cf 5a 23 ee

Core 1 forwarding packets. [Ctrl+C to quit]

端口3和fe 02 cf 5a 23 ee正好是ifconfig中的dtap0 nic。现在,我尝试向dtap0接口注入流量。但是,我尝试使用由pktgen Linux提供的,但仍然失败。

我首先使用以下方式给interace dtap0一个ip地址:

代码语言:javascript
复制
sudo dhclient dtap0

并得到:

代码语言:javascript
复制
dtap0     Link encap:Ethernet  HWaddr fe:02:cf:5a:23:ee
          inet addr:10.0.2.16  Bcast:10.0.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:73 errors:0 dropped:0 overruns:0 frame:0
          TX packets:92 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:500
          RX bytes:6651 (6.6 KB)  TX bytes:7808 (7.8 KB)

然后,我编写了一个shell脚本来生成从eth0dtap0的流量负载(我希望如此)。这是剧本。

代码语言:javascript
复制
#!/bin/sh

#modprobe pktgen
modprobe pktgen

function pgset() {
    local result

    echo $1 > $PGDEV

    result=`cat $PGDEV | fgrep "Result: OK:"`
    if [ "$result" = "" ]; then
         cat $PGDEV | fgrep Result:
    fi
}

function pg() {
    echo inject > $PGDEV
    cat $PGDEV
}

# Config Start Here -----------------------------------------------------------


# thread config
# Each CPU has own thread. Two CPU exammple. We add eth1, eth2 respectivly.

PGDEV=/proc/net/pktgen/kpktgend_0
  echo "Removing all devices"
 pgset "rem_device_all"
  echo "Adding eth0"
 pgset "add_device eth0"
  echo "Setting max_before_softirq 10000"
 pgset "max_before_softirq 10000"


# device config
# delay 0 means maximum speed.

CLONE_SKB="clone_skb 1000000"
# NIC adds 4 bytes CRC
PKT_SIZE="pkt_size 60"

# COUNT 0 means forever
#COUNT="count 0"
COUNT="count 10000000"
DELAY="delay 0"

PGDEV=/proc/net/pktgen/eth0
  echo "Configuring $PGDEV"
 pgset "$COUNT"
 pgset "$CLONE_SKB"
 pgset "$PKT_SIZE"
 pgset "$DELAY"
 # ip address of interface dtap0
 pgset "dst 10.0.2.16"
 # the mac address of interface dtap0
 pgset "dst_mac  fe:02:cf:5a:23:ee"

# Time to run
PGDEV=/proc/net/pktgen/pgctrl

 echo "Running... ctrl^C to stop"
 pgset "start"
 echo "Done"

运行此脚本后,我发现接口eth0正在生成输出数据包(使用nloadifconfig)。但是,接口dtap0没有传入通信量。我也尝试iperf发送流量,但是dtap0既不能处理TCP连接,也不能处理UDP ACK。iperfping都不可用。

谢谢你对我的问题有任何看法。

EDIT2:

感谢@Amedeo的份额。我已经了解了如何使用pktgen提供的Linux来向RX/TX Callback示例应用程序发送数据包。

运行RX/TX Callback示例应用程序的所有内容都与EDIT1相同。我将pktgen的脚本更改如下:

代码语言:javascript
复制
#!/bin/sh

#modprobe pktgen
modprobe pktgen

function pgset() {
    local result

    echo $1 > $PGDEV

    result=`cat $PGDEV | fgrep "Result: OK:"`
    if [ "$result" = "" ]; then
         cat $PGDEV | fgrep Result:
    fi
}

function pg() {
    echo inject > $PGDEV
    cat $PGDEV
}

# Config Start Here -----------------------------------------------------------


# thread config
# Each CPU has own thread. Two CPU exammple. We add dtap0

PGDEV=/proc/net/pktgen/kpktgend_1
  # echo "Removing all devices"
 # pgset "rem_device_all"
  echo "Adding dtap0"
 pgset "add_device dtap0"
  echo "Setting max_before_softirq 10000"
 pgset "max_before_softirq 10000"


# device config
# delay 0 means maximum speed.

CLONE_SKB="clone_skb 1000000"
# NIC adds 4 bytes CRC
PKT_SIZE="pkt_size 60"

# COUNT 0 means forever
#COUNT="count 0"
COUNT="count 10000000"
DELAY="delay 0"

PGDEV=/proc/net/pktgen/dtap0
  echo "Configuring $PGDEV"
 pgset "$COUNT"
 pgset "$CLONE_SKB"
 pgset "$PKT_SIZE"
 pgset "$DELAY"
 # pgset "dst 192.168.211.101"
 # whatever mac address
 pgset "dst_mac ce:2a:23:42:ce:ff"

# Time to run
PGDEV=/proc/net/pktgen/pgctrl

 echo "Running... ctrl^C to stop"
 pgset "start"
 echo "Done"

我需要做的只是从dtap0中发送数据包!和

代码语言:javascript
复制
dtap0 --- dpdk port --- rxtx_callbacks 

一切都很顺利。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-11 18:30:08

人们期望你看不到交通。RX/TX回调示例是L2FWD示例的推广。此代码接收来自一个端口的通信,并将其转发给另一个端口。如果没有传入的通信量,应用程序将永远轮询,尝试接收某些内容,而不会转发任何内容。

因为这两个端口使用的是DPDK驱动程序,所以内核看不到它们。因此,通常的工具(ifconfig、tcpdump、pktgen等)没有看到这些接口。

您只能将一个物理接口绑定到dpdk,并使用tap接口作为第二个接口。tap接口绑定到内核,因此您可以很容易地在其中注入通信量(例如使用tcpreplay)。

要使用tap接口,只需添加参数--vdev=net_tap0

代码语言:javascript
复制
sudo ./build/rxtx_callbacks -l1 -n4 --vdev=net_tap0

这将创建一个从ifconfig可见的接口dtap0。进入此接口的所有通信量将由rxtx_callbacks应用程序接收并转发到另一个物理端口。

来源:https://doc.dpdk.org/guides/nics/tap.html

端到端实验

您还可以删除所有的dpdk物理端口,并只使用两个点击端口。通过这种方式,您可以拥有:

代码语言:javascript
复制
dtap0 --- dpdk port --- rxtx_callbacks --- dpdk port --- dtap1

而这两个水龙头可以通过rxtx_callbacks应用程序相互切换。

复制这些信息的步骤如下:

1)解除DPDK中所有物理接口的绑定

2)使用两个水龙头运行rxtx_callbacks:

代码语言:javascript
复制
sudo ./rxtx_callbacks -l1 -n4 --vdev=net_tap0 --vdev=net_tap1

3)现在您有了两个TAP接口: dtap0和dtap1。将dtap1移动到不同的网络命名空间,并将IP分配给dtap0和dtap1:

代码语言:javascript
复制
sudo ip netns add ns1 
sudo ip link set dtap1 netns ns1
sudo ip netns exec ns1 ifconfig dtap1 11.0.0.2/24
sudo ifconfig dtap0 11.0.0.1/24

4)您可以从dtap1中选择dtap0 (反之亦然):

代码语言:javascript
复制
sudo ping 11.0.0.2
sudo ip netns exec ns1 ping 11.0.0.1

5)清除:将dtap1移动到默认名称空间并删除名称空间。

代码语言:javascript
复制
sudo ip netns exec ns1 ip link set dtap1 netns 1
sudo ip netns del ns1
票数 2
EN

Stack Overflow用户

发布于 2018-09-12 06:24:29

最简单的解决方案是使用一个主机作为DPDK目标,使用另一个主机作为数据包生成器。快速数据包生成器占用大量CPU资源,因此在DPDK目标上运行它肯定会降低DPDK性能。

但是,有时另一个主机不可用,因此第二个最简单的解决方案是在同一主机上连接背对背的物理以太网设备。在您的例子中,DPDK端口、eth2eth3应该使用交叉补丁线与pktgen端口、eth0eth1进行物理连接。

在这种情况下,如果只配置一个具有ip地址的pktgen端口,即:

代码语言:javascript
复制
# ifconfig eth2 down # for DPDK
# ifconfig eth3 down # for DPDK

# ifconfig eth0 172.16.0.1/24 up # for pktgen with an IP (TX)
# ifconfig eth1 up # for pktgen without IP (RX)

# arp -s 172.16.0.2 00:0c:29:f7:4d:25 # MAC of the connected DPDK port

然后,正常的ping 172.16.0.2产生带有DST 172.16.0.2、dst 00:0c:29:f7:4d:25的ICMP包,并将它们发送到eth0,并将eth0连接到DPDK端口。

要查看数据包正在返回eth1,我们应该将接口设置为一种混杂模式。默认情况下,tcpdump会这样做。因此,如果一切都已经启动并运行:

代码语言:javascript
复制
# tcpdump -eni eth1

应该显示从DPDK返回的数据包。一旦您测试了它,就可以迁移到pktgen了。

使用@Amedeo描述的vdev解决方案也应该有效。但是,您将无法通过vdev来推动大量的流量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52277448

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档