DPDK patches and discussions
 help / color / mirror / Atom feed
From: Ke Zhang <ke1x.zhang@intel.com>
To: dev@dpdk.org, mb@smartsharesystems.com, thomas@monjalon.net,
	ferruh.yigit@amd.com, olivier.matz@6wind.com,
	Yuying.Zhang@intel.com, beilei.xing@intel.com
Cc: Ke Zhang <ke1x.zhang@intel.com>
Subject: [PATCH] net/i40e: disable source pruning
Date: Mon,  9 Jan 2023 10:20:27 +0800	[thread overview]
Message-ID: <20230109022027.190627-1-ke1x.zhang@intel.com> (raw)
In-Reply-To: <20211020012831.8480-1-alvinx.zhang@intel.com>

VRRP advertisement packets are dropped on i40e PF devices because
when a MAC address is added to a device, packets originating from
that MAC address are dropped.

This patch adds a interface in lib/ethdev to support disabling
source pruning to work around above issue.

Bugzilla ID: 648

Signed-off-by: Ke Zhang <ke1x.zhang@intel.com>
---
 app/test-pmd/cmdline.c         | 77 ++++++++++++++++++++++++++++++++++
 drivers/net/i40e/i40e_ethdev.c | 53 +++++++++++++++++++++++
 lib/ethdev/ethdev_driver.h     |  6 +++
 lib/ethdev/rte_ethdev.c        | 16 +++++++
 lib/ethdev/rte_ethdev.h        | 15 +++++++
 5 files changed, 167 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index cb8c174020..a9602a2ed0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -482,6 +482,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set promisc (port_id|all) (on|off)\n"
 			"    Set the promiscuous mode on port_id, or all.\n\n"
 
+			"set llb (port_id|all) (on|off)\n"
+			"    Set vsi local loopback on port_id, or all.\n\n"
+
 			"set allmulti (port_id|all) (on|off)\n"
 			"    Set the allmulti mode on port_id, or all.\n\n"
 
@@ -5775,6 +5778,78 @@ static cmdline_parse_inst_t cmd_set_promisc_mode_one = {
 	},
 };
 
+/* *** SET VSI LOCAL LOOPBACK *** */
+struct cmd_set_vsi_local_lb_result {
+	cmdline_fixed_string_t set;
+	cmdline_fixed_string_t llb;
+	cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */
+	uint16_t port_num;               /* valid if "allports" argument == 0 */
+	cmdline_fixed_string_t enable;
+};
+
+static void cmd_set_vsi_llb_parsed(void *parsed_result,
+					__rte_unused struct cmdline *cl,
+					void *allports)
+{
+	struct cmd_set_vsi_local_lb_result *res = parsed_result;
+	int enable;
+	portid_t i;
+
+	if (!strcmp(res->enable, "on"))
+		enable = 1;
+	else
+		enable = 0;
+
+	/* all ports */
+	if (allports) {
+		RTE_ETH_FOREACH_DEV(i)
+			rte_eth_dev_enable_local_lb(i, enable);
+	} else {
+		rte_eth_dev_enable_local_lb(res->port_num, enable);
+	}
+}
+
+static cmdline_parse_token_string_t cmd_setllb_set =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_vsi_local_lb_result, set, "set");
+static cmdline_parse_token_string_t cmd_setllb_llb =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_vsi_local_lb_result, llb,
+				 "llb");
+static cmdline_parse_token_string_t cmd_setllb_portall =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_vsi_local_lb_result, port_all,
+				 "all");
+static cmdline_parse_token_num_t cmd_setllb_portnum =
+	TOKEN_NUM_INITIALIZER(struct cmd_set_vsi_local_lb_result, port_num,
+			      RTE_UINT16);
+static cmdline_parse_token_string_t cmd_setllb_enalbe =
+	TOKEN_STRING_INITIALIZER(struct cmd_set_vsi_local_lb_result, enable,
+				 "on#off");
+
+static cmdline_parse_inst_t cmd_set_vsi_enable_all = {
+	.f = cmd_set_vsi_llb_parsed,
+	.data = (void *)1,
+	.help_str = "set llb all on|off: Set vsi local loopback for all ports",
+	.tokens = {
+		(void *)&cmd_setllb_set,
+		(void *)&cmd_setllb_llb,
+		(void *)&cmd_setllb_portall,
+		(void *)&cmd_setllb_enalbe,
+		NULL,
+	},
+};
+
+static cmdline_parse_inst_t cmd_set_vsi_enable_one = {
+	.f = cmd_set_vsi_llb_parsed,
+	.data = (void *)0,
+	.help_str = "set llb <port_id> on|off: Set vsi local loopback on port id",
+	.tokens = {
+		(void *)&cmd_setllb_set,
+		(void *)&cmd_setllb_llb,
+		(void *)&cmd_setllb_portnum,
+		(void *)&cmd_setllb_enalbe,
+		NULL,
+	},
+};
+
 /* *** SET ALLMULTI MODE *** */
 struct cmd_set_allmulti_mode_result {
 	cmdline_fixed_string_t set;
@@ -12866,6 +12941,8 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_show_port_cman_capa,
 	(cmdline_parse_inst_t *)&cmd_show_port_cman_config,
 	(cmdline_parse_inst_t *)&cmd_set_port_cman_config,
+	(cmdline_parse_inst_t *)&cmd_set_vsi_enable_all,
+	(cmdline_parse_inst_t *)&cmd_set_vsi_enable_one,
 	NULL,
 };
 
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7726a89d99..dd07c38f0f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -406,6 +406,7 @@ static void i40e_ethertype_filter_restore(struct i40e_pf *pf);
 static void i40e_tunnel_filter_restore(struct i40e_pf *pf);
 static void i40e_filter_restore(struct i40e_pf *pf);
 static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev);
