From 796aca112228f4eccd9ef09d7041202c01f5de7b Mon Sep 17 00:00:00 2001 From: Adam Kiripolsky Date: Wed, 4 Dec 2024 16:34:51 +0100 Subject: [PATCH] dpdk/rss MR changes --- src/util-dpdk-i40e.c | 6 +-- src/util-dpdk-ice.c | 28 +++--------- src/util-dpdk-ixgbe.c | 64 +++++++++++++-------------- src/util-dpdk-mlx5.c | 6 +-- src/util-dpdk-rss.c | 100 ++++++++++++++++++++++++++++++++---------- src/util-dpdk-rss.h | 2 +- 6 files changed, 117 insertions(+), 89 deletions(-) diff --git a/src/util-dpdk-i40e.c b/src/util-dpdk-i40e.c index d332e0c150d8..cc2202d0ddff 100644 --- a/src/util-dpdk-i40e.c +++ b/src/util-dpdk-i40e.c @@ -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 @@ -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, @@ -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); diff --git a/src/util-dpdk-ice.c b/src/util-dpdk-ice.c index 3d5dd863d8c9..7cc27b61c132 100644 --- a/src/util-dpdk-ice.c +++ b/src/util-dpdk-ice.c @@ -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, @@ -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) { diff --git a/src/util-dpdk-ixgbe.c b/src/util-dpdk-ixgbe.c index 8e5452c97490..d08dbdf5a58f 100644 --- a/src/util-dpdk-ixgbe.c +++ b/src/util-dpdk-ixgbe.c @@ -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 -// * -// * DPDK driver's helper functions -// * -// */ +/** + * \file + * + * \author Lukas Sismis + * + * DPDK driver's helper functions + * + */ #include "util-dpdk-ixgbe.h" #include "util-dpdk.h" @@ -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, @@ -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) { diff --git a/src/util-dpdk-mlx5.c b/src/util-dpdk-mlx5.c index 14049bad10a9..5f7ee723f209 100644 --- a/src/util-dpdk-mlx5.c +++ b/src/util-dpdk-mlx5.c @@ -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, @@ -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) { diff --git a/src/util-dpdk-rss.c b/src/util-dpdk-rss.c index 6bf1b0e9953e..44420f5402f5 100644 --- a/src/util-dpdk-rss.c +++ b/src/util-dpdk-rss.c @@ -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; @@ -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 } }; @@ -79,7 +100,7 @@ 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); @@ -87,18 +108,30 @@ int DeviceCreateRSSFlowUniform( 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; @@ -108,7 +141,7 @@ 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); @@ -116,24 +149,29 @@ static int DeviceCreateRSSFlow(int port_id, const char *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 @@ -144,7 +182,7 @@ 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); @@ -152,35 +190,49 @@ int DeviceSetRSSFlowQueues(int port_id, const char *port_name, struct rte_flow_a 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 */ diff --git a/src/util-dpdk-rss.h b/src/util-dpdk-rss.h index 38db769c8a83..bc254673e959 100644 --- a/src/util-dpdk-rss.h +++ b/src/util-dpdk-rss.h @@ -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);