> On Apr 19, 2023, at 12:24 AM, Ye, MingjinX wrote: > > VRRP advertisement packets are dropped on i40e PF device because > when a MAC address is added to a device, packets originating from > that MAC address are dropped. > This patch fixes the bug by disabling source pruning by default, > and adds a PMD specific API to enable/disable source pruning. > > Bugzilla ID: 648 > > Signed-off-by: Mingjin Ye > --- > v3: The i40e specific commands are moved to > drivers/net/i40e/i40e_testpmd.c. > -- > v4: Modify the commit log. > --- > drivers/net/i40e/i40e_ethdev.c | 43 ++++++++++++++++ > drivers/net/i40e/i40e_ethdev.h | 1 + > drivers/net/i40e/i40e_testpmd.c | 88 +++++++++++++++++++++++++++++++++ > drivers/net/i40e/rte_pmd_i40e.c | 20 ++++++++ > drivers/net/i40e/rte_pmd_i40e.h | 17 +++++++ > drivers/net/i40e/version.map | 1 + > 6 files changed, 170 insertions(+) > > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c > index cb0070f94b..90d8e5a8bc 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -5647,6 +5647,46 @@ i40e_enable_pf_lb(struct i40e_pf *pf) > hw->aq.asq_last_status); > } > > +/* i40e_pf_set_source_prune > + * @pf: pointer to the pf structure > + * @on: Enable/disable source prune > + * > + * set source prune on pf > + */ > +int > +i40e_pf_set_source_prune(struct i40e_pf *pf, int on) > +{ > + struct i40e_hw *hw = I40E_PF_TO_HW(pf); > + struct i40e_vsi_context ctxt; > + int ret; > + > + 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, > @@ -5704,6 +5744,9 @@ i40e_vsi_setup(struct i40e_pf *pf, > } > } > > + /* source prune is disabled to support VRRP in default*/ > + i40e_pf_set_source_prune(pf, 0); > + > vsi = rte_zmalloc("i40e_vsi", sizeof(struct i40e_vsi), 0); > if (!vsi) { > PMD_DRV_LOG(ERR, "Failed to allocate memory for vsi"); > diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h > index 9b806d130e..6f65d5e0ac 100644 > --- a/drivers/net/i40e/i40e_ethdev.h > +++ b/drivers/net/i40e/i40e_ethdev.h > @@ -1430,6 +1430,7 @@ int i40e_pf_calc_configured_queues_num(struct i40e_pf *pf); > int i40e_pf_reset_rss_reta(struct i40e_pf *pf); > int i40e_pf_reset_rss_key(struct i40e_pf *pf); > int i40e_pf_config_rss(struct i40e_pf *pf); > +int i40e_pf_set_source_prune(struct i40e_pf *pf, int on); > int i40e_set_rss_key(struct i40e_vsi *vsi, uint8_t *key, uint8_t key_len); > int i40e_set_rss_lut(struct i40e_vsi *vsi, uint8_t *lut, uint16_t lut_size); > int i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params); > diff --git a/drivers/net/i40e/i40e_testpmd.c b/drivers/net/i40e/i40e_testpmd.c > index 7be9fea5b0..b6ef5d6e42 100644 > --- a/drivers/net/i40e/i40e_testpmd.c > +++ b/drivers/net/i40e/i40e_testpmd.c > @@ -2446,6 +2446,84 @@ static cmdline_parse_inst_t cmd_ptype_mapping_update = { > }, > }; > > +/* *** configure source prune for 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_i40e_set_pf_src_prune(i, enable); > + } else { > + rte_pmd_i40e_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, "i40e_src_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 i40e_src_prune on|off: Set source pruning on 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 i40e_src_prune on|off: Set source pruning on 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 i40e_cmds = { > .commands = { > { > @@ -2592,6 +2670,16 @@ static struct testpmd_driver_commands i40e_cmds = { > " (pctype_id_0[,pctype_id_1]*) (flow_type_id)\n" > " Update a flow type to pctype mapping item on a port\n", > }, > + { > + &cmd_config_src_prune_all, > + "port config all i40e_src_prune (on|off)\n" > + " Set source pruning on pf port all.\n" > + }, > + { > + &cmd_config_src_prune_specific, > + "port config (port_id) i40e_src_prune (on|off)\n" > + " Set source pruning on pf port_id.\n" > + }, > { NULL, NULL }, > }, > }; > diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c > index 35829a1eea..9d39984ea1 100644 > --- a/drivers/net/i40e/rte_pmd_i40e.c > +++ b/drivers/net/i40e/rte_pmd_i40e.c > @@ -3282,3 +3282,23 @@ rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev) > > return 0; > } > + > +int > +rte_pmd_i40e_set_pf_src_prune(uint16_t port, uint8_t on) > +{ > + struct rte_eth_dev *dev; > + struct i40e_pf *pf; > + int ret; > + > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); > + > + dev = &rte_eth_devices[port]; > + > + if (!is_i40e_supported(dev)) > + return -ENOTSUP; > + > + pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); > + > + ret = i40e_pf_set_source_prune(pf, on); > + return ret; > +} > diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h > index 4cb21c3713..a802f989e9 100644 > --- a/drivers/net/i40e/rte_pmd_i40e.h > +++ b/drivers/net/i40e/rte_pmd_i40e.h > @@ -1134,6 +1134,23 @@ __rte_experimental > int > rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev); > > +/** > + * 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_i40e_set_pf_src_prune(uint16_t port, > + uint8_t on); > + > #ifdef __cplusplus > } > #endif > diff --git a/drivers/net/i40e/version.map b/drivers/net/i40e/version.map > index 561db50eac..51e1ac4f06 100644 > --- a/drivers/net/i40e/version.map > +++ b/drivers/net/i40e/version.map > @@ -46,4 +46,5 @@ EXPERIMENTAL { > rte_pmd_i40e_get_fdir_stats; > rte_pmd_i40e_set_gre_key_len; > rte_pmd_i40e_set_switch_dev; > + rte_pmd_i40e_set_pf_src_prune; > }; > — > 2.25.1 > The patch appears to correct the issue reported in bug 648. Tested-by: Matthew Smith >