Aravind Prabhakar

Systems Engineer | Networking | Security | PreSales | Cloud | Devops | AIOps

View on GitHub Linkedin Blogs Tags
24 November 2022

Using dpdk pktgen as a software traffic generator

By Aravind

Setup pktgen

I was always in need for traffic generator and i ended up writing my own packet crafter. However, was becoming too tedius to add new packet formats! In order for pktgen to be setup, either we can use it on baremetal/vm with sriov vfs being passed. However not all the times, we would have the flexibility of the NICs being connected. How about scenarios where you have multiple VMs and want to test something functionally and need a quick traffic generator ? In such cases, we can run packet gen on virtio interfaces

Bring up the dpdk packet gen VM

use the script here to bring up the VM. The bash script just brings up 2 VMs with ubuntu

Increase root partition size (optional)

sometimes the expanded disk doesnt show up on the vm when you run dh -h

you can do the below quick steps to increase the size

fdisk /dev/sda

press "p" for partition numbers
press "d" followed by "1" which is root partition
press "n" followed by hitting "return" so that default vals are accepted 
press "y" to accept change in signature
press "w" to sync the changes

resize2fs /dev/sda1

now validate the size and notice that it increased to 50G

root@pktgen2:~/dpdk_pktgen# df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           394M  2.8M  391M   1% /run
/dev/sda1        51G  3.1G   48G   6% /
< ----- snipped ------- >

Setup huge pages

Huge pages is important without which pktgen probably would not work. I have seen debugging references where we can pass a flag to skip but it is recommended to use huge pages

Follow here to update huge pages

Install dependencies

If igb_uio module not found install the below

sudo apt-get install -y dpdk-igb-uio-dkms

If uio_pci_generic module not found , install the below

sudo apt-get install -y linux-modules-extra-5.4.0-126-generic

Load the modules

modprobe modprobe igb_uio
modprobe uio_pci_generic

Verify

root@pktgen2:~/dpdk_pktgen# lsmod | grep uio
uio_pci_generic        16384  0
igb_uio                20480  0
uio                    20480  2 igb_uio,uio_pci_generic

At this stage all the dependencies are met and let us proceed with installation

Clone the repo

git clone https://github.com/ARD92/dpdk_pktgen.git

Atoonk did a great job of packaging it! it makes it seemless to install pktgen! Kudos to him! I was struggling to compile with all dependencies missing when I initially tried to setup pktgen. I forked the same repo.

Modify the install-dpdk-pktgen.sh file

Edit the file to add the pci address of the interfaces. In the above vm that you create, let us consider the interface ens4

Gather the PCI bus info

root@pktgen2:~/dpdk_pktgen# lspci | grep Ether
00:03.0 Ethernet controller: Red Hat, Inc. Virtio network device
00:04.0 Ethernet controller: Red Hat, Inc. Virtio network device

let us choose 00:04.0. edit the file with this value for the export PCI_IF param.

export PCI_IF="0000:00:04.0"

save and quit the file.

Install pktgen

chmod +x install-dpdk-pktgen.sh

./install-dpdk-pktgen.sh

This will take a bit of time to compile and install. At the end of the installation, just scroll up to ensure no error aborted the setup.

verify if interface bound to dpdk

Notice on the very first line 00:04:0 is bound to dpdk-compatible driver. we will use this to send packets out of. At this time since its bound, the interfaces would not show up on ip link show

root@pktgen2:~/dpdk_pktgen# /opt/dpdk-20.02/usertools/dpdk-devbind.py -s

Network devices using DPDK-compatible driver
============================================
0000:00:04.0 'Virtio network device 1000' drv=igb_uio unused=vfio-pci,uio_pci_generic

Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device 1000' if=ens3 drv=virtio-pci unused=igb_uio,vfio-pci,uio_pci_generic *Active*

No 'Baseband' devices detected
==============================

No 'Crypto' devices detected
============================

No 'Eventdev' devices detected
==============================

No 'Mempool' devices detected
=============================

No 'Compress' devices detected
==============================

No 'Misc (rawdev)' devices detected
===================================

Usage

Now that pktgen is installed, let us look to see how to run the traffic. You can use the example pkt file to start.

Pkt file sample for single flow

Save the below contents into a file pktgen.pkt

stop 0
set 0 rate 0.1
set 0 ttl 10
set 0 proto udp
set 0 dport 81
set 0 dst mac 44:ec:ce:c1:a8:20
#set 0 src mac 00:52:44:11:22:33
#set 0 src mac 00:00:00:00:00:01
set 0 dst ip 10.99.204.8
set 0 src ip 10.99.204.3/30
set 0 size 64

Run pktgen

/opt/pktgen-20.02.0/app/x86_64-native-linuxapp-gcc/pktgen --file-prefix=pktgen -- -P -m 1.0 -f pktgen.pkt

Note that this guide talks about only virtio based interfaces and not for performance based. In case you need to generate more, provide enough resources to vm and pin the CPUs in the same numa for better performance. The .pkt files can be reused.

once you run the above command you would see the below. use start 0 to start traffic

Connect to a topology ?

Based on the above steps if you have pktgen running , you can pass this traffic to any VNF/CNF running on the server. Just ensure the interface ens4 far end on host is placed on same linux/ovs as the other VNF/CNF

pktgen-data1		8000.52540008e7d7	no		pktgen-dta1-nic
							pktgen1-ens4
pktgen-data2		8000.525400d00b25	no		pktgen-dta2-nic
							pktgen2-ens4

Additional references

Pkt file sample for range of flows

enable 0 range
range 0 dst mac 00:00:5e:00:01:00 00:00:5e:00:01:00 00:00:5e:00:01:00 00:00:00:00:00:00
range 0 src mac aa:bb:cc:dd:ee:50 aa:bb:cc:dd:ee:50 aa:bb:cc:dd:ee:50 00:00:00:00:00:00
range 0 dst ip 1.1.61.2 1.1.61.2 1.1.61.2 0.0.0.0
range 0 src ip 1.1.52.2 1.1.52.2 1.1.52.2 0.0.0.0
range 0 dst port 1024 1024 49151 1
range 0 src port 49152 49152 65535 1
range 0 size 64 64 64 0
set 0 size 64
set 0 count 0
set 0 rate 1

More samples can be found here

Running Lua scripts

Install below dependencies to run lua scripts. You can pass lua scripts just like how .pkt files are passed using the -f flag.

sudo apt-get install liblua5.3-dev
sudo apt-get install liblua5.3-0
sudo apt-get install lua5.3
cd ~/Pktgen-DPDK
meson -Denable_lua=true build
ninja -C build
ldconfig
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: /usr/lib/x86_64-linux-gnu/

Using packetgen

Finding sibling threadis

cat /sys/devices/system/cpu/cpu2/topology/thread_siblings_list
2,34

cat /sys/devices/system/cpu/cpu3/topology/thread_siblings_list
3,35

Here cpu 2 has sibling thread 34 and cpu3 has sibling thread 35.

STTY

Once we run pktgen it might overwrite the screen. use stty sane to fix that

Pktgen usage

using it with Junos

When you want to pass traffic to vNFs such as vMX, vSRX. Make sure the mac address of the interfaces match with the destination mac on the .pkt file

For example here the dmac address belongs to interface ge-0/0/0 of vMX

Find mac address

show interfaces ge-0/0/0 extensive | match Curr

.pkt file

[ linux  ] tags: linux