patches for DPDK stable branches
 help / color / mirror / Atom feed
* [PATCH] net/ice: add source prune configuration API
@ 2025-11-01 10:46 Anurag Mandal
  2025-11-01 18:29 ` [PATCH v2] " Anurag Mandal
  2025-11-05 18:30 ` [PATCH v4] net/ice: add option to enable source prune Anurag Mandal
  0 siblings, 2 replies; 5+ messages in thread
From: Anurag Mandal @ 2025-11-01 10:46 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson, anatoly.burakov, Anurag Mandal, stable

Source prune is disabled by default to support
VRRP advertisement packets in a vsi of ice PF.
There is no way to enable source prune itself.

This patch adds a PMD specific API to enable/disable
source prune for all PF ports or for an indiviual PF port.

Tested the following with VRRP advertisement packets in a
vsi of ice PF :-
1. Source prune default mode.
2. Enable source prune for an indiviual PF port.
3. Disable source prune for an indiviual PF port
4. Enable source prune for all PF ports.
5. Disable source prune for all PF ports.

Fixes: 6f866eb93e79 ("net/ice: fix dropped packets when using VRRP")
Cc: stable@dpdk.org

Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c  | 72 +++++++++++++++++++++++
 drivers/net/intel/ice/ice_ethdev.h  | 16 ++++++
 drivers/net/intel/ice/ice_testpmd.c | 88 +++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 4669eba7c7..2431199add 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -13,6 +13,7 @@
 #include <unistd.h>
 #include <math.h>
 
+#include <eal_export.h>
 #include <rte_tailq.h>
 #include <rte_os_shim.h>
 
@@ -201,6 +202,7 @@ static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_
 						size_t *no_of_elements);
 static int ice_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info);
 static int ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf);
+static int ice_pf_set_source_prune(struct ice_pf *pf, uint8_t on);
 
 static const struct rte_pci_id pci_id_ice_map[] = {
 	{ RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -1703,6 +1705,75 @@ ice_pf_sw_init(struct rte_eth_dev *dev)
 	return 0;
 }
 
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_ice_set_pf_src_prune, 25.11)
+int
+rte_pmd_ice_set_pf_src_prune(uint16_t port, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct ice_pf *pf;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_ice_supported(dev))
+		return -ENOTSUP;
+
+	pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	ret = ice_pf_set_source_prune(pf, on);
+	return ret;
+}
+
+/* ice_pf_set_source_prune
+ * @pf: pointer to the pf structure
+ * @on: enable/disable source prune
+ *
+ * set source prune on pf
+ */
+static int
+ice_pf_set_source_prune(struct ice_pf *pf, uint8_t on)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+	struct ice_vsi *vsi = pf->main_vsi;
+	struct ice_vsi_ctx ctxt;
+	int ret;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	ctxt.flags = ICE_AQ_VSI_TYPE_PF;
+	ctxt.info.valid_sections |=
+		rte_cpu_to_le_16(ICE_AQ_VSI_PROP_SW_VALID);
+	ctxt.info.sw_id = hw->port_info->sw_id;
+	ctxt.vsi_num = vsi->vsi_id;
+
+	if (on) {
+		/* Enable source prune */
+		ctxt.info.sw_flags &=
+			~(ICE_AQ_VSI_SW_FLAG_LOCAL_LB);
+		ctxt.info.sw_flags &=
+			~(ICE_AQ_VSI_SW_FLAG_SRC_PRUNE);
+	} else {
+		/* Disable source prune to support VRRP */
+		ctxt.info.sw_flags =
+			ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
+		ctxt.info.sw_flags |=
+			ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
+	}
+
+        ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
+        if (ret) {
+                PMD_DRV_LOG(ERR, "Update VSI failed to %s source prune",
+                            on ? "enable" : "disable");
+                return -EINVAL;
+        } else {
+		vsi->info.valid_sections |=
+			rte_cpu_to_le_16(ICE_AQ_VSI_PROP_SW_VALID);
+		vsi->info.sw_flags = ctxt.info.sw_flags;
+        }
+
+        return 0;
+}
+
 struct ice_vsi *
 ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 {
@@ -1753,6 +1824,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 		 * by ice_init_hw
 		 */
 		vsi_ctx.info.sw_id = hw->port_info->sw_id;
+		/* disable source prune to support VRRP in default */
 		vsi_ctx.info.sw_flags = ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
 		vsi_ctx.info.sw_flags |= ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
 		cfg = ICE_AQ_VSI_PROP_SW_VALID;
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 6478d6dfbd..c2dad32045 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -805,6 +805,22 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size);
 __rte_experimental
 int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream);
 
