DPDK on Mellanox Bluefield-2 SmartNIC

Suricata v7.0.2
Running on Bluefield-2 SmartNIC from Nvidia. It runs a Ubuntu 22.04.
Suricata was compiled from source.

Hi All, I am running Suricata with the above setting.
Suricata is working on the Bluefield-2 SmartNIC on other modes, e.g., AF_PACKET (+ebpf loadbalancing).
I wanted to try out with DPDK. I compiled DPDK on my own and during the compilation of Suricata, all related libs were found.

My setup looks like this:
measurement_setup_suricata_IPS_af_packet.drawio

Looks a bit complicated, but it is not. Just that everything is in one server, which allows me to do accurate latency measurements.
Eventually, my aim is to run Suricata on the SmartNIC, which can inspect the traffic before it would reach the host itself. Therefore, there is a realky physical interface (termed as bf1_p0 in the figure), and a virtual one facing the host (termed as bf1_pf0hpf). While I have issues in setting up Suricata to use DPDK for both of my interfaces (I don’t know how to configure bf1_pf0hpf for now), I was wondering whether I can just make an IPS mode on the same interface, i.e., copy from bf1_p0 back to pf1_p0 itself.

I replay a specific PCAP file and matching rules are installed in Suricata. This use case is working with other modes, so logically they are confirmed.
However, when I run with DPDK, I don’t see any alert logs (which should be there) and also no packets are sent back to the same interface.

I also tried running Suricata with none or tap mode, with or without any copy-interface set in order to just see the alerts (without actually sending the packets back). However, I have no success yet I neither have any error. Does anybody has some experience similar to my setup?

My suricata.yaml’s relevant part:

dpdk:
  eal-params:
    proc-type: primary
#    allow: ["0000:03:00.0"] #this is p0 interface
  # DPDK capture support
  # RX queues (and TX queues in IPS mode) are assigned to cores in 1:1 ratio
  interfaces:
    - interface: 0000:03:00.0 # PCIe address of the NIC port - this is p0 interface
      threads: 4
      promisc: true
      multicast: true 
      checksum-checks: true
      checksum-checks-offload: true 
      mtu: 1518
      mempool-size: 262143 # The number of elements in the mbuf pool
      mempool-cache-size: 511
      rx-descriptors: 4096
      tx-descriptors: 4096
      copy-mode: ips
      copy-iface: 0000:03:00.0 
...
threading:
  set-cpu-affinity: yes
  cpu-affinity:
    - management-cpu-set:
        cpu: [ 0 ]  
    - receive-cpu-set:
        cpu: [ 0 ]  
    - worker-cpu-set:
        cpu: [ "1-4" ]
        mode: "exclusive"

        prio:
          low: [  ]
          medium: [ 0 ]
          high: [ "1-4" ]
          default: "high"

The STDOUT of Suricata after running
suricata -c /etc/suricata/suricata.yaml --dpdk -vv

