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 devarg to support disabling source pruning to work around above issue. Signed-off-by: Alvin Zhang <alvinx.zh...@intel.com> --- doc/guides/nics/i40e.rst | 9 ++++++ drivers/net/i40e/i40e_ethdev.c | 65 ++++++++++++++++++++++++++++++++++++++++++ drivers/net/i40e/i40e_ethdev.h | 1 + 3 files changed, 75 insertions(+) diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst index ef91b3a..1089a3a 100644 --- a/doc/guides/nics/i40e.rst +++ b/doc/guides/nics/i40e.rst @@ -236,6 +236,15 @@ Runtime Config Options -a 84:00.0,vf_msg_cfg=80@120:180 +- ``Disable source pruning on PF`` (default ``not disabled``) + + When a MAC address is added to a device, packets originating from that MAC + address will be dropped for source pruning. To disable source pruning on PF + we can add ``devargs`` parameter ``disable_source_pruning=[0,1]`` and set its + value to 1, for example:: + + -a 84:00.0,disable_source_pruning=1 + Vector RX Pre-conditions ~~~~~~~~~~~~~~~~~~~~~~~~ For Vector RX it is assumed that the number of descriptor rings will be a power diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 1fc3d89..3722e87 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -47,6 +47,7 @@ #define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver" #define ETH_I40E_QUEUE_NUM_PER_VF_ARG "queue-num-per-vf" #define ETH_I40E_VF_MSG_CFG "vf_msg_cfg" +#define ETH_I40E_DISABLE_SOURCE_PRUNING_ARG "disable_source_pruning" #define I40E_CLEAR_PXE_WAIT_MS 200 #define I40E_VSI_TSR_QINQ_STRIP 0x4010 @@ -411,6 +412,7 @@ static int i40e_sw_tunnel_filter_insert(struct i40e_pf *pf, ETH_I40E_SUPPORT_MULTI_DRIVER, ETH_I40E_QUEUE_NUM_PER_VF_ARG, ETH_I40E_VF_MSG_CFG, + ETH_I40E_DISABLE_SOURCE_PRUNING_ARG, NULL}; static const struct rte_pci_id pci_id_i40e_map[] = { @@ -1368,6 +1370,23 @@ static inline void i40e_clear_automask(struct i40e_pf *pf) } static int +i40e_parse_bool(__rte_unused const char *key, const char *value, void *opaque) +{ + char *end; + unsigned long i; + + errno = 0; + i = strtoul(value, &end, 10); + if (errno != 0 || end == value || *end != 0 || i > 1) { + PMD_DRV_LOG(ERR, "Wrong bool value: %s", value); + return -EINVAL; + } + + *(bool *)opaque = (bool)i; + return 0; +} + +static int i40e_parse_vf_msg_config(struct rte_eth_dev *dev, struct i40e_vf_msg_cfg *msg_cfg) { @@ -1404,6 +1423,42 @@ static inline void i40e_clear_automask(struct i40e_pf *pf) return ret; } +static int +i40e_parse_source_pruning_config(struct rte_eth_dev *dev) +{ + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct rte_kvargs *kvlist; + int kvargs_count; + int ret = -EINVAL; + + if (!dev->device->devargs) + return 0; + + kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys); + if (!kvlist) + return 0; + + kvargs_count = rte_kvargs_count(kvlist, + ETH_I40E_DISABLE_SOURCE_PRUNING_ARG); + if (kvargs_count > 1) { + PMD_DRV_LOG(ERR, "More than one argument \"%s\"!", + ETH_I40E_DISABLE_SOURCE_PRUNING_ARG); + goto free_end; + } + + if (kvargs_count && + rte_kvargs_process(kvlist, ETH_I40E_DISABLE_SOURCE_PRUNING_ARG, + i40e_parse_bool, + &pf->disable_source_pruning) < 0) + goto free_end; + + ret = 0; + +free_end: + rte_kvargs_free(kvlist); + return ret; +} + #define I40E_ALARM_INTERVAL 50000 /* us */ static int @@ -1487,6 +1542,10 @@ static inline void i40e_clear_automask(struct i40e_pf *pf) /* Check if need to support multi-driver */ i40e_support_multi_driver(dev); + ret = i40e_parse_source_pruning_config(dev); + if (ret) + return ret; + /* Make sure all is clean before doing PF reset */ i40e_clear_hw(hw); @@ -5812,6 +5871,12 @@ struct i40e_vsi * ctxt.pf_num = hw->pf_id; ctxt.uplink_seid = vsi->uplink_seid; ctxt.vf_num = 0; + if (pf->disable_source_pruning) { + ctxt.info.valid_sections |= + cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID); + ctxt.info.switch_id |= + cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_LOCAL_LB); + } /* Update VSI parameters */ ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL); diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 8a68b36..b441153 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -1171,6 +1171,7 @@ struct i40e_pf { bool dport_replace_flag; /* Destination port replace is done */ struct i40e_tm_conf tm_conf; bool support_multi_driver; /* 1 - support multiple driver */ + bool disable_source_pruning; /* 1 - disable source pruning */ /* Dynamic Device Personalization */ bool gtp_support; /* 1 - support GTP-C and GTP-U */ -- 1.8.3.1