From 0e4cce4e11c85ec90243746f6db8239fb4c1bd34 Mon Sep 17 00:00:00 2001 From: Adam Kiripolsky Date: Tue, 10 Dec 2024 16:29:00 +0100 Subject: [PATCH] dpdk/rss: add rte_flow_rss support for mlx5 mlx5 driver uses only one generic rte_flow rss rule to match all traffic Ticket: 7337 --- src/Makefile.am | 2 ++ src/source-dpdk.c | 5 ++- src/util-dpdk-mlx5.c | 76 ++++++++++++++++++++++++++++++++++++++++++++ src/util-dpdk-mlx5.h | 35 ++++++++++++++++++++ src/util-dpdk-rss.c | 3 +- 5 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/util-dpdk-mlx5.c create mode 100644 src/util-dpdk-mlx5.h diff --git a/src/Makefile.am b/src/Makefile.am index 449aad5480c9..56b77a2ad3a7 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -479,6 +479,7 @@ noinst_HEADERS = \ util-dpdk-i40e.h \ util-dpdk-ice.h \ util-dpdk-ixgbe.h \ + util-dpdk-mlx5.h \ util-dpdk-bonding.h \ util-dpdk-rss.h \ util-ebpf.h \ @@ -1028,6 +1029,7 @@ libsuricata_c_a_SOURCES = \ util-dpdk-i40e.c \ util-dpdk-ice.c \ util-dpdk-ixgbe.c \ + util-dpdk-mlx5.c \ util-dpdk-bonding.c \ util-dpdk-rss.c \ util-ebpf.c \ diff --git a/src/source-dpdk.c b/src/source-dpdk.c index 4b7d9bc3dcdb..8a475d59f1db 100644 --- a/src/source-dpdk.c +++ b/src/source-dpdk.c @@ -90,6 +90,7 @@ TmEcode NoDPDKSupportExit(ThreadVars *tv, const void *initdata, void **data) #include "util-dpdk-i40e.h" #include "util-dpdk-ice.h" #include "util-dpdk-ixgbe.h" +#include "util-dpdk-mlx5.h" #include "util-dpdk-bonding.h" #include @@ -200,6 +201,8 @@ static void DevicePostStartPMDSpecificActions(DPDKThreadVars *ptv, const char *d ixgbeDeviceSetRSS(ptv->port_id, ptv->threads, ptv->livedev->dev); if (strcmp(driver_name, "net_ice") == 0) iceDeviceSetRSS(ptv->port_id, ptv->threads, ptv->livedev->dev); + if (strcmp(driver_name, "mlx5_pci") == 0) + mlx5DeviceSetRSS(ptv->port_id, ptv->threads, ptv->livedev->dev); } static void DevicePreClosePMDSpecificActions(DPDKThreadVars *ptv, const char *driver_name) @@ -209,7 +212,7 @@ static void DevicePreClosePMDSpecificActions(DPDKThreadVars *ptv, const char *dr } if (strcmp(driver_name, "net_i40e") == 0 || strcmp(driver_name, "net_ixgbe") == 0 || - strcmp(driver_name, "net_ice") == 0) { + strcmp(driver_name, "net_ice") == 0 || strcmp(driver_name, "mlx5_pci") == 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 }; diff --git a/src/util-dpdk-mlx5.c b/src/util-dpdk-mlx5.c new file mode 100644 index 000000000000..314b24919ad9 --- /dev/null +++ b/src/util-dpdk-mlx5.c @@ -0,0 +1,76 @@ +/* Copyright (C) 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 NVIDIA mlx5 driver helpers functions + * + * @{ + */ + +/** + * \file + * + * \author Adam Kiripolsky + * + * DPDK driver's helper functions + * + */ + +#include "util-debug.h" +#include "util-dpdk.h" +#include "util-dpdk-bonding.h" +#include "util-dpdk-mlx5.h" +#include "util-dpdk-rss.h" + +#ifdef HAVE_DPDK + +#define MLX5_RSS_HKEY_LEN 40 + +int mlx5DeviceSetRSS(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 = { + .rss_key = RSS_HKEY, + .rss_key_len = MLX5_RSS_HKEY_LEN, + }; + + 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, nb_rx_queues, queues, RTE_ETH_HASH_FUNCTION_TOEPLITZ, true); + + int retval = DeviceCreateRSSFlowGeneric(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; +} + +#endif /* HAVE_DPDK */ +/** + * @} + */ diff --git a/src/util-dpdk-mlx5.h b/src/util-dpdk-mlx5.h new file mode 100644 index 000000000000..c7b871405c01 --- /dev/null +++ b/src/util-dpdk-mlx5.h @@ -0,0 +1,35 @@ +/* Copyright (C) 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. + */ + +/** + * \file + * + * \author Adam Kiripolsky + */ + +#ifndef UTIL_DPDK_MLX5_H +#define UTIL_DPDK_MLX5_H + +#include "suricata-common.h" + +#ifdef HAVE_DPDK + +int mlx5DeviceSetRSS(int port_id, int nb_rx_queues, char *port_name); + +#endif /* HAVE_DPDK */ + +#endif /* UTIL_DPDK_MLX5_H */ diff --git a/src/util-dpdk-rss.c b/src/util-dpdk-rss.c index 51378ae49ef5..c77b1e8356bb 100644 --- a/src/util-dpdk-rss.c +++ b/src/util-dpdk-rss.c @@ -108,7 +108,8 @@ int DeviceCreateRSSFlowGeneric( action[0].conf = &rss_conf; action[1].type = RTE_FLOW_ACTION_TYPE_END; - pattern[0].type = RTE_FLOW_ITEM_TYPE_END; + pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH; + pattern[1].type = RTE_FLOW_ITEM_TYPE_END; struct rte_flow *flow = rte_flow_create(port_id, &attr, pattern, action, &flow_error); if (flow == NULL) {