Skip to content

Commit

Permalink
dpdk/rss MR changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Kiripolsky authored and Adam Kiripolsky committed Dec 4, 2024
1 parent e0b84d0 commit 796aca1
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 89 deletions.
6 changes: 2 additions & 4 deletions src/util-dpdk-i40e.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (C) 2021-2024s 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 @@ -188,7 +188,6 @@ static int i40eDeviceSetRSSWithFlows(int port_id, const char *port_name, int nb_
uint8_t rss_key[I40E_RSS_HKEY_LEN];
uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
struct rte_flow_error flush_error = { 0 };
struct rte_flow_action_rss rss_action_conf = { 0 };
struct rte_eth_rss_conf rss_conf = {
.rss_key = rss_key,
.rss_key_len = I40E_RSS_HKEY_LEN,
Expand All @@ -205,8 +204,7 @@ static int i40eDeviceSetRSSWithFlows(int port_id, const char *port_name, int nb_
"configured with a positive number");
}

rss_action_conf = DeviceInitRSSAction(
rss_conf, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_DEFAULT, false);
struct rte_flow_action_rss rss_action_conf = DeviceInitRSSAction(rss_conf, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_DEFAULT, false);

retval = DeviceSetRSSFlowQueues(port_id, port_name, rss_action_conf);

Expand Down
28 changes: 5 additions & 23 deletions src/util-dpdk-ice.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,11 @@ static void iceDeviceSetRSSHashFunction(uint64_t *rss_hf)
#endif
}

static int iceDeviceSetRSSFlowIPv4(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
int ret = DeviceSetRSSFlowIPv4(port_id, port_name, rss_conf);

return ret;
}

static int iceDeviceSetRSSFlowIPv6(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
int ret = DeviceSetRSSFlowIPv6(port_id, port_name, rss_conf);

return ret;
}

int iceDeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
{
int iceDeviceSetRSS(int port_id, int nb_rx_queues, char* port_name)
{
uint8_t rss_key[ICE_RSS_HKEY_LEN];
uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
struct rte_flow_error flush_error = { 0 };
struct rte_flow_action_rss rss_action_conf = { 0 };
struct rte_eth_rss_conf rss_conf = {
.rss_key = rss_key,
.rss_key_len = ICE_RSS_HKEY_LEN,
Expand All @@ -89,11 +72,10 @@ int iceDeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
"configured with a positive number");
}

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

retval = iceDeviceSetRSSFlowIPv4(port_id, port_name, rss_action_conf);
retval |= iceDeviceSetRSSFlowIPv6(port_id, port_name, rss_action_conf);
retval = DeviceSetRSSFlowIPv4(port_id, port_name, rss_action_conf);
retval |= DeviceSetRSSFlowIPv6(port_id, port_name, rss_action_conf);
if (retval != 0) {
retval = rte_flow_flush(port_id, &flush_error);
if (retval != 0) {
Expand Down
64 changes: 31 additions & 33 deletions src/util-dpdk-ixgbe.c
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
// /* 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
// * Software Foundation.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * version 2 along with this program; if not, write to the Free Software
// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
// * 02110-1301, USA.
// */
/* 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
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/

// /**
// * \defgroup dpdk DPDK Intel IXGBE driver helpers functions
// *
// * @{
// */
/**
* \defgroup dpdk DPDK Intel IXGBE driver helpers functions
*
* @{
*/

// /**
// * \file
// *
// * \author Lukas Sismis <lukas.sismis@gmail.com>
// *
// * DPDK driver's helper functions
// *
// */
/**
* \file
*
* \author Lukas Sismis <lukas.sismis@gmail.com>
*
* DPDK driver's helper functions
*
*/

#include "util-dpdk-ixgbe.h"
#include "util-dpdk.h"
Expand All @@ -50,7 +50,6 @@ int ixgbeDeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
uint8_t rss_key[IXGBE_RSS_HKEY_LEN];
uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
struct rte_flow_error flush_error = { 0 };
struct rte_flow_action_rss rss_action_conf = { 0 };
struct rte_eth_rss_conf rss_conf = {
.rss_key = rss_key,
.rss_key_len = IXGBE_RSS_HKEY_LEN,
Expand All @@ -67,10 +66,9 @@ int ixgbeDeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
"configured with a positive number");
}

rss_action_conf = DeviceInitRSSAction(
rss_conf, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_DEFAULT, true);
struct rte_flow_action_rss rss_action_conf = DeviceInitRSSAction(rss_conf, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_DEFAULT, true);

retval = DeviceCreateRSSFlowUniform(port_id, port_name, rss_action_conf);
retval = DeviceCreateRSSFlowGeneric(port_id, port_name, rss_action_conf);
if (retval != 0) {
retval = rte_flow_flush(port_id, &flush_error);
if (retval != 0) {
Expand Down
6 changes: 2 additions & 4 deletions src/util-dpdk-mlx5.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ int mlx5DeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
uint8_t rss_key[MLX5_RSS_HKEY_LEN];
uint16_t queues[RTE_MAX_QUEUES_PER_PORT];
struct rte_flow_error flush_error = { 0 };
struct rte_flow_action_rss rss_action_conf = { 0 };
struct rte_eth_rss_conf rss_conf = {
.rss_key = rss_key,
.rss_key_len = MLX5_RSS_HKEY_LEN,
Expand All @@ -62,10 +61,9 @@ int mlx5DeviceSetRSS(int port_id, int nb_rx_queues, char *port_name)
"configured with a positive number");
}

rss_action_conf = DeviceInitRSSAction(
rss_conf, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_TOEPLITZ, true);
struct rte_flow_action_rss rss_action_conf = DeviceInitRSSAction(rss_conf, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_TOEPLITZ, true);

retval = DeviceCreateRSSFlowUniform(port_id, port_name, rss_action_conf);
retval = DeviceCreateRSSFlowGeneric(port_id, port_name, rss_action_conf);
if (retval != 0) {
retval = rte_flow_flush(port_id, &flush_error);
if (retval != 0) {
Expand Down
100 changes: 76 additions & 24 deletions src/util-dpdk-rss.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,20 @@

#ifdef HAVE_DPDK

struct rte_flow_action_rss DeviceInitRSSAction(struct rte_eth_rss_conf rss_conf, int nb_rx_queues,
uint16_t *queues, enum rte_eth_hash_function func, bool set_key)
/**
* \brief Initialize RSS action configuration for
* RTE_FLOW RSS rule based on input arguments
*
* \param rss_conf RSS configuration
* \param nb_rx_queues number of rx queues
* \param queues array of queue indexes
* \param func RSS hash function
* \param set_key flag to set RSS hash key and it's length
* \return struct rte_flow_action_rss RSS action configuration
* to be used in a rule
*/
struct rte_flow_action_rss DeviceInitRSSAction(struct rte_eth_rss_conf rss_conf, int nb_rx_queues, uint16_t *queues,
enum rte_eth_hash_function func, bool set_key)
{
struct rte_flow_action_rss rss_action_conf = { 0 };
rss_action_conf.func = func;
Expand All @@ -61,12 +73,21 @@ struct rte_flow_action_rss DeviceInitRSSAction(struct rte_eth_rss_conf rss_conf,
return rss_action_conf;
}

int DeviceCreateRSSFlowUniform(
/**
* \brief Creates RTE_FLOW RSS rule used by NIC drivers
* to redistribute packets to different queues based
* on IP adresses.
*
* \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
*/
int DeviceCreateRSSFlowGeneric(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
struct rte_flow_attr attr = { 0 };
struct rte_flow_action action[] = { { 0 }, { 0 } };
struct rte_flow *flow;
struct rte_flow_error flow_error = { 0 };
struct rte_flow_item pattern[] = { { 0 } };

Expand All @@ -79,26 +100,38 @@ int DeviceCreateRSSFlowUniform(

pattern[0].type = RTE_FLOW_ITEM_TYPE_END;

flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
struct rte_flow *flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
if (flow == NULL) {
SCLogError("Error when creating rte_flow rule on %s: %s", port_name, flow_error.message);
int ret = rte_flow_validate(port_id, &attr, pattern, action, &flow_error);
SCLogError("Error on rte_flow validation for port %s: %s errmsg: %s", port_name,
rte_strerror(-ret), flow_error.message);
return ret;
} else {
SCLogInfo("RTE_FLOW flow rule created for port %s", port_name);
SCLogDebug("RTE_FLOW flow rule created for port %s", port_name);
}

return 0;
}

/**
* \brief Create RTE_FLOW RSS rule configured with pattern and rss_type
* but with no rx_queues configured. This is specific way of setting RTE_FLOW RSS rule
* for some drivers (mostly for intel NICs). This function's call must be preceded by
* call to function DeviceSetRSSFlowQueues().
*
* \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
* \param rss_type RSS hash type - only this type is used when creating hash with RSS hash function
* \param pattern pattern to match incoming traffic
* \return int 0 on success, a negative errno value otherwise
*/
static int DeviceCreateRSSFlow(int port_id, const char *port_name,
struct rte_flow_action_rss rss_conf, uint64_t rss_type, struct rte_flow_item *pattern)
{
struct rte_flow_attr attr = { 0 };
struct rte_flow_action action[] = { { 0 }, { 0 } };
struct rte_flow *flow;
struct rte_flow_error flow_error = { 0 };

rss_conf.types = rss_type;
Expand All @@ -108,32 +141,37 @@ static int DeviceCreateRSSFlow(int port_id, const char *port_name,
action[0].conf = &rss_conf;
action[1].type = RTE_FLOW_ACTION_TYPE_END;

flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
struct rte_flow *flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
if (flow == NULL) {
SCLogError("Error when creating rte_flow rule on %s: %s", port_name, flow_error.message);
int ret = rte_flow_validate(port_id, &attr, pattern, action, &flow_error);
SCLogError("Error on rte_flow validation for port %s: %s errmsg: %s", port_name,
rte_strerror(-ret), flow_error.message);
return ret;
} else {
SCLogInfo("RTE_FLOW flow rule created for port %s", port_name);
SCLogDebug("RTE_FLOW flow rule created for port %s", port_name);
}

return 0;
}

/**
* @brief Some drivers (mostly for intel NICs) require specific way of setting RTE_FLOW RSS rules
* \brief Some drivers (mostly for intel NICs) require specific way of setting RTE_FLOW RSS rules
* with one rule that sets up only queues and other rules that specify patterns to match with
* queues configured.
* queues configured (created with function DeviceCreateRSSFlow() that should follow after this function's
* call).
*
* \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
*/

int DeviceSetRSSFlowQueues(int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
int DeviceSetRSSFlowQueues(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
struct rte_flow_attr attr = { 0 };
struct rte_flow_item pattern[] = { { 0 }, { 0 }, { 0 }, { 0 } };
struct rte_flow_action action[] = { { 0 }, { 0 } };
struct rte_flow *flow;
struct rte_flow_error flow_error = { 0 };

rss_conf.types = 0; // queues region can not be configured with types
Expand All @@ -144,43 +182,57 @@ int DeviceSetRSSFlowQueues(int port_id, const char *port_name, struct rte_flow_a
action[0].conf = &rss_conf;
action[1].type = RTE_FLOW_ACTION_TYPE_END;

flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
struct rte_flow *flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error);
if (flow == NULL) {
SCLogError("Error when creating rte_flow rule on %s: %s", port_name, flow_error.message);
int ret = rte_flow_validate(port_id, &attr, pattern, action, &flow_error);
SCLogError("Error on rte_flow validation for port %s: %s errmsg: %s", port_name,
rte_strerror(-ret), flow_error.message);
return ret;
} else {
SCLogInfo("RTE_FLOW queue region created for port %s", port_name);
SCLogDebug("RTE_FLOW queue region created for port %s", port_name);
}
return 0;
}

int DeviceSetRSSFlowIPv4(int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
/**
* \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
*/
int DeviceSetRSSFlowIPv4(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
int ret = 0;
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;
ret |= DeviceCreateRSSFlow(port_id, port_name, rss_conf, RTE_ETH_RSS_IPV4, pattern);

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

int DeviceSetRSSFlowIPv6(int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
/**
* \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
*/
int DeviceSetRSSFlowIPv6(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf)
{
int ret = 0;
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;
ret |= DeviceCreateRSSFlow(port_id, port_name, rss_conf, RTE_ETH_RSS_IPV6, pattern);

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

#endif /* HAVE_DPDK */
Expand Down
2 changes: 1 addition & 1 deletion src/util-dpdk-rss.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
struct rte_flow_action_rss DeviceInitRSSAction(struct rte_eth_rss_conf rss_conf, int nb_rx_queues,
uint16_t *queues, enum rte_eth_hash_function func, bool set_key);
int DeviceSetRSSFlowQueues(int port_id, const char *port_name, struct rte_flow_action_rss rss_conf);
int DeviceCreateRSSFlowUniform(
int DeviceCreateRSSFlowGeneric(
int port_id, const char *port_name, struct rte_flow_action_rss rss_conf);
int DeviceSetRSSFlowIPv4(int port_id, const char *port_name, struct rte_flow_action_rss rss_conf);
int DeviceSetRSSFlowIPv6(int port_id, const char *port_name, struct rte_flow_action_rss rss_conf);
Expand Down

0 comments on commit 796aca1

Please sign in to comment.