[1057774] Notice: suricata: This is Suricata version 7.0.2 RELEASE running in SYSTEM mode
[1057774] Info: cpu: CPUs/cores online: 8
[1057774] Info: dpdk: Setting IPS mode
[1057774] Info: exception-policy: master exception-policy set to: auto
[1057774] Info: suricata: Preparing unexpected signal handling
[1057774] Info: conf: Running in live mode, activating unix socket
[1057774] Info: logopenfile: fast output device (regular) initialized: fast.log
[1057774] Info: logopenfile: eve-log output device (regular) initialized: eve.json
[1057774] Info: logopenfile: stats output device (regular) initialized: stats.log
[1057774] Info: detect: 1 rule files processed. 48 rules successfully loaded, 0 rules failed
[1057774] Info: threshold-config: Threshold config parsed: 0 rule(s) found
[1057774] Info: detect: 48 signatures processed. 0 are IP-only rules, 0 are inspecting packet payload, 0 inspect application layer, 0 are decoder event only
[1057774] Perf: detect: TCP toserver: 41 port groups, 41 unique SGH's, 0 copies
[1057774] Perf: detect: TCP toclient: 21 port groups, 21 unique SGH's, 0 copies
[1057774] Perf: detect: UDP toserver: 41 port groups, 41 unique SGH's, 0 copies
[1057774] Perf: detect: UDP toclient: 21 port groups, 21 unique SGH's, 0 copies
[1057774] Perf: detect: OTHER toserver: 254 proto groups, 1 unique SGH's, 253 copies
[1057774] Perf: detect: OTHER toclient: 254 proto groups, 0 unique SGH's, 254 copies
[1057774] Perf: detect: Unique rule groups: 125
[1057774] Perf: detect: Builtin MPM "toserver TCP packet": 0
[1057774] Perf: detect: Builtin MPM "toclient TCP packet": 0
[1057774] Perf: detect: Builtin MPM "toserver TCP stream": 0
[1057774] Perf: detect: Builtin MPM "toclient TCP stream": 0
[1057774] Perf: detect: Builtin MPM "toserver UDP packet": 0
[1057774] Perf: detect: Builtin MPM "toclient UDP packet": 0
[1057774] Perf: detect: Builtin MPM "other IP packet": 0
[1057774] Perf: profiling-rulegroups: Registered 125 rulegroup profiling counters.
[1057774] Perf: profiling-keywords: Registered 276 keyword profiling counters.
[1057774] Perf: profiling-rules: Registered 48 rule profiling counters.
EAL: No available hugepages reported in hugepages-32768kB
EAL: No available hugepages reported in hugepages-64kB
EAL: No available hugepages reported in hugepages-1048576kB
EAL:   Invalid NUMA socket, default to 0
EAL:   Invalid NUMA socket, default to 0
[1057774] Info: dpdk: 0000:03:00.0: DPDK IPS mode activated: 0000:03:00.0->0000:03:00.0
[1057774] Info: runmodes: 0000:03:00.0: creating 4 threads
[1057785] Perf: threads: Setting prio -2 for thread "W#01-03:00.0" to cpu/core 1, thread id 1057785
[1057786] Perf: threads: Setting prio -2 for thread "W#02-03:00.0" to cpu/core 2, thread id 1057786
[1057787] Perf: threads: Setting prio -2 for thread "W#03-03:00.0" to cpu/core 3, thread id 1057787
[1057788] Perf: threads: Setting prio -2 for thread "W#04-03:00.0" to cpu/core 4, thread id 1057788
[1057789] Perf: threads: Setting prio 0 for thread "FM#01", thread id 1057789
[1057790] Perf: threads: Setting prio 0 for thread "FR#01", thread id 1057790
[1057791] Perf: threads: Setting prio 0 for thread "CW", thread id 1057791
[1057792] Perf: threads: Setting prio 0 for thread "CS", thread id 1057792
[1057774] Info: unix-manager: unix socket '/var/run/suricata/suricata-command.socket'
[1057793] Perf: threads: Setting prio 0 for thread "US", thread id 1057793
[1057774] Notice: threads: Threads created -> W: 4 FM: 1 FR: 1   Engine started.
[1057774] Info: dpdk: 6193 of 6622 of hugepages are free - number of hugepages can be lowered to e.g. 494
^C[1057774] Notice: suricata: Signal Received.  Stopping engine.
[1057774] Info: suricata: time elapsed 1214.633s
[1057790] Perf: flow-manager: 0 flows processed
[1057785] Perf: dpdk: Port 0 (0000:03:00.0) - tx_packets: 1
[1057785] Perf: dpdk: Port 0 (0000:03:00.0) - tx_bytes: 74
[1057785] Perf: dpdk: 0000:03:00.0: total RX stats: packets 0 bytes: 0 missed: 0 errors: 0 nombufs: 0
[1057785] Perf: dpdk: 0000:03:00.0: total TX stats: packets 0 bytes: 0 errors: 0
[1057785] Perf: dpdk: (W#01-03:00.0) received packets 0
[1057786] Perf: dpdk: (W#02-03:00.0) received packets 0
[1057787] Perf: dpdk: (W#03-03:00.0) received packets 0
[1057788] Perf: dpdk: (W#04-03:00.0) received packets 0
[1057774] Info: counters: Alerts: 0
[1057774] Perf: ippair: ippair memory usage: 422144 bytes, maximum: 16777216
[1057774] Perf: profiling: Done dumping profiling data.
[1057774] Perf: host: host memory usage: 406144 bytes, maximum: 33554432
[1057774] Perf: profiling-rules: Dumping profiling data for 48 rules.
[1057774] Perf: profiling-rules: Done dumping profiling data.
[1057774] Perf: profiling-keywords: Done dumping keyword profiling data.
[1057774] Perf: profiling-rulegroups: Done dumping rulegroup profiling data.
[1057774] Perf: dpdk: 0000:03:00.0: closing device
[1057774] Notice: device: 0000:03:00.0: packets: 0, drops: 0 (0.00%), invalid chksum: 0

As you can see, there are no errors but also no packets received/processed at all.

Thanks

Hi there,

I have not been able to get my hands on the Bluefield card. However, I would first try with some basic DPDK application e.g. dpdk-testpmd, and see if that receives any packets. Have you tried that?

sudo dpdk-testpmd -a 0000:03:00.0 -l 1,2 -- -i # i gets you interactive mode, you can then execute start/stop commands (or run it without interactive mode)

I see you have a switch in between the packet generator and Suricata. Are you sure that can not interfere with the packets? If the testpmd application will work then the problem is somewhere in Suricata.

Also, can you test other modes also receive packets in IDS mode (copy-mode: none)? I would now start experimenting with that before we move to the more complicated setup.

Maybe this will help: ESPCommunity

Thanks for your reply and sorry for my late one. I was not able to reach the servers due to some networking errors in the last 5 days.

I am testing now with testpmd as per your suggestion, and it turns out it does not work either. I mean I can start it but no packet processing is being done. It also turned out that I have testpmd installed in two locations (probably after trying to compile different versions), one under /usr/bin/ and one under /usr/local/bin. On top of these, there is the original Nvidia version of DPDK installed to /opt/mellanox/dpdk; all are from different versions (I suppose).
Is there any way to print out the compiled/used DPDK version, when running an app, for instance, testpmd itself?

I know the pkg-config --modversion libdpdk command, which gives me the following info:

# pkg-config --modversion libdpdk
    20.05.0

The original mellanox-dpdk coming with the distro has higher version number:

# dpkg -l |grep dpdk
ii  dpdk-dev                                      21.11.4-0ubuntu0.22.04.1                               arm64        Data Plane Development Kit (dev tools)
ii  libdpdk-dev:arm64                             21.11.4-0ubuntu0.22.04.1                               arm64        Data Plane Development Kit (basic development files)
ii  mlnx-dpdk                                     22.11.0-2307.2.0.23070500.2307.2.0                     arm64        Data Plane Development Kit (runtime)
ii  mlnx-dpdk-dev:arm64                           22.11.0-2307.2.0.23070500.2307.2.0                     arm64        Data Plane Development Kit (basic development files)

Maybe I first try to remove all versions and start from scratch.
I will keep you updated

I have removed all DPDK libs, and compiled the latest DPDK that can be compiled without errors, which is 20.05. Now, I see something very strange.
I start dpkd-testpmd and it seems everything is fine:

root /home/ubuntu/dpdk# /usr/local/bin/dpdk-testpmd -w 0000:03:00.0 -w 0000:03:00.1 -l 1-3 -- -i
EAL: Detected 8 lcore(s)
EAL: Detected 1 NUMA nodes
EAL: Multi-process socket /var/run/dpdk/rte/mp_socket
EAL: Selected IOVA mode 'PA'
EAL: No free hugepages reported in hugepages-32768kB
EAL: No available hugepages reported in hugepages-32768kB
EAL: No free hugepages reported in hugepages-64kB
EAL: No available hugepages reported in hugepages-64kB
EAL: Probing VFIO support...
EAL:   Invalid NUMA socket, default to 0
EAL: Probe PCI driver: net_mlx5 (15b3:a2d6) device: 0000:03:00.0 (socket 0)
EAL:   Invalid NUMA socket, default to 0
EAL: Probe PCI driver: net_mlx5 (15b3:a2d6) device: 0000:03:00.1 (socket 0)
Interactive-mode selected
testpmd: create a new mbuf pool <mbuf_pool_socket_0>: n=163456, size=2176, socket=0
testpmd: preferred mempool ops selected: ring_mp_mc
Configuring Port 0 (socket 0)
Port 0: 22:3D:EA:12:12:F0
Configuring Port 1 (socket 0)
Port 1: 42:DA:98:98:62:6D
Checking link statuses...
Done
testpmd> start 
io packet forwarding - ports=2 - cores=1 - streams=2 - NUMA support enabled, MP allocation mode: native
Logical Core 2 (socket 0) forwards packets on 2 streams:
  RX P=0/Q=0 (socket 0) -> TX P=1/Q=0 (socket 0) peer=02:00:00:00:00:01
  RX P=1/Q=0 (socket 0) -> TX P=0/Q=0 (socket 0) peer=02:00:00:00:00:00

  io packet forwarding packets/burst=32
  nb forwarding cores=1 - nb forwarding ports=2
  port 0: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x0 Tx offloads=0x0
    RX queue: 0
      RX desc=256 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=256 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
  port 1: RX queue number: 1 Tx queue number: 1
    Rx offloads=0x0 Tx offloads=0x0
    RX queue: 0
      RX desc=256 - RX free threshold=0
      RX threshold registers: pthresh=0 hthresh=0  wthresh=0
      RX Offloads=0x0
    TX queue: 0
      TX desc=256 - TX free threshold=0
      TX threshold registers: pthresh=0 hthresh=0  wthresh=0
      TX offloads=0x0 - TX RS bit threshold=0
testpmd>

However, after the packets are sent towards the SmartNIC, no forwarding is done by dpdk-testpmd.
During the time when testpmd is running, if I try to run tcpdump on the ports, I also don’t see any packets; but this should be fine as the DPDK application, in this case, testpmd should pick up those packets. And it is somewhat justified after I stop testpmd and quit it.
It says 0 packets were processed, but right after it stops, I start to see the packets via tcpdump meaning that the problem is with the DPDK app and the packets are coming in.

testpmd> quit
Telling cores to stop...
Waiting for lcores to finish...

  ---------------------- Forward statistics for port 0  ----------------------
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ----------------------------------------------------------------------------

  ---------------------- Forward statistics for port 1  ----------------------
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ----------------------------------------------------------------------------

  +++++++++++++++ Accumulated forward statistics for all ports+++++++++++++++
  RX-packets: 0              RX-dropped: 0             RX-total: 0
  TX-packets: 0              TX-dropped: 0             TX-total: 0
  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Done.

Stopping port 0...
Stopping ports...
Done

Stopping port 1...
Stopping ports...
Done

Shutting down port 0...
Closing ports...
Done

Shutting down port 1...
Closing ports...
Done

Bye...

At the tcpdump terminal, packets turn up after quitting dpdk-testpmd:

root /home/ubuntu# tcpdump -i p0
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on p0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
08:22:48.249873 IP 192.168.0.1.1234 > 192.168.1.1.5678: Flags [.], seq 74616:74622, ack 74640, win 8192, length 6
08:22:48.249873 IP 192.168.0.1.1234 > 192.168.1.1.5678: Flags [.], seq 0:6, ack 1, win 8192, length 6
08:22:48.249873 IP 192.168.0.1.1234 > 192.168.1.1.5678: Flags [.], seq 0:6, ack 1, win 8192, length 6
08:22:48.249873 IP 192.168.0.1.1234 > 192.168.1.1.5678: Flags [.], seq 0:6, ack 1, win 8192, length 6
08:22:48.249874 IP 192.168.0.1.1234 > 192.168.1.1.5678: Flags [.], seq 0:6, ack 1, win 8192, length 6

Hi cs.lev,

You’ve mentioned that you compiled your own DPDK and there is NVIDIA included DPDK at the same time.

Here are my 2 cents:

  • I would replace your own DPDK installation with NVIDIA’s primary installation and try again.
  • When I compile DPDK from scratch it happens that MLX5 drivers are missing so I need to install those as well. However, that seems to not be the case here because otherwise, testpmd wouldn’t even find the devices. But possibly it might not contain the correct drivers?
  • Your DPDK version also seems a little odd, I would move to LTS version, at least 20.11 but rather to 22.11 or even 23.11. I always go with the .11 versions.

If this doesn’t solve your issue then I would contact NVIDIA support or reach out to DPDK users mailing list: mails.dpdk.org Mailing Lists

Thanks for your reply.
The built-in/NVIDIA-provided DPDK is kinda useless. I always have problems with it, even on the host machine where I compiled Pktgen for traffic generation. Anyway, I managed to overcome the issue, or at least it seems :slight_smile:

The proper way of installing the latest DPDK on the Bluefield is a bit different from the standard procedures I used to use on the host - it took some time for me to find the correct way as no explicit tutorial was given. There is a trick with setting the platform from native to the actual one. I found the correct one from config/arm/meson.build where there is something called soc_bluefield

Anyway, the steps to be taken are as follows (for DPDK 22.11.3 (LTS)):

# wget https://fast.dpdk.org/rel/dpdk-22.11.3.tar.xz
# tar -xJf dpdk-22.11.3.tar.xz
# ln -s dpdk-stable-22.11.3/ dpdk
# cd dpdk/
# meson setup -Dplatform=bluefield build
# ninja -C build
# ninja -C build install

The symlink is just my typical trick I use to access the directory faster. It also comes handy if you set ENV var RTE_SDK in your .bashrc as anytime you install a different version of DPDK, you only need to set the symlink and don’t have to touch ENV vars.

The platform is also just bluefield not soc_bluefield. The latter throws an error anyway.

After all this, and if all necessary libs are installed, of course, DPDK 22.11.3 compiles and dpdk-testpmd not only runs without error, but also forwards the packets.

Thank @lukashino for indirectly forcing me into the realm of correct DPDK installation :slight_smile:
What I learned on the way is that compilation and even running without errors still do not mean everythings works :smiley:

1 Like

Perfect, thanks for coming back with the solution!

I was under the impression that DPDK has moved away from RTE_* environment variables since 19.11 and everything is configured through meson.

Btw: where are you compiling DPDK? Is it directly on the Bluefield chip? Then I would assume that “native” would work but I guess not… :sweat_smile:

FYI: DPDK has a stable git repository where you could just clone the repository and checkout to the version you need - dpdk-stable - Data Plane Development Kit - stable branches
It is different from the Github one because it also contains patches after the first .11 subversion was released (e.g. 22.11.1/2/3). Sticking to the tar download is I believe a good practice this is just in case you want to change a lot of DPDK versions.

You are probably right about the RTE_* ENV vars. I am just still sticking to it as it does not do any harm :slight_smile:
But, sure, as you see I already compile it via meson.

I compile DPDK on the Bluefield itself.

I suppose the -Dplatform=native is the default one if not set to something else. And if I don’t set it to bluefield, then the compilation fails as there is some rxp-compiler.h dependency it is looking for, but there is no such package/library available for the bluefield that would containt that. On the host machine, it compiles, though - I suppose it’s a built-in “recognition” of the Mellanox mlx5 driver and its features available on the host, but not available on the Bluefield. So I have to set it explicitly.

Thanks for the heads-up regarding the git repo; I was aware of it, but I did not want to play around with more version that are available on the main DPDK website :smiley: