Hi SidAli,


if that is the only rule you are creating then I don't think it is enough. Please have a look at this snippet I made few years back.

https://gist.github.com/lukashino/8fe387caabe2750d396bc97f2d66066a


There you first initialize the number of queues and then in the follow-up rules the patterns you want to apply RSS to.


Cheers,

Lukas

On 3/25/25 17:42, Sid ali cherrati wrote:
Dear DPDK Team,

I hope this message finds you well. I am reaching out to seek your expertise regarding an issue I am encountering while configuring DPDK flow rules with RSS on an Intel X710 NIC (using the i40e driver). Despite multiple attempts, I have been unable to resolve the error and would greatly appreciate your guidance.

Objective :
Redirect UDP traffic (specific destination IP/port) to multiple RX queues using rte_flow with RSS.

Error :
Validation failed: RSS Queues not supported when pattern specified .

Hardware/Software:

  • NIC: Intel X710

  • Driver: i40e
  • DPDK Version: 23.11

Code Snippet:
int flow_filtering(uint16_t port_id, uint32_t ip_addr, uint16_t udp_port) {
struct rte_flow_error error;
struct rte_flow_attr attr = { .ingress = 1, .priority = 0 };
struct rte_flow_item pattern[4];
struct rte_flow_action action[2];
struct rte_flow *flow;
// Ethernet
memset(pattern, 0, sizeof(pattern));
pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
// IPv4
struct rte_flow_item_ipv4 ipv4_spec = { .hdr.dst_addr = RTE_BE32(ip_addr) };
struct rte_flow_item_ipv4 ipv4_mask = { .hdr.dst_addr = RTE_BE32(0xFFFFFFFF) };
pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
pattern[1].spec = &ipv4_spec;
pattern[1].mask = &ipv4_mask;
// UDP
struct rte_flow_item_udp udp_spec = { .hdr.dst_port = RTE_BE16(udp_port) };
struct rte_flow_item_udp udp_mask = { .hdr.dst_port = RTE_BE16(0xFFFF) };
pattern[2].type = RTE_FLOW_ITEM_TYPE_UDP;
pattern[2].spec = &udp_spec;
pattern[2].mask = &udp_mask;
pattern[3].type = RTE_FLOW_ITEM_TYPE_END;
// action
action[0].type = RTE_FLOW_ACTION_TYPE_RSS;
// struct rte_flow_action_queue queue_action = { .index = RX_ID };
// action[0].conf = &queue_action;
// Configuration RSS
uint16_t queues[] = {1, 2, 3};
struct rte_flow_action_rss rss_conf = {
.func = RTE_ETH_HASH_FUNCTION_DEFAULT,
.types =
RTE_ETH_RSS_IPV4 |
RTE_ETH_RSS_UDP,
.key_len = 0,
.queue_num = 3,
.queue = queues,
};
action[0].type = RTE_FLOW_ACTION_TYPE_RSS;
action[0].conf = &rss_conf;
action[1].type = RTE_FLOW_ACTION_TYPE_END;
if (rte_flow_validate(port_id, &attr, pattern, action, &error) != 0) {
printf("Validation Failure: %s\n", error.message);
return -1;
}
// Flow rule creation
flow = rte_flow_create(port_id, &attr, pattern, action, &error);
if (flow == NULL) {
printf("Error creating flow rule : %s\n", error.message);
return -1;
}
printf("Flow rule created for IP %u.%u.%u.%u and UDP port %u\n",
(ip_addr >> 24) & 0xFF, (ip_addr >> 16) & 0xFF,
(ip_addr >> 8) & 0xFF, ip_addr & 0xFF, udp_port);
return 0;
}

I would be grateful for any insights, code examples, or documentation references to resolve this issue. Please let me know if additional details are required.

Thank you in advance for your time and support.

Best regards,

SidAli