+static int i40e_enable_pf_local_lb(struct rte_eth_dev *dev, int on);
 
 static const char *const valid_keys[] = {
 	ETH_I40E_FLOATING_VEB_ARG,
@@ -517,6 +518,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.tm_ops_get                   = i40e_tm_ops_get,
 	.tx_done_cleanup              = i40e_tx_done_cleanup,
 	.get_monitor_addr             = i40e_get_monitor_addr,
+	.enable_local_lb              = i40e_enable_pf_local_lb,
 };
 
 /* store statistics names and its offset in stats structure */
@@ -5634,6 +5636,57 @@ i40e_enable_pf_lb(struct i40e_pf *pf)
 			    hw->aq.asq_last_status);
 }
 
+/* i40e_enable_pf_local_lb
+ * @pf: pointer to the pf structure
+ *
+ * allow local loopback on pf
+ */
+static int
+i40e_enable_pf_local_lb(struct rte_eth_dev *dev, int on)
+{
+	struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	struct i40e_vsi_context ctxt;
+	int ret;
+
+	/* Use the FW API if FW >= v5.0 */
+	if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) {
+#ifdef TREX_PATCH
+		/* Most of our customers do not have latest FW */
+		PMD_INIT_LOG(INFO, "FW < v5.0, cannot enable local loopback");
+#else
+		PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable local loopback");
+#endif
+		return I40E_NOT_SUPPORTED;
+	}
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	ctxt.seid = pf->main_vsi_seid;
+	ctxt.pf_num = hw->pf_id;
+	ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "cannot get pf vsi config, err %d, aq_err %d",
+			    ret, hw->aq.asq_last_status);
+		return ret;
+	}
+	ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+	ctxt.info.valid_sections =
+		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+	if (on)
+		ctxt.info.switch_id |=
+			rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB);
+	else
+		ctxt.info.switch_id &=
+			~rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB);
+
+	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+	if (ret)
+		PMD_DRV_LOG(ERR, "update vsi switch failed, aq_err=%d",
+			    hw->aq.asq_last_status);
+
+	return ret;
+}
+
 /* Setup a VSI */
 struct i40e_vsi *
 i40e_vsi_setup(struct i40e_pf *pf,
diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 6a550cfc83..3a11a7fab4 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -668,6 +668,10 @@ typedef int (*eth_get_module_info_t)(struct rte_eth_dev *dev,
 typedef int (*eth_get_module_eeprom_t)(struct rte_eth_dev *dev,
 				       struct rte_dev_eeprom_info *info);
 
+/** @internal Function used to enable/disable the vsi loop back of an Ethernet device. */
+typedef int (*eth_enable_local_lb_t)(struct rte_eth_dev *dev,
+				  int on);
+
 struct rte_flow_ops;
 /**
  * @internal
@@ -1403,6 +1407,8 @@ struct eth_dev_ops {
 	eth_cman_config_set_t cman_config_set;
 	/** Retrieve congestion management configuration */
 	eth_cman_config_get_t cman_config_get;
+	/** Enable/disable the vsi loop back of an Ethernet device */
+	eth_enable_local_lb_t enable_local_lb;
 };
 
 /**
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 5d5e18db1e..3991688e2b 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -6318,6 +6318,22 @@ rte_eth_buffer_split_get_supported_hdr_ptypes(uint16_t port_id, uint32_t *ptypes
 	return j;
 }
 
+int
+rte_eth_dev_enable_local_lb(uint16_t port_id, int on)
+{
+	struct rte_eth_dev *dev;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+
+	if (*dev->dev_ops->enable_local_lb == NULL)
+		return -ENOTSUP;
+
+	ret = (*dev->dev_ops->enable_local_lb)(dev, on);
+	return eth_err(port_id, ret);
+}
+
 RTE_LOG_REGISTER_DEFAULT(rte_eth_dev_logtype, INFO);
 
 RTE_INIT(ethdev_init_telemetry)
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index c129ca1eaf..c4888ebd62 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -3437,6 +3437,21 @@ int rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu);
  */
 int rte_eth_dev_vlan_filter(uint16_t port_id, uint16_t vlan_id, int on);
 
+/**
+ * Enable/Disable local Loopback for VSIs that are used as uplink of a software
+ * (cascaded) VEB, VEPA or Port Virtualizer.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param on
+ *   If > 0, enable local Loopback.
+ *   Otherwise, disable local Loopback.
+ * @return
+ *   - (0) if successful.
+ *   - negative if failed.
+ */
+int rte_eth_dev_enable_local_lb(uint16_t port_id, int on);
+
 /**
  * Enable/Disable hardware VLAN Strip by a Rx queue of an Ethernet device.
  *
-- 
2.25.1


  parent reply	other threads:[~2023-01-09  2:34 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-19  9:04 [dpdk-dev] " Alvin Zhang
2021-10-19  9:38 ` [dpdk-dev] [PATCH v2] " Alvin Zhang
2021-10-20  1:28   ` [dpdk-dev] [PATCH v3] " Alvin Zhang
2022-02-21  8:30     ` Jiang, YuX
2022-02-21  9:35       ` Morten Brørup
2022-12-26  9:03         ` Zhang, Ke1X
2022-12-26 10:26           ` Morten Brørup
2022-12-26 10:27           ` Morten Brørup
2023-01-09  2:20     ` Ke Zhang [this message]
2023-01-09  7:40       ` [PATCH] " Morten Brørup
2023-01-13 12:50       ` Ferruh Yigit
2023-01-30  8:09       ` [PATCH v2] net/i40e: support enabling/disabling " Ke Zhang
2023-01-30  8:41         ` Morten Brørup
2023-01-30  8:58         ` David Marchand
2023-01-31  3:28           ` Zhang, Ke1X
2023-02-01 11:11             ` Thomas Monjalon
2023-02-07  1:40               ` Zhang, Ke1X
2023-02-07  8:35                 ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230109022027.190627-1-ke1x.zhang@intel.com \
    --to=ke1x.zhang@intel.com \
    --cc=Yuying.Zhang@intel.com \
    --cc=beilei.xing@intel.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=mb@smartsharesystems.com \
    --cc=olivier.matz@6wind.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).