<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 19, 2023, at 12:24 AM, Ye, MingjinX <<a href="mailto:mingjinx.ye@intel.com" class="">mingjinx.ye@intel.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">VRRP advertisement packets are dropped on i40e PF device because<br class="">when a MAC address is added to a device, packets originating from<br class="">that MAC address are dropped.<br class="">This patch fixes the bug by disabling source pruning by default,<br class="">and adds a PMD specific API to enable/disable source pruning.<br class=""><br class="">Bugzilla ID: 648<br class=""><br class="">Signed-off-by: Mingjin Ye <<a href="mailto:mingjinx.ye@intel.com" class="">mingjinx.ye@intel.com</a>><br class="">---<br class="">v3: The i40e specific commands are moved to<br class="">drivers/net/i40e/i40e_testpmd.c.<br class="">--<br class="">v4: Modify the commit log.<br class="">---<br class=""> drivers/net/i40e/i40e_ethdev.c  | 43 ++++++++++++++++<br class=""> drivers/net/i40e/i40e_ethdev.h  |  1 +<br class=""> drivers/net/i40e/i40e_testpmd.c | 88 +++++++++++++++++++++++++++++++++<br class=""> drivers/net/i40e/rte_pmd_i40e.c | 20 ++++++++<br class=""> drivers/net/i40e/rte_pmd_i40e.h | 17 +++++++<br class=""> drivers/net/i40e/version.map    |  1 +<br class=""> 6 files changed, 170 insertions(+)<br class=""><br class="">diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c<br class="">index cb0070f94b..90d8e5a8bc 100644<br class="">--- a/drivers/net/i40e/i40e_ethdev.c<br class="">+++ b/drivers/net/i40e/i40e_ethdev.c<br class="">@@ -5647,6 +5647,46 @@ i40e_enable_pf_lb(struct i40e_pf *pf)<br class="">                            hw->aq.asq_last_status);<br class=""> }<br class=""><br class="">+/* i40e_pf_set_source_prune<br class="">+ * @pf: pointer to the pf structure<br class="">+ * @on: Enable/disable source prune<br class="">+ *<br class="">+ * set source prune on pf<br class="">+ */<br class="">+int<br class="">+i40e_pf_set_source_prune(struct i40e_pf *pf, int on)<br class="">+{<br class="">+       struct i40e_hw *hw = I40E_PF_TO_HW(pf);<br class="">+       struct i40e_vsi_context ctxt;<br class="">+       int ret;<br class="">+<br class="">+       memset(&ctxt, 0, sizeof(ctxt));<br class="">+       ctxt.seid = pf->main_vsi_seid;<br class="">+       ctxt.pf_num = hw->pf_id;<br class="">+       ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL);<br class="">+       if (ret) {<br class="">+               PMD_DRV_LOG(ERR, "cannot get pf vsi config, err %d, aq_err %d",<br class="">+                           ret, hw->aq.asq_last_status);<br class="">+               return ret;<br class="">+       }<br class="">+       ctxt.flags = I40E_AQ_VSI_TYPE_PF;<br class="">+       ctxt.info.valid_sections =<br class="">+               rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);<br class="">+       if (on)<br class="">+               ctxt.info.switch_id &=<br class="">+                       ~rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB);<br class="">+       else<br class="">+               ctxt.info.switch_id |=<br class="">+                       rte_cpu_to_le_16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB);<br class="">+<br class="">+       ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);<br class="">+       if (ret)<br class="">+               PMD_DRV_LOG(ERR, "update vsi switch failed, aq_err=%d",<br class="">+                           hw->aq.asq_last_status);<br class="">+<br class="">+       return ret;<br class="">+}<br class="">+<br class=""> /* Setup a VSI */<br class=""> struct i40e_vsi *<br class=""> i40e_vsi_setup(struct i40e_pf *pf,<br class="">@@ -5704,6 +5744,9 @@ i40e_vsi_setup(struct i40e_pf *pf,<br class="">                }<br class="">        }<br class=""><br class="">+       /* source prune is disabled to support VRRP in default*/<br class="">+       i40e_pf_set_source_prune(pf, 0);<br class="">+<br class="">        vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0);<br class="">        if (!vsi) {<br class="">                PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi");<br class="">diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h<br class="">index 9b806d130e..6f65d5e0ac 100644<br class="">--- a/drivers/net/i40e/i40e_ethdev.h<br class="">+++ b/drivers/net/i40e/i40e_ethdev.h<br class="">@@ -1430,6 +1430,7 @@ int i40e_pf_calc_configured_queues_num(struct i40e_pf *pf);<br class=""> int i40e_pf_reset_rss_reta(struct i40e_pf *pf);<br class=""> int i40e_pf_reset_rss_key(struct i40e_pf *pf);<br class=""> int i40e_pf_config_rss(struct i40e_pf *pf);<br class="">+int i40e_pf_set_source_prune(struct i40e_pf *pf, int on);<br class=""> int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len);<br class=""> int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size);<br class=""> int i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params);<br class="">diff --git a/drivers/net/i40e/i40e_testpmd.c b/drivers/net/i40e/i40e_testpmd.c<br class="">index 7be9fea5b0..b6ef5d6e42 100644<br class="">--- a/drivers/net/i40e/i40e_testpmd.c<br class="">+++ b/drivers/net/i40e/i40e_testpmd.c<br class="">@@ -2446,6 +2446,84 @@ static cmdline_parse_inst_t cmd_ptype_mapping_update = {<br class="">        },<br class=""> };<br class=""><br class="">+/* *** configure source prune for port *** */<br class="">+struct cmd_config_src_prune_result {<br class="">+       cmdline_fixed_string_t port;<br class="">+       cmdline_fixed_string_t keyword;<br class="">+       cmdline_fixed_string_t port_all; /* valid if "allports" argument == 1 */<br class="">+       uint16_t port_id;                /* valid if "allports" argument == 0 */<br class="">+       cmdline_fixed_string_t item;<br class="">+       cmdline_fixed_string_t enable;<br class="">+};<br class="">+<br class="">+static void cmd_config_pf_src_prune_parsed(void *parsed_result,<br class="">+                                       __rte_unused struct cmdline *cl,<br class="">+                                       void *allports)<br class="">+{<br class="">+       struct cmd_config_src_prune_result *res = parsed_result;<br class="">+       uint8_t enable;<br class="">+       uint16_t i;<br class="">+<br class="">+       if (!strcmp(res->enable, "on"))<br class="">+               enable = 1;<br class="">+       else<br class="">+               enable = 0;<br class="">+<br class="">+       /* all ports */<br class="">+       if (allports) {<br class="">+               RTE_ETH_FOREACH_DEV(i)<br class="">+                       rte_pmd_i40e_set_pf_src_prune(i, enable);<br class="">+       } else {<br class="">+               rte_pmd_i40e_set_pf_src_prune(res->port_id, enable);<br class="">+       }<br class="">+}<br class="">+<br class="">+static cmdline_parse_token_string_t cmd_config_src_prune_port =<br class="">+       TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port, "port");<br class="">+static cmdline_parse_token_string_t cmd_config_src_prune_keyword =<br class="">+       TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, keyword,<br class="">+                                "config");<br class="">+static cmdline_parse_token_string_t cmd_config_src_prune_portall =<br class="">+       TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, port_all,<br class="">+                                "all");<br class="">+static cmdline_parse_token_num_t cmd_config_src_prune_port_id =<br class="">+       TOKEN_NUM_INITIALIZER(struct cmd_config_src_prune_result, port_id,<br class="">+                             RTE_UINT16);<br class="">+static cmdline_parse_token_string_t cmd_config_src_prune_item =<br class="">+       TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result,<br class="">+                       item, "i40e_src_prune");<br class="">+static cmdline_parse_token_string_t cmd_config_src_prune_enable =<br class="">+       TOKEN_STRING_INITIALIZER(struct cmd_config_src_prune_result, enable,<br class="">+                                "on#off");<br class="">+<br class="">+static cmdline_parse_inst_t cmd_config_src_prune_all = {<br class="">+       .f = cmd_config_pf_src_prune_parsed,<br class="">+       .data = (void *)1,<br class="">+       .help_str = "port config all i40e_src_prune on|off: Set source pruning on all pf ports.",<br class="">+       .tokens = {<br class="">+               (void *)&cmd_config_src_prune_port,<br class="">+               (void *)&cmd_config_src_prune_keyword,<br class="">+               (void *)&cmd_config_src_prune_portall,<br class="">+               (void *)&cmd_config_src_prune_item,<br class="">+               (void *)&cmd_config_src_prune_enable,<br class="">+               NULL,<br class="">+       },<br class="">+};<br class="">+<br class="">+static cmdline_parse_inst_t cmd_config_src_prune_specific = {<br class="">+       .f = cmd_config_pf_src_prune_parsed,<br class="">+       .data = (void *)0,<br class="">+       .help_str = "port config <port_id> i40e_src_prune on|off: Set source pruning on specific pf port.",<br class="">+       .tokens = {<br class="">+               (void *)&cmd_config_src_prune_port,<br class="">+               (void *)&cmd_config_src_prune_keyword,<br class="">+               (void *)&cmd_config_src_prune_port_id,<br class="">+               (void *)&cmd_config_src_prune_item,<br class="">+               (void *)&cmd_config_src_prune_enable,<br class="">+               NULL,<br class="">+       },<br class="">+};<br class="">+<br class=""> static struct testpmd_driver_commands i40e_cmds = {<br class="">        .commands = {<br class="">        {<br class="">@@ -2592,6 +2670,16 @@ static struct testpmd_driver_commands i40e_cmds = {<br class="">                " (pctype_id_0[,pctype_id_1]*) (flow_type_id)\n"<br class="">                "    Update a flow type to pctype mapping item on a port\n",<br class="">        },<br class="">+       {<br class="">+               &cmd_config_src_prune_all,<br class="">+               "port config all i40e_src_prune (on|off)\n"<br class="">+               "    Set source pruning on pf port all.\n"<br class="">+       },<br class="">+       {<br class="">+               &cmd_config_src_prune_specific,<br class="">+               "port config (port_id) i40e_src_prune (on|off)\n"<br class="">+               "    Set source pruning on pf port_id.\n"<br class="">+       },<br class="">        { NULL, NULL },<br class="">        },<br class=""> };<br class="">diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c<br class="">index 35829a1eea..9d39984ea1 100644<br class="">--- a/drivers/net/i40e/rte_pmd_i40e.c<br class="">+++ b/drivers/net/i40e/rte_pmd_i40e.c<br class="">@@ -3282,3 +3282,23 @@ rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev)<br class=""><br class="">        return 0;<br class=""> }<br class="">+<br class="">+int<br class="">+rte_pmd_i40e_set_pf_src_prune(uint16_t port, uint8_t on)<br class="">+{<br class="">+       struct rte_eth_dev *dev;<br class="">+       struct i40e_pf *pf;<br class="">+       int ret;<br class="">+<br class="">+       RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);<br class="">+<br class="">+       dev = &rte_eth_devices[port];<br class="">+<br class="">+       if (!is_i40e_supported(dev))<br class="">+               return -ENOTSUP;<br class="">+<br class="">+       pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);<br class="">+<br class="">+       ret = i40e_pf_set_source_prune(pf, on);<br class="">+       return ret;<br class="">+}<br class="">diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h<br class="">index 4cb21c3713..a802f989e9 100644<br class="">--- a/drivers/net/i40e/rte_pmd_i40e.h<br class="">+++ b/drivers/net/i40e/rte_pmd_i40e.h<br class="">@@ -1134,6 +1134,23 @@ __rte_experimental<br class=""> int<br class=""> rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev);<br class=""><br class="">+/**<br class="">+ * Enable/Disable source prune on all the PF.<br class="">+ *<br class="">+ * @param port<br class="">+ *    The port identifier of the Ethernet device.<br class="">+ * @param on<br class="">+ *    1 - Enable source prune.<br class="">+ *    0 - Disable source prune.<br class="">+ * @return<br class="">+ *   - (0) if successful.<br class="">+ *   - (-ENODEV) if *port* invalid.<br class="">+ *   - (-EINVAL) if bad parameter.<br class="">+ */<br class="">+__rte_experimental<br class="">+int rte_pmd_i40e_set_pf_src_prune(uint16_t port,<br class="">+                                uint8_t on);<br class="">+<br class=""> #ifdef __cplusplus<br class=""> }<br class=""> #endif<br class="">diff --git a/drivers/net/i40e/version.map b/drivers/net/i40e/version.map<br class="">index 561db50eac..51e1ac4f06 100644<br class="">--- a/drivers/net/i40e/version.map<br class="">+++ b/drivers/net/i40e/version.map<br class="">@@ -46,4 +46,5 @@ EXPERIMENTAL {<br class="">        rte_pmd_i40e_get_fdir_stats;<br class="">        rte_pmd_i40e_set_gre_key_len;<br class="">        rte_pmd_i40e_set_switch_dev;<br class="">+       rte_pmd_i40e_set_pf_src_prune;<br class=""> };<br class="">—<br class="">2.25.1<br class=""><br class=""></div></div></blockquote><br class=""></div><div>The patch appears to correct the issue reported in bug 648.</div><div><br class=""></div><div>Tested-by: Matthew Smith <<a href="mailto:mgsmith@netgate.com" class="">mgsmith@netgate.com</a>></div><div><br class=""></div></body></html>