+/**
+ * Enable/Disable source prune on all the PF.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable source prune.
+ *    0 - Disable source prune.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+__rte_experimental
+int rte_pmd_ice_set_pf_src_prune(uint16_t port, uint8_t on);
+
 int
 ice_tm_setup_txq_node(struct ice_pf *pf, struct ice_hw *hw, uint16_t qid, uint32_t node_teid);
 
diff --git a/drivers/net/intel/ice/ice_testpmd.c b/drivers/net/intel/ice/ice_testpmd.c
index 98c02d68c6..29a15f548f 100644
--- a/drivers/net/intel/ice/ice_testpmd.c
+++ b/drivers/net/intel/ice/ice_testpmd.c
@@ -206,6 +206,84 @@ cmdline_parse_inst_t cmd_txsched_dump = {
 	},
 };
 
+/* *** configure source prune for ice port *** */
+struct cmd_config_src_prune_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t keyword;
+	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
+	uint16_t port_id;                /* valid if "allports" argument == 0 */
+	cmdline_fixed_string_t item;
+	cmdline_fixed_string_t enable;
+};
+
+static void cmd_config_pf_src_prune_parsed(void *parsed_result,
+					__rte_unused struct cmdline *cl,
+					void *allports)
+{
+	struct cmd_config_src_prune_result *res = parsed_result;
+	uint8_t enable;
+	uint16_t i;
+
+	if (!strcmp(res->enable, "on"))
+		enable = 1;
+	else
+		enable = 0;
+
+	/* all ports */
+	if (allports) {
+		RTE_ETH_FOREACH_DEV(i)
+			rte_pmd_ice_set_pf_src_prune(i, enable);
+	} else {
+		rte_pmd_ice_set_pf_src_prune(res->port_id, enable);
+	}
+}
+
+static cmdline_parse_token_string_t cmd_config_src_prune_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port, "port");
+static cmdline_parse_token_string_t cmd_config_src_prune_keyword =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, keyword,
+				 "config");
+static cmdline_parse_token_string_t cmd_config_src_prune_portall =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port_all,
+				 "all");
+static cmdline_parse_token_num_t cmd_config_src_prune_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_src_prune_result, port_id,
+			      RTE_UINT16);
+static cmdline_parse_token_string_t cmd_config_src_prune_item =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result,
+			item, "ice_source_prune");
+static cmdline_parse_token_string_t cmd_config_src_prune_enable =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, enable,
+				 "on#off");
+
+static cmdline_parse_inst_t cmd_config_src_prune_all = {
+	.f = cmd_config_pf_src_prune_parsed,
+	.data = (void *)1,
+	.help_str = "port config all ice_source_prune on|off: Set source prune on/off all pf ports.",
+	.tokens = {
+		(void *)&cmd_config_src_prune_port,
+		(void *)&cmd_config_src_prune_keyword,
+		(void *)&cmd_config_src_prune_portall,
+		(void *)&cmd_config_src_prune_item,
+		(void *)&cmd_config_src_prune_enable,
+		NULL,
+	},
+};
+
+static cmdline_parse_inst_t cmd_config_src_prune_specific = {
+	.f = cmd_config_pf_src_prune_parsed,
+	.data = (void *)0,
+	.help_str = "port config <port_id> ice_source_prune on|off: Set source prune on/off specific pf port.",
+	.tokens = {
+		(void *)&cmd_config_src_prune_port,
+		(void *)&cmd_config_src_prune_keyword,
+		(void *)&cmd_config_src_prune_port_id,
+		(void *)&cmd_config_src_prune_item,
+		(void *)&cmd_config_src_prune_enable,
+		NULL,
+	},
+};
+
 static struct testpmd_driver_commands ice_cmds = {
 	.commands = {
 	{
@@ -225,6 +303,16 @@ static struct testpmd_driver_commands ice_cmds = {
 		"txsched dump (port_id) <brief|detail> (config_path)\n"
 		"    Dump tx scheduling runtime configure on a port\n\n",
 
+	},
+		{
+		&cmd_config_src_prune_all,
+		"port config all ice_source_prune (on|off)\n"
+		"    Set source prune on/off pf port all.\n"
+	},
+	{
+		&cmd_config_src_prune_specific,
+		"port config (port_id) ice_source_prune (on|off)\n"
+		"    Set source prune on/off pf port_id.\n"
 	},
 	{ NULL, NULL },
 	},
-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] net/ice: add source prune configuration API
  2025-11-01 10:46 [PATCH] net/ice: add source prune configuration API Anurag Mandal
@ 2025-11-01 18:29 ` Anurag Mandal
  2025-11-02  1:19   ` [PATCH v3] " Anurag Mandal
  2025-11-05 18:30 ` [PATCH v4] net/ice: add option to enable source prune Anurag Mandal
  1 sibling, 1 reply; 5+ messages in thread
From: Anurag Mandal @ 2025-11-01 18:29 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson, anatoly.burakov, Anurag Mandal, stable

Source prune is disabled by default to support
VRRP advertisement packets in a vsi of ice PF.
There is no way to enable source prune itself.

This patch adds a PMD specific API to enable/disable
source prune for all PF ports or for an individual PF port.

Tested the following with VRRP advertisement packets in a
vsi of ice PF:
1. Source prune default mode.
2. Enable source prune for an individual PF port.
3. Disable source prune for an individual PF port.
4. Enable source prune for all PF ports.
5. Disable source prune for all PF ports.

Fixes: 6f866eb93e79 ("net/ice: fix dropped packets when using VRRP")
Cc: stable@dpdk.org

Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c  | 72 +++++++++++++++++++++++
 drivers/net/intel/ice/ice_ethdev.h  | 16 ++++++
 drivers/net/intel/ice/ice_testpmd.c | 88 +++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 4669eba7c7..27904589d5 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -2,6 +2,7 @@
  * Copyright(c) 2018 Intel Corporation
  */
 
+#include <eal_export.h>
 #include <rte_string_fns.h>
 #include <ethdev_pci.h>
 
@@ -201,6 +202,7 @@ static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_
 						size_t *no_of_elements);
 static int ice_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info);
 static int ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf);
+static int ice_pf_set_source_prune(struct ice_pf *pf, uint8_t on);
 
 static const struct rte_pci_id pci_id_ice_map[] = {
 	{ RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -1703,6 +1705,75 @@ ice_pf_sw_init(struct rte_eth_dev *dev)
 	return 0;
 }
 
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_ice_set_pf_src_prune, 25.11)
+int
+rte_pmd_ice_set_pf_src_prune(uint16_t port, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct ice_pf *pf;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_ice_supported(dev))
+		return -ENOTSUP;
+
+	pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	ret = ice_pf_set_source_prune(pf, on);
+	return ret;
+}
+
+/* ice_pf_set_source_prune
+ * @pf: pointer to the pf structure
+ * @on: enable/disable source prune
+ *
+ * set source prune on pf
+ */
+static int
+ice_pf_set_source_prune(struct ice_pf *pf, uint8_t on)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+	struct ice_vsi *vsi = pf->main_vsi;
+	struct ice_vsi_ctx ctxt;
+	int ret;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	ctxt.flags = ICE_AQ_VSI_TYPE_PF;
+	ctxt.info.valid_sections |=
+		rte_cpu_to_le_16(ICE_AQ_VSI_PROP_SW_VALID);
+	ctxt.info.sw_id = hw->port_info->sw_id;
+	ctxt.vsi_num = vsi->vsi_id;
+
+	if (on) {
+		/* Enable source prune */
+		ctxt.info.sw_flags &=
+			~(ICE_AQ_VSI_SW_FLAG_LOCAL_LB);
+		ctxt.info.sw_flags &=
+			~(ICE_AQ_VSI_SW_FLAG_SRC_PRUNE);
+	} else {
+		/* Disable source prune to support VRRP */
+		ctxt.info.sw_flags =
+			ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
+		ctxt.info.sw_flags |=
+			ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
+	}
+
+	ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Update VSI failed to %s source prune",
+			on ? "enable" : "disable");
+		return -EINVAL;
+	} else {
+		vsi->info.valid_sections |=
+			rte_cpu_to_le_16(ICE_AQ_VSI_PROP_SW_VALID);
+		vsi->info.sw_flags = ctxt.info.sw_flags;
+	}
+
+	return 0;
+}
+
 struct ice_vsi *
 ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 {
@@ -1753,6 +1824,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 		 * by ice_init_hw
 		 */
 		vsi_ctx.info.sw_id = hw->port_info->sw_id;
+		/* disable source prune to support VRRP in default */
 		vsi_ctx.info.sw_flags = ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
 		vsi_ctx.info.sw_flags |= ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
 		cfg = ICE_AQ_VSI_PROP_SW_VALID;
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 6478d6dfbd..c2dad32045 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -805,6 +805,22 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size);
 __rte_experimental
 int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream);
 
+/**
+ * Enable/Disable source prune on all the PF.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable source prune.
+ *    0 - Disable source prune.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+__rte_experimental
+int rte_pmd_ice_set_pf_src_prune(uint16_t port, uint8_t on);
+
 int
 ice_tm_setup_txq_node(struct ice_pf *pf, struct ice_hw *hw, uint16_t qid, uint32_t node_teid);
 
diff --git a/drivers/net/intel/ice/ice_testpmd.c b/drivers/net/intel/ice/ice_testpmd.c
index 98c02d68c6..29a15f548f 100644
--- a/drivers/net/intel/ice/ice_testpmd.c
+++ b/drivers/net/intel/ice/ice_testpmd.c
@@ -206,6 +206,84 @@ cmdline_parse_inst_t cmd_txsched_dump = {
 	},
 };
 
+/* *** configure source prune for ice port *** */
+struct cmd_config_src_prune_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t keyword;
+	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
+	uint16_t port_id;                /* valid if "allports" argument == 0 */
+	cmdline_fixed_string_t item;
+	cmdline_fixed_string_t enable;
+};
+
+static void cmd_config_pf_src_prune_parsed(void *parsed_result,
+					__rte_unused struct cmdline *cl,
+					void *allports)
+{
+	struct cmd_config_src_prune_result *res = parsed_result;
+	uint8_t enable;
+	uint16_t i;
+
+	if (!strcmp(res->enable, "on"))
+		enable = 1;
+	else
+		enable = 0;
+
+	/* all ports */
+	if (allports) {
+		RTE_ETH_FOREACH_DEV(i)
+			rte_pmd_ice_set_pf_src_prune(i, enable);
+	} else {
+		rte_pmd_ice_set_pf_src_prune(res->port_id, enable);
+	}
+}
+
+static cmdline_parse_token_string_t cmd_config_src_prune_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port, "port");
+static cmdline_parse_token_string_t cmd_config_src_prune_keyword =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, keyword,
+				 "config");
+static cmdline_parse_token_string_t cmd_config_src_prune_portall =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port_all,
+				 "all");
+static cmdline_parse_token_num_t cmd_config_src_prune_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_src_prune_result, port_id,
+			      RTE_UINT16);
+static cmdline_parse_token_string_t cmd_config_src_prune_item =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result,
+			item, "ice_source_prune");
+static cmdline_parse_token_string_t cmd_config_src_prune_enable =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, enable,
+				 "on#off");
+
+static cmdline_parse_inst_t cmd_config_src_prune_all = {
+	.f = cmd_config_pf_src_prune_parsed,
+	.data = (void *)1,
+	.help_str = "port config all ice_source_prune on|off: Set source prune on/off all pf ports.",
+	.tokens = {
+		(void *)&cmd_config_src_prune_port,
+		(void *)&cmd_config_src_prune_keyword,
+		(void *)&cmd_config_src_prune_portall,
+		(void *)&cmd_config_src_prune_item,
+		(void *)&cmd_config_src_prune_enable,
+		NULL,
+	},
+};
+
+static cmdline_parse_inst_t cmd_config_src_prune_specific = {
+	.f = cmd_config_pf_src_prune_parsed,
+	.data = (void *)0,
+	.help_str = "port config <port_id> ice_source_prune on|off: Set source prune on/off specific pf port.",
+	.tokens = {
+		(void *)&cmd_config_src_prune_port,
+		(void *)&cmd_config_src_prune_keyword,
+		(void *)&cmd_config_src_prune_port_id,
+		(void *)&cmd_config_src_prune_item,
+		(void *)&cmd_config_src_prune_enable,
+		NULL,
+	},
+};
+
 static struct testpmd_driver_commands ice_cmds = {
 	.commands = {
 	{
@@ -225,6 +303,16 @@ static struct testpmd_driver_commands ice_cmds = {
 		"txsched dump (port_id) <brief|detail> (config_path)\n"
 		"    Dump tx scheduling runtime configure on a port\n\n",
 
+	},
+		{
+		&cmd_config_src_prune_all,
+		"port config all ice_source_prune (on|off)\n"
+		"    Set source prune on/off pf port all.\n"
+	},
+	{
+		&cmd_config_src_prune_specific,
+		"port config (port_id) ice_source_prune (on|off)\n"
+		"    Set source prune on/off pf port_id.\n"
 	},
 	{ NULL, NULL },
 	},
-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3] net/ice: add source prune configuration API
  2025-11-01 18:29 ` [PATCH v2] " Anurag Mandal
@ 2025-11-02  1:19   ` Anurag Mandal
  2025-11-05  9:13     ` Bruce Richardson
  0 siblings, 1 reply; 5+ messages in thread
From: Anurag Mandal @ 2025-11-02  1:19 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson, anatoly.burakov, Anurag Mandal, stable

Source prune is disabled by default to support
VRRP advertisement packets in a vsi of ice PF.
There is no way to enable source prune itself.

This patch adds a PMD specific API to enable/disable
source prune for all PF ports or for an individual PF port.

Tested the following with VRRP advertisement packets in a
vsi of ice PF:
1. Source prune default mode.
2. Enable source prune for an individual PF port.
3. Disable source prune for an individual PF port.
4. Enable source prune for all PF ports.
5. Disable source prune for all PF ports.

Fixes: 6f866eb93e79 ("net/ice: fix dropped packets when using VRRP")
Cc: stable@dpdk.org

Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
---
 drivers/net/intel/ice/ice_ethdev.c  | 72 +++++++++++++++++++++++
 drivers/net/intel/ice/ice_ethdev.h  | 16 ++++++
 drivers/net/intel/ice/ice_testpmd.c | 88 +++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)

diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 4669eba7c7..d1565f0a7a 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -2,6 +2,7 @@
  * Copyright(c) 2018 Intel Corporation
  */
 
+#include <eal_export.h>
 #include <rte_string_fns.h>
 #include <ethdev_pci.h>
 
@@ -201,6 +202,7 @@ static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_
 						size_t *no_of_elements);
 static int ice_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info);
 static int ice_priority_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_pfc_conf *pfc_conf);
+static int ice_pf_set_source_prune(struct ice_pf *pf, uint8_t on);
 
 static const struct rte_pci_id pci_id_ice_map[] = {
 	{ RTE_PCI_DEVICE(ICE_INTEL_VENDOR_ID, ICE_DEV_ID_E823L_BACKPLANE) },
@@ -1703,6 +1705,75 @@ ice_pf_sw_init(struct rte_eth_dev *dev)
 	return 0;
 }
 
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_pmd_ice_set_pf_src_prune, 25.11)
+int
+rte_pmd_ice_set_pf_src_prune(uint16_t port, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct ice_pf *pf;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_ice_supported(dev))
+		return -ENOTSUP;
+
+	pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	ret = ice_pf_set_source_prune(pf, on);
+	return ret;
+}
+
+/* ice_pf_set_source_prune
+ * @pf: pointer to the pf structure
+ * @on: enable/disable source prune
+ *
+ * set source prune on pf
+ */
+static int
+ice_pf_set_source_prune(struct ice_pf *pf, uint8_t on)
+{
+	struct ice_hw *hw = ICE_PF_TO_HW(pf);
+	struct ice_vsi *vsi = pf->main_vsi;
+	struct ice_vsi_ctx ctxt;
+	int ret;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	ctxt.flags = ICE_AQ_VSI_TYPE_PF;
+	ctxt.info.valid_sections |=
+		rte_cpu_to_le_16(ICE_AQ_VSI_PROP_SW_VALID);
+	ctxt.info.sw_id = hw->port_info->sw_id;
+	ctxt.vsi_num = vsi->vsi_id;
+
+	if (on) {
+		/* Enable source prune */
+		ctxt.info.sw_flags &=
+			~(ICE_AQ_VSI_SW_FLAG_LOCAL_LB);
+		ctxt.info.sw_flags &=
+			~(ICE_AQ_VSI_SW_FLAG_SRC_PRUNE);
+	} else {
+		/* Disable source prune to support VRRP */
+		ctxt.info.sw_flags =
+			ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
+		ctxt.info.sw_flags |=
+			ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
+	}
+
+	ret = ice_update_vsi(hw, vsi->idx, &ctxt, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Update VSI failed to %s source prune",
+			on ? "enable" : "disable");
+		return -EINVAL;
+	}
+
+	vsi->info.valid_sections |=
+		rte_cpu_to_le_16(ICE_AQ_VSI_PROP_SW_VALID);
+	vsi->info.sw_flags = ctxt.info.sw_flags;
+
+	return 0;
+}
+
 struct ice_vsi *
 ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 {
@@ -1753,6 +1824,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 		 * by ice_init_hw
 		 */
 		vsi_ctx.info.sw_id = hw->port_info->sw_id;
+		/* disable source prune to support VRRP in default */
 		vsi_ctx.info.sw_flags = ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
 		vsi_ctx.info.sw_flags |= ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
 		cfg = ICE_AQ_VSI_PROP_SW_VALID;
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 6478d6dfbd..c2dad32045 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -805,6 +805,22 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size);
 __rte_experimental
 int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream);
 
+/**
+ * Enable/Disable source prune on all the PF.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable source prune.
+ *    0 - Disable source prune.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+__rte_experimental
+int rte_pmd_ice_set_pf_src_prune(uint16_t port, uint8_t on);
+
 int
 ice_tm_setup_txq_node(struct ice_pf *pf, struct ice_hw *hw, uint16_t qid, uint32_t node_teid);
 
diff --git a/drivers/net/intel/ice/ice_testpmd.c b/drivers/net/intel/ice/ice_testpmd.c
index 98c02d68c6..29a15f548f 100644
--- a/drivers/net/intel/ice/ice_testpmd.c
+++ b/drivers/net/intel/ice/ice_testpmd.c
@@ -206,6 +206,84 @@ cmdline_parse_inst_t cmd_txsched_dump = {
 	},
 };
 
+/* *** configure source prune for ice port *** */
+struct cmd_config_src_prune_result {
+	cmdline_fixed_string_t port;
+	cmdline_fixed_string_t keyword;
+	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
+	uint16_t port_id;                /* valid if "allports" argument == 0 */
+	cmdline_fixed_string_t item;
+	cmdline_fixed_string_t enable;
+};
+
+static void cmd_config_pf_src_prune_parsed(void *parsed_result,
+					__rte_unused struct cmdline *cl,
+					void *allports)
+{
+	struct cmd_config_src_prune_result *res = parsed_result;
+	uint8_t enable;
+	uint16_t i;
+
+	if (!strcmp(res->enable, "on"))
+		enable = 1;
+	else
+		enable = 0;
+
+	/* all ports */
+	if (allports) {
+		RTE_ETH_FOREACH_DEV(i)
+			rte_pmd_ice_set_pf_src_prune(i, enable);
+	} else {
+		rte_pmd_ice_set_pf_src_prune(res->port_id, enable);
+	}
+}
+
+static cmdline_parse_token_string_t cmd_config_src_prune_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port, "port");
+static cmdline_parse_token_string_t cmd_config_src_prune_keyword =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, keyword,
+				 "config");
+static cmdline_parse_token_string_t cmd_config_src_prune_portall =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port_all,
+				 "all");
+static cmdline_parse_token_num_t cmd_config_src_prune_port_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_src_prune_result, port_id,
+			      RTE_UINT16);
+static cmdline_parse_token_string_t cmd_config_src_prune_item =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result,
+			item, "ice_source_prune");
+static cmdline_parse_token_string_t cmd_config_src_prune_enable =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, enable,
+				 "on#off");
+
+static cmdline_parse_inst_t cmd_config_src_prune_all = {
+	.f = cmd_config_pf_src_prune_parsed,
+	.data = (void *)1,
+	.help_str = "port config all ice_source_prune on|off: Set source prune on/off all pf ports.",
+	.tokens = {
+		(void *)&cmd_config_src_prune_port,
+		(void *)&cmd_config_src_prune_keyword,
+		(void *)&cmd_config_src_prune_portall,
+		(void *)&cmd_config_src_prune_item,
+		(void *)&cmd_config_src_prune_enable,
+		NULL,
+	},
+};
+
+static cmdline_parse_inst_t cmd_config_src_prune_specific = {
+	.f = cmd_config_pf_src_prune_parsed,
+	.data = (void *)0,
+	.help_str = "port config <port_id> ice_source_prune on|off: Set source prune on/off specific pf port.",
+	.tokens = {
+		(void *)&cmd_config_src_prune_port,
+		(void *)&cmd_config_src_prune_keyword,
+		(void *)&cmd_config_src_prune_port_id,
+		(void *)&cmd_config_src_prune_item,
+		(void *)&cmd_config_src_prune_enable,
+		NULL,
+	},
+};
+
 static struct testpmd_driver_commands ice_cmds = {
 	.commands = {
 	{
@@ -225,6 +303,16 @@ static struct testpmd_driver_commands ice_cmds = {
 		"txsched dump (port_id) <brief|detail> (config_path)\n"
 		"    Dump tx scheduling runtime configure on a port\n\n",
 
+	},
+		{
+		&cmd_config_src_prune_all,
+		"port config all ice_source_prune (on|off)\n"
+		"    Set source prune on/off pf port all.\n"
+	},
+	{
+		&cmd_config_src_prune_specific,
+		"port config (port_id) ice_source_prune (on|off)\n"
+		"    Set source prune on/off pf port_id.\n"
 	},
 	{ NULL, NULL },
 	},
-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3] net/ice: add source prune configuration API
  2025-11-02  1:19   ` [PATCH v3] " Anurag Mandal
@ 2025-11-05  9:13     ` Bruce Richardson
  0 siblings, 0 replies; 5+ messages in thread
From: Bruce Richardson @ 2025-11-05  9:13 UTC (permalink / raw)
  To: Anurag Mandal; +Cc: dev, anatoly.burakov, stable

On Sun, Nov 02, 2025 at 01:19:19AM +0000, Anurag Mandal wrote:
> Source prune is disabled by default to support
> VRRP advertisement packets in a vsi of ice PF.
> There is no way to enable source prune itself.
> 
> This patch adds a PMD specific API to enable/disable
> source prune for all PF ports or for an individual PF port.
> 
> Tested the following with VRRP advertisement packets in a
> vsi of ice PF:
> 1. Source prune default mode.
> 2. Enable source prune for an individual PF port.
> 3. Disable source prune for an individual PF port.
> 4. Enable source prune for all PF ports.
> 5. Disable source prune for all PF ports.
> 
> Fixes: 6f866eb93e79 ("net/ice: fix dropped packets when using VRRP")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
> ---
>  drivers/net/intel/ice/ice_ethdev.c  | 72 +++++++++++++++++++++++
>  drivers/net/intel/ice/ice_ethdev.h  | 16 ++++++
>  drivers/net/intel/ice/ice_testpmd.c | 88 +++++++++++++++++++++++++++++
>  3 files changed, 176 insertions(+)
>
Rather than having a new private API for this, would a device arg (devarg)
passed on the commandline be a better choice? Private APIs are not really
nice in DPDK, and for this feature I can't see it being something that
needs enabling/disabling at runtime by apps. Just having it as a device
setting, set at init should probably work.

/Bruce 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4] net/ice: add option to enable source prune
  2025-11-01 10:46 [PATCH] net/ice: add source prune configuration API Anurag Mandal
  2025-11-01 18:29 ` [PATCH v2] " Anurag Mandal
@ 2025-11-05 18:30 ` Anurag Mandal
  1 sibling, 0 replies; 5+ messages in thread
From: Anurag Mandal @ 2025-11-05 18:30 UTC (permalink / raw)
  To: dev; +Cc: bruce.richardson, anatoly.burakov, Anurag Mandal, stable

Source prune is disabled by default to support
VRRP advertisement packets in a vsi of ice PF.
There is no way to enable source prune itself.

This patch introduces devarg "source-prune-enable" to allow
user to enable source prune.

Enable Source Prune to automatically drop incoming packets when
their source MAC address matches one of the MAC addresses assigned
to that same NIC port.

Tested the following with VRRP advertisement packets in a
vsi of ice PF:
1. Source prune default mode with no devarg option.
2. Enable source prune with devarg"source-prune-enable=1".
3. Disable source prune with devarg"source-prune-enable=0".

Fixes: 6f866eb93e79 ("net/ice: fix dropped packets when using VRRP")
Cc: stable@dpdk.org

Signed-off-by: Anurag Mandal <anurag.mandal@intel.com>
---
V4: Adressed Bruce Richardson's comment
 - changed from private API to devarg option.

 doc/guides/nics/ice.rst            | 11 +++++++++++
 drivers/net/intel/ice/ice_ethdev.c | 25 +++++++++++++++++++++++--
 drivers/net/intel/ice/ice_ethdev.h |  1 +
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 7e9ba23102..09561b08c5 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -183,6 +183,17 @@ Runtime Configuration
   If the value provided is greater than the number of levels provided by the HW,
   SW will use the hardware maximum value.
 
