Skip to content

Commit

Permalink
dpdk/rss: add rte_flow rss support for ice
Browse files Browse the repository at this point in the history
ice driver requires 2 rte_flow rules for matching and
redistributing incoming traffic with RSS.

The rules set up by iceDeviceSetRSSFlowIPv4() and
iceDeviceSetRSSFlowIPv6() are different only in the pattern
("pattern eth / ipv4 / end" or "pattern eth / ipv6 / end"
in dpdk-testpmd syntax) and in the hash type (ipv4 src dst / ipv6 src
dst). ice will match all ipv4 or ipv6 traffic independently of
following l4 protocol. The rules can not have queues configured,
implicitly they will use all queues available.
The hash function is set to RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ
as the hash key also can not be set explicitly.

The syntax in dpdk-testpmd for rule to match all ipv4 traffic
with attributes:
	port index == 0
is as follows:
"flow create 0 ingress pattern eth / ipv4 / end actions rss types ipv4
end queues end func symmetric_toeplitz / end"
(queues need to be set to NULL)

Ticket: 7337
  • Loading branch information
Adam Kiripolsky authored and Adam Kiripolsky committed Dec 21, 2024
1 parent f2e9cd6 commit ccd2aed
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
5 changes: 4 additions & 1 deletion src/source-dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ static void DevicePostStartPMDSpecificActions(DPDKThreadVars *ptv, const char *d
i40eDeviceSetRSS(ptv->port_id, ptv->threads, ptv->livedev->dev);
else if (strcmp(driver_name, "net_ixgbe") == 0)
ixgbeDeviceSetRSS(ptv->port_id, ptv->threads, ptv->livedev->dev);
else if (strcmp(driver_name, "net_ice") == 0)
iceDeviceSetRSS(ptv->port_id, ptv->threads, ptv->livedev->dev);
}

static void DevicePreClosePMDSpecificActions(DPDKThreadVars *ptv, const char *driver_name)
Expand All @@ -206,7 +208,8 @@ static void DevicePreClosePMDSpecificActions(DPDKThreadVars *ptv, const char *dr
driver_name = BondingDeviceDriverGet(ptv->port_id);
}

if (strcmp(driver_name, "net_i40e") == 0 || strcmp(driver_name, "net_ixgbe") == 0) {
if (strcmp(driver_name, "net_i40e") == 0 || strcmp(driver_name, "net_ixgbe") == 0 ||
strcmp(driver_name, "net_ice") == 0) {
#if RTE_VERSION > RTE_VERSION_NUM(20, 0, 0, 0)
// Flush the RSS rules that have been inserted in the post start section
struct rte_flow_error flush_error = { 0 };
Expand Down
74 changes: 73 additions & 1 deletion src/util-dpdk-ice.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2021 Open Information Security Foundation
/* Copyright (C) 2021-2024 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
Expand Down Expand Up @@ -32,6 +32,9 @@

#include "util-dpdk-ice.h"
#include "util-dpdk.h"
#include "util-dpdk-rss.h"
#include "util-debug.h"
#include "util-dpdk-bonding.h"

#ifdef HAVE_DPDK

Expand All @@ -46,6 +49,75 @@ static void iceDeviceSetRSSHashFunction(uint64_t *rss_hf)
#endif
}

/**
* \brief Creates RTE_FLOW pattern to match ipv4 traffic
*
* \param port_id The port identifier of the Ethernet device
* \param port_name The port name of the Ethernet device
* \param rss_conf RSS configuration
* \return int 0 on success, a negative errno value otherwise
*/
static int iceDeviceSetRSSFlowIPv4(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
struct rte_flow_item pattern[] = { { 0 }, { 0 }, { 0 } };

pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
pattern[2].type = RTE_FLOW_ITEM_TYPE_END;

return DeviceCreateRSSFlow(port_id, port_name, rss_conf, RTE_ETH_RSS_IPV4, pattern);
}

/**
* \brief Creates RTE_FLOW pattern to match ipv6 traffic
*
* \param port_id The port identifier of the Ethernet device
* \param port_name The port name of the Ethernet device
* \param rss_conf RSS configuration
* \return int 0 on success, a negative errno value otherwise
*/

static int iceDeviceSetRSSFlowIPv6(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
struct rte_flow_item pattern[] = { { 0 }, { 0 }, { 0 } };

pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV6;
pattern[2].type = RTE_FLOW_ITEM_TYPE_END;

return DeviceCreateRSSFlow(port_id, port_name, rss_conf, RTE_ETH_RSS_IPV6, pattern);
}

int iceDeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
{
uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
struct rte_flow_error flush_error = { 0 };
struct rte_eth_rss_conf rss_conf = { 0 };

if (nb_rx_queues < 1) {
FatalError("The number of queues for RSS configuration must be "
"configured with a positive number");
}

struct rte_flow_action_rss rss_action_conf = DeviceInitRSSAction(
rss_conf, 0, queues, RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ, false);

int retval = iceDeviceSetRSSFlowIPv4(port_id, port_name, rss_action_conf);
retval |= iceDeviceSetRSSFlowIPv6(port_id, port_name, rss_action_conf);
if (retval != 0) {
retval = rte_flow_flush(port_id, &flush_error);
if (retval != 0) {
SCLogError("Unable to flush rte_flow rules of %s: %s Flush error msg: %s", port_name,
rte_strerror(-retval), flush_error.message);
}
return retval;
}

return 0;
}

void iceDeviceSetRSSConf(struct rte_eth_rss_conf *rss_conf)
{
iceDeviceSetRSSHashFunction(&rss_conf->rss_hf);
Expand Down
3 changes: 2 additions & 1 deletion src/util-dpdk-ice.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2021 Open Information Security Foundation
/* Copyright (C) 2021-2024 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
Expand Down Expand Up @@ -30,6 +30,7 @@

#include "util-dpdk.h"

int iceDeviceSetRSS(int port_id, int nb_rx_queues, char *port_name);
void iceDeviceSetRSSConf(struct rte_eth_rss_conf *rss_conf);

#endif /* HAVE_DPDK */
Expand Down

0 comments on commit ccd2aed

Please sign in to comment.