I have a DPDK application that used Boost asio to join a multicast group and receives multicast IPv4 UDP packets over a VLAN on a particular UDP port number (other UDP ports are also used for other traffic). I am trying to receive only those multicast UDP packets at that port in the DPDK application and place them into an RX queue and have all other ingress network traffic act as if the DPDK application were not running (go to kernel). As such, I am using flow isolated mode (rte_flow_isolate()). The flow filtering part of my application as based off the flow_filtering example provided by DPDK with the additions of the call to rte_flow_isolate() and a VLAN filter. The filters I'm using are below:
action[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
action[0].conf = &queue;
action[1].type = RTE_FLOW_ACTION_TYPE_END;
pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
pattern[1].type = RTE_FLOW_ITEM_TYPE_VLAN;
//vlan id here
pattern[2].type = RTE_FLOW_ITEM_TYPE_IPV4;
//no specific ip address given
pattern[3].type = RTE_FLOW_ITEM_TYPE_UDP;
//udp port here
pattern[4].type = RTE_FLOW_ITEM_TYPE_END;
Using these filters, I am unable to receive any packets and the same is true if I only remove the UDP filter. However, if I remove both the IPV4 and UDP filters (keeping the ETH and VLAN filters), I can receive all the packets I need, along with other ones I don't want (and would like to be sent to the kernel).
Here's an entry for the packet I need to receive from a Wireshark capture. Currently my theory is that because the reserved bit (evil bit) is being set in the IPv4 header, the packet is not being recognized as IPv4. This is probably a stretch:
Frame 100: 546 bytes on wire (4368 bits), 546 bytes captured (4368 bits) on interface 0
Ethernet II, Src: (src MAC), Dst: IPv4mcast_...
802.1Q Virtual LAN, PRI: 0, FRI: 0, ID: 112
Internet Protocol Version 4, Src: (src IP), Dst: (Dst mcast IP)
Version: 4
Header length: 20 bytes
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
Total length: 1108
Identification: 0x000 (0)
Flags: 0x04 (RESERVED BIT HAS BEEN SET)
Fragment offset: 0
Time to live: 64
Protocol: UDP (17)
Header checksum: 0xd8c4 [validation disabled]
Source: srcip
Destination: dstip
User Datagram Protocol, Src Port: (src port), Dst Port: (dst port)
Data (N bytes)
The hardware I'm running on has a Mellanox ConnectX-5 card and as such, DPDK is using the MLX5 driver, which does not support RTE_FLOW_ITEM_TYPE_RAW along with many other items in the RTE Flow API. I am on DPDK 19.11 and the OFED version I'm using is 4.6 for RHEL 7.6 (x86_64)
What am I doing wrong here and why does adding the RTE_FLOW_ITEM_TYPE_IPV4 filter (without ip address, spec and mask both memset to 0) cause my application to not receive any packets, even though they are IPv4 packets? Is there a way around this with the MLX5 driver for DPDK?