+- ``Source Prune Enable`` (default ``0``)
+
+  Enable Source Prune to automatically drop incoming packets when
+  their source MAC address matches one of the MAC addresses assigned
+  to that same NIC port.
+
+  Source Prune can be enabled by setting the devargs parameter ``source-prune-enable``,
+  for example::
+
+    -a 80:00.0,source-prune-enable=1
+
 - ``Protocol extraction for per queue``
 
   Configure the RX queues to do protocol extraction into mbuf for protocol
diff --git a/drivers/net/intel/ice/ice_ethdev.c b/drivers/net/intel/ice/ice_ethdev.c
index 4669eba7c7..540d0bd977 100644
--- a/drivers/net/intel/ice/ice_ethdev.c
+++ b/drivers/net/intel/ice/ice_ethdev.c
@@ -41,6 +41,7 @@
 #define ICE_DDP_FILENAME_ARG      "ddp_pkg_file"
 #define ICE_DDP_LOAD_SCHED_ARG    "ddp_load_sched_topo"
 #define ICE_TM_LEVELS_ARG         "tm_sched_levels"
+#define ICE_SRC_PRUNE_ENABLE_ARG  "source-prune-enable"
 #define ICE_LINK_STATE_ON_CLOSE   "link_state_on_close"
 
 #define ICE_CYCLECOUNTER_MASK  0xffffffffffffffffULL
@@ -58,6 +59,7 @@ static const char * const ice_valid_args[] = {
 	ICE_DDP_FILENAME_ARG,
 	ICE_DDP_LOAD_SCHED_ARG,
 	ICE_TM_LEVELS_ARG,
+	ICE_SRC_PRUNE_ENABLE_ARG,
 	ICE_LINK_STATE_ON_CLOSE,
 	NULL
 };
@@ -1716,6 +1718,7 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 	uint16_t max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
 	uint8_t tc_bitmap = 0x1;
 	uint16_t cfg;
+	struct ice_adapter *ad = (struct ice_adapter *)hw->back;
 
 	/* hw->num_lports = 1 in NIC mode */
 	vsi = rte_zmalloc(NULL, sizeof(struct ice_vsi), 0);
@@ -1753,8 +1756,20 @@ ice_setup_vsi(struct ice_pf *pf, enum ice_vsi_type type)
 		 * by ice_init_hw
 		 */
 		vsi_ctx.info.sw_id = hw->port_info->sw_id;
-		vsi_ctx.info.sw_flags = ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
-		vsi_ctx.info.sw_flags |= ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
+		/* Source Prune */
+		if (ad->devargs.source_prune_enable == 1) {
+			/* Enable source prune */
+			vsi_ctx.info.sw_flags &=
+				~(ICE_AQ_VSI_SW_FLAG_LOCAL_LB);
+			vsi_ctx.info.sw_flags &=
+				~(ICE_AQ_VSI_SW_FLAG_SRC_PRUNE);
+		} else {
+			/* Disable source prune to support VRRP */
+			vsi_ctx.info.sw_flags =
+				ICE_AQ_VSI_SW_FLAG_LOCAL_LB;
+			vsi_ctx.info.sw_flags |=
+				ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
+		}
 		cfg = ICE_AQ_VSI_PROP_SW_VALID;
 		vsi_ctx.info.valid_sections |= rte_cpu_to_le_16(cfg);
 		vsi_ctx.info.sw_flags2 = ICE_AQ_VSI_SW_FLAG_LAN_ENA;
@@ -2449,6 +2464,11 @@ static int ice_parse_devargs(struct rte_eth_dev *dev)
 	if (ret)
 		goto bail;
 
+	ret = rte_kvargs_process(kvlist, ICE_SRC_PRUNE_ENABLE_ARG,
+				 &parse_bool, &ad->devargs.source_prune_enable);
+	if (ret)
+		goto bail;
+
 	ret = rte_kvargs_process(kvlist, ICE_LINK_STATE_ON_CLOSE,
 				 &parse_link_state_on_close, &ad->devargs.link_state_on_close);
 
@@ -7659,6 +7679,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_ice,
 			      ICE_DDP_FILENAME_ARG "=</path/to/file>"
 			      ICE_DDP_LOAD_SCHED_ARG "=<0|1>"
 			      ICE_TM_LEVELS_ARG "=<N>"
+			      ICE_SRC_PRUNE_ENABLE_ARG "=<0|1>"
 			      ICE_RX_LOW_LATENCY_ARG "=<0|1>"
 			      ICE_LINK_STATE_ON_CLOSE "=<down|up|initial>");
 
diff --git a/drivers/net/intel/ice/ice_ethdev.h b/drivers/net/intel/ice/ice_ethdev.h
index 6478d6dfbd..408cbe4a38 100644
--- a/drivers/net/intel/ice/ice_ethdev.h
+++ b/drivers/net/intel/ice/ice_ethdev.h
@@ -614,6 +614,7 @@ struct ice_devargs {
 	uint8_t pps_out_ena;
 	uint8_t ddp_load_sched;
 	uint8_t tm_exposed_levels;
+	uint8_t source_prune_enable;
 	int link_state_on_close;
 	int xtr_field_offs;
 	uint8_t xtr_flag_offs[PROTO_XTR_MAX];
-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-11-05 18:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-11-01 10:46 [PATCH] net/ice: add source prune configuration API Anurag Mandal
2025-11-01 18:29 ` [PATCH v2] " Anurag Mandal
2025-11-02  1:19   ` [PATCH v3] " Anurag Mandal
2025-11-05  9:13     ` Bruce Richardson
2025-11-05 18:30 ` [PATCH v4] net/ice: add option to enable source prune Anurag Mandal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).