В образце приложения обратных вызовов DPDK RX/TX трафик не возникает

Я новичок в области DPDK. Я начну с примеров приложений, представленных на главной странице DPDK. Я застрял в примере --- Пример приложения обратного вызова DPDK RX/TX. Условие состоит в том, что трафик не появляется (но выводится) в течение длительного времени. Я думаю, причина в том, что я не могу отправить трафик на порт DPDK.

Сначала я покажу пошаговую настройку. Хорошая информация в начале

Информация NIC при запуске

Затем я отказываюсь eth2 а также eth3 с

sudo ifconfig eth2 down
sudo ifconfig eth3 down

Далее, используя usertools/dpdk-setup.sh Я строю источник DPDK (i686-native-linuxapp-gcc), вставьте модуль IGB UIO, настройте отображение огромных страниц для систем, отличных от NUMA, привяжите устройство к модулю IGB UIO. Это настройки моего устройства и огромный список страниц: устройство UIO Bind огромная информация

Вся подготовка сделана. Я начинаю строить пример приложения. Используя следующие команды

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хотя.

Другие вопросы по тегам