В образце приложения обратных вызовов DPDK RX/TX трафик не возникает
Я новичок в области DPDK. Я начну с примеров приложений, представленных на главной странице DPDK. Я застрял в примере --- Пример приложения обратного вызова DPDK RX/TX. Условие состоит в том, что трафик не появляется (но выводится) в течение длительного времени. Я думаю, причина в том, что я не могу отправить трафик на порт DPDK.
Сначала я покажу пошаговую настройку. Хорошая информация в начале
Затем я отказываюсь eth2
а также eth3
с
sudo ifconfig eth2 down
sudo ifconfig eth3 down
Далее, используя usertools/dpdk-setup.sh
Я строю источник DPDK (i686-native-linuxapp-gcc
), вставьте модуль IGB UIO, настройте отображение огромных страниц для систем, отличных от NUMA, привяжите устройство к модулю IGB UIO. Это настройки моего устройства и огромный список страниц:
Вся подготовка сделана. Я начинаю строить пример приложения. Используя следующие команды
export RTE_SDK=~/dpdk/dpdk-18.08
export RTE_TARGET=i686-native-linuxapp-gcc
cd examples/rxtx_callbacks/
make
Все в порядке, и выведите информацию о компиляции:
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
Затем я запускаю пример приложения, используя:
sudo ./build/rxtx_callbacks -l1 -n4
Журнал выполнения:
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
Со временем ничего не происходит. Тем не менее, я считаю, что результат выполнения должен быть следующим:
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
Я пытаюсь найти результат, я добавляю printf
в lcore_main()
функционировать следующим образом:
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))
, Поэтому я пытаюсь отправлять пакеты самостоятельно с помощью pktgen, предоставляемого Linux (НЕ DPDK). Однако не удастся. Я покажу свой след.
#!/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 находятся на уровне 2, инструменты уровня 3, такие как ping
бесполезны. Пример приложения застревает все время, и я в отчаянии. Не могли бы вы поделиться некоторыми мыслями, чтобы решить мою проблему?
С наилучшими пожеланиями.
EDIT1:
Ответ @ Амедео работает, однако я просто могу отправить какой-то пакет (несколько пакетов, а не поток трафика) в приложение обратного вызова RX / TX. Я пытался использовать pktgen
предоставляется Linux, но интерфейс dtap0
не может получить трафик, сгенерированный pktgen
, Ниже приведен мой экспериментальный курс.
Во-первых, вся подготовка такая же, как указано выше. Тем не менее, я запускаю пример приложения с помощью команды
sudo ./build/rxtx_callbacks -l1 -n4 --vdev=net_tap0
скорее, чем
sudo ./build/rxtx_callbacks -l1 -n4
Я вижу новый ник в ifconfig
после запуска примера приложения.
О, я должен отметить, что я отказался eth1
еще такой, что eth1
, eth2
, а также eth3
для использования DPDK. Результат выполнения показывает следующее:
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
это точно dtap0
ник в ifconfig
, Теперь я пытаюсь ввести трафик в dtap0
интерфейс. Тем не менее, я пытаюсь использовать pktgen
предоставляется Linux, но все равно не удается.
Я сначала даю взаимодействие dtap0
IP-адрес, используя:
sudo dhclient dtap0
и получить:
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)
Затем я пишу сценарий оболочки для генерации нагрузки трафика из eth0
в dtap0
(Хотелось бы). Это сценарий.
#!/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
производит исходящие пакеты (используя nload
или же ifconfig
). Тем не менее, интерфейс dtap0
не имеет входящего трафика. Я тоже стараюсь iperf
отправлять трафик, но dtap0
не может обрабатывать ни TCP-соединение, ни UDP ACK. iperf
а также ping
оба недоступны.
Спасибо, что поделились любой идеей по моей проблеме.
EDIT2:
Благодаря доле @ Амедео. Я понял, как использовать pktgen
предоставляется Linux для отправки пакетов RX/TX Callback
образец приложения.
Все для бега RX/TX Callback
Пример приложения такой же, как EDIT1. Я меняю скрипт на pktgen
следующее:
#!/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! А также
dtap0 --- dpdk port --- rxtx_callbacks
Все идет как надо.
2 ответа
Ожидается, что вы не видите трафика. Пример обратных вызовов RX/TX является обобщением примера L2FWD. Этот код получает трафик с одного порта и перенаправляет его на другой. Если входящего трафика нет, приложение будет опрашивать вечно, пытаясь что-то получить и ничего не будет пересылать.
Поскольку 2 порта используют драйверы DPDK, они не видны ядром. По этой причине обычные инструменты (ifconfig, tcpdump, pktgen и т. Д.) Не видят эти интерфейсы.
Вы можете привязать к dpdk только один физический интерфейс и использовать интерфейс крана в качестве второго интерфейса. Интерфейс tap связан с ядром, поэтому вы можете легко вводить в него трафик (например, используя tcpreplay).
Чтобы использовать интерфейс крана, вам просто нужно добавить параметр --vdev=net_tap0
:
sudo ./build/rxtx_callbacks -l1 -n4 --vdev=net_tap0
это создаст интерфейс dtap0
видно из ifconfig. Весь трафик, который входит в этот интерфейс, будет получен приложением rxtx_callbacks и перенаправлен на другой физический порт.
Источник: https://doc.dpdk.org/guides/nics/tap.html
Сквозной эксперимент
Вы также можете удалить все физические порты dpdk и использовать только 2 порта TAP. Таким образом, вы можете иметь:
dtap0 --- dpdk port --- rxtx_callbacks --- dpdk port --- dtap1
и 2 TAP могут пропинговать друг друга через приложение rxtx_callbacks.
Шаги, чтобы воспроизвести это:
1) Отсоедините все физические интерфейсы от DPDK
2) Запустите rxtx_callbacks с 2 TAP:
sudo ./rxtx_callbacks -l1 -n4 --vdev=net_tap0 --vdev=net_tap1
3) Теперь у вас есть 2 интерфейса TAP: dtap0 и dtap1. Переместите dtap1 в другое пространство имен сети и назначьте IP-адреса dtap0 и dtap1:
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 (и наоборот):
sudo ping 11.0.0.2
sudo ip netns exec ns1 ping 11.0.0.1
5) Очистка: переместите dtap1 в пространство имен по умолчанию и удалите пространство имен.
sudo ip netns exec ns1 ip link set dtap1 netns 1
sudo ip netns del ns1
Самое простое решение, которое отлично подходит для начала, - это использовать один хост в качестве цели DPDK, а другой - в качестве генератора пакетов. Быстрый генератор пакетов потребляет много ресурсов ЦП, поэтому запуск его на цели DPDK определенно снизит производительность DPDK.
Однако иногда другой хост недоступен, поэтому второе простейшее решение - подключить физические Ethernet-устройства друг к другу на том же хосте. В вашем случае порты DPDK eth2
а также eth3
должен быть физически подключен с помощью перекрестного соединительного кабеля с pktgen
порты eth0
а также eth1
,
В этом случае вы сможете использовать ping
и т.д., если вы настроите только один pktgen
порт с IP-адресом, т.е.
# 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
должен производить ICMP-пакеты с DST IP 172.16.0.2
, дст MAC 00:0c:29:f7:4d:25
и отправить их eth0
, который должен быть подключен вплотную к порту DPDK.
Чтобы увидеть, что пакеты возвращаются eth1
, мы должны перевести интерфейс в беспорядочный режим. tcpdump
делает это по умолчанию. Итак, если все работает и работает:
# tcpdump -eni eth1
должен показывать пакеты, возвращающиеся из DPDK. После того как вы проверили это, вы можете перейти к pktgen
,
Решение с vdev
описанный @Amedeo также должен работать. Вы не сможете протолкнуть много трафика через vdev
хотя.