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)
#if RTE_VERSION > RTE_VERSION_NUM(20, 0, 0, 0)
strcmp(driver_name, "net_i40e") == 0 ||
#endif /* RTE_VERSION > RTE_VERSION_NUM(20, 0, 0, 0) */
- strcmp(driver_name, "net_ixgbe") == 0) {
+ strcmp(driver_name, "net_ixgbe") == 0 || strcmp(driver_name, "net_ice") == 0) {
// Flush the RSS rules that have been inserted in the post start section
struct rte_flow_error flush_error = { 0 };
int32_t retval = rte_flow_flush(ptv->port_id, &flush_error);
-/* Copyright (C) 2021 Open Information Security Foundation
+/* Copyright (C) 2021-2025 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
#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
#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 DPDKCreateRSSFlow(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 DPDKCreateRSSFlow(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 =
+ DPDKInitRSSAction(rss_conf, 0, queues, RTE_ETH_HASH_FUNCTION_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("%s: unable to flush rte_flow rules: %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);