From patchwork Mon May 28 02:01:10 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qi Zhang X-Patchwork-Id: 40452 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 3C0F337A0; Mon, 28 May 2018 04:00:58 +0200 (CEST) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) by dpdk.org (Postfix) with ESMTP id 1CB17200 for ; Mon, 28 May 2018 04:00:50 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 May 2018 19:00:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,450,1520924400"; d="scan'208";a="43290568" Received: from dpdk51.sh.intel.com ([10.67.110.184]) by fmsmga008.fm.intel.com with ESMTP; 27 May 2018 19:00:48 -0700 From: Qi Zhang To: beilei.xing@intel.com Cc: dev@dpdk.org, helin.zhang@intel.com, liang-min.wang@intel.com, Qi Zhang Date: Mon, 28 May 2018 10:01:10 +0800 Message-Id: <20180528020110.37713-3-qi.z.zhang@intel.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180528020110.37713-1-qi.z.zhang@intel.com> References: <20180528020110.37713-1-qi.z.zhang@intel.com> Subject: [dpdk-dev] [PATCH 2/2] net/i40e: enable VF VLAN antispoof X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Due to hardware limitation, there is no perfect solution to enable VF vlan antispoof, to enable it means lost something else. So the solution is to introduce devarg "support-vf-vlan-antispoof" that turn on the feature to meet customer's specific requirement while no impact on normal case when it is turned off. Below impact is expected when support-vf-vlan-antispoof is turned on: 1. Multi-driver is not supported since some global register is changed in DPDK driver during init which is no expected by kernel driver. 2. Unicast / Multicase promiscuous mode can not be configured separately. So, function rte_pmd_i40e_set_vf_unicast_promics and rte_pmd_i40e_set_vf_multicast_promisc will fail and new funciton rte_pmd_i40e_set_vf_promics is introduced as a coarse-grain API. 3. VLAN anti-spoof and Mac anti-spoof are always enable/disable together. (rte_eth_set_vf_mac_anti_spoof and rte_eth_set_vf_vlan_anti_spoof do the same thing now.) 4. When VLAN/MAC anti-spoof is turned on, vlan tag will be added to vlan promisc table, so in the rx path, mac address match will be ignored, only vlan will be matched. Signed-off-by: Qi Zhang --- doc/guides/nics/i40e.rst | 28 +++++ drivers/net/i40e/i40e_ethdev.c | 99 +++++++++++++---- drivers/net/i40e/i40e_ethdev.h | 1 + drivers/net/i40e/i40e_pf.c | 30 ++++-- drivers/net/i40e/rte_pmd_i40e.c | 171 ++++++++++++++++++++++++++---- drivers/net/i40e/rte_pmd_i40e.h | 22 ++++ drivers/net/i40e/rte_pmd_i40e_version.map | 8 +- 7 files changed, 309 insertions(+), 50 deletions(-) diff --git a/doc/guides/nics/i40e.rst b/doc/guides/nics/i40e.rst index 18549bf5a..ff054f3c4 100644 --- a/doc/guides/nics/i40e.rst +++ b/doc/guides/nics/i40e.rst @@ -124,6 +124,34 @@ Runtime Config Options will switch PF interrupt from IntN to Int0 to avoid interrupt conflict between DPDK and Linux Kernel. +- ``Support VF VLAN anti-spoof`` (default ``disable``) + + This is a work around to enable vlan antispoof on VF to support customer with + this specific requirement, the reason not make it as a default config is: + due to hardware limitation, when turn on this feature, some global register will + be re-write and some device default behaviour will be changed. (see below for + more detail). ``devargs`` parameter ``support-vf-vlan-antispoof`` is introduced, + for example:: + + -w 84:00.0,support-vf-vlan-antispoof=1 + + By default its off, when it turn on, will have below impact: + + Multi-driver is not supported since some global register is changed in DPDK driver + during init which is no expected by kernel driver. + + Unicast / Multicase promiscuous mode can not be configured separately. So, function + ``rte_pmd_i40e_set_vf_unicast_promics`` and ``rte_pmd_i40e_set_vf_multicast_promisc`` + will fail and new funciton rte_pmd_i40e_set_vf_promics is introduced as a coarse-grain + API. + + VLAN anti-spoof and Mac anti-spoof are always enable/disable together. + (``rte_eth_set_vf_mac_anti_spoof`` and ``rte_eth_set_vf_vlan_anti_spoof`` now do the + same thing). + + When VLAN/MAC anti-spoof is turn on, vlan tag will be added to vlan promisc table, so + in the rx path, mac address match will be ignored, only vlan will be matched. + - ``Support VF Port Representor`` (default ``not enabled``) The i40e PF PMD supports the creation of VF port representors for the control diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index f0c17a439..486124dfa 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -327,7 +327,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev, static int i40e_dev_get_dcb_info(struct rte_eth_dev *dev, struct rte_eth_dcb_info *dcb_info); static int i40e_dev_sync_phy_type(struct i40e_hw *hw); -static void i40e_configure_registers(struct i40e_hw *hw); +static void i40e_configure_registers(struct rte_eth_dev *dev); static void i40e_hw_init(struct rte_eth_dev *dev); static int i40e_config_qinq(struct i40e_hw *hw, struct i40e_vsi *vsi); static enum i40e_status_code i40e_aq_del_mirror_rule(struct i40e_hw *hw, @@ -1097,45 +1097,54 @@ i40e_init_queue_region_conf(struct rte_eth_dev *dev) memset(info, 0, sizeof(struct i40e_queue_regions)); } -#define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver" +#define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver" +#define ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF "support-vf-vlan-antispoof" static int -i40e_parse_multi_drv_handler(__rte_unused const char *key, - const char *value, - void *opaque) +i40e_parse_config_handler(__rte_unused const char *key, + const char *value, + void *opaque) { struct i40e_pf *pf; - unsigned long support_multi_driver; + unsigned long flag; char *end; pf = (struct i40e_pf *)opaque; errno = 0; - support_multi_driver = strtoul(value, &end, 10); + flag = strtoul(value, &end, 10); if (errno != 0 || end == value || *end != 0) { PMD_DRV_LOG(WARNING, "Wrong global configuration"); return -(EINVAL); } - if (support_multi_driver == 1 || support_multi_driver == 0) - pf->support_multi_driver = (bool)support_multi_driver; - else - PMD_DRV_LOG(WARNING, "%s must be 1 or 0,", - "enable global configuration by default." - ETH_I40E_SUPPORT_MULTI_DRIVER); + if (flag == 1 || flag == 0) { + if (!strcmp(ETH_I40E_SUPPORT_MULTI_DRIVER, key)) + pf->support_multi_driver = (bool)flag; + else if (!strcmp(ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF, key)) + pf->support_vf_vlan_antispoof = (bool)flag; + } else { + PMD_DRV_LOG(WARNING, "%s must be 1 or 0, use default config 0", + key); + } + return 0; } static int -i40e_support_multi_driver(struct rte_eth_dev *dev) +i40e_parse_device_args(struct rte_eth_dev *dev) { struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); static const char *const valid_keys[] = { - ETH_I40E_SUPPORT_MULTI_DRIVER, NULL}; + ETH_I40E_SUPPORT_MULTI_DRIVER, + ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF, + NULL}; struct rte_kvargs *kvlist; /* Enable global configuration by default */ pf->support_multi_driver = false; + /* vlan antispoof is not supported by default */ + pf->support_vf_vlan_antispoof = false; if (!dev->device->devargs) return 0; @@ -1150,7 +1159,18 @@ i40e_support_multi_driver(struct rte_eth_dev *dev) ETH_I40E_SUPPORT_MULTI_DRIVER); if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER, - i40e_parse_multi_drv_handler, pf) < 0) { + i40e_parse_config_handler, pf) < 0) { + rte_kvargs_free(kvlist); + return -EINVAL; + } + + if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF) > 1) + PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only " + "the first invalid or last valid one is used !", + ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF); + + if (rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF, + i40e_parse_config_handler, pf) < 0) { rte_kvargs_free(kvlist); return -EINVAL; } @@ -1236,8 +1256,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) hw->bus.func = pci_dev->addr.function; hw->adapter_stopped = 0; - /* Check if need to support multi-driver */ - i40e_support_multi_driver(dev); + /* check multi driver and vlan anti-spoof in devargs */ + i40e_parse_device_args(dev); + + /* vf vlan anti spoof is conflict with multi driver support */ + if (pf->support_multi_driver && pf->support_vf_vlan_antispoof) + return -ENOTSUP; /* Make sure all is clean before doing PF reset */ i40e_clear_hw(hw); @@ -1316,7 +1340,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) * registers. Note that the workaround can be removed when it is fixed * in firmware in the future. */ - i40e_configure_registers(hw); + i40e_configure_registers(dev); /* Get hw capabilities */ ret = i40e_get_cap(hw); @@ -2436,6 +2460,13 @@ i40e_dev_promiscuous_enable(struct rte_eth_dev *dev) struct i40e_vsi *vsi = pf->main_vsi; int status; + if (pf->support_vf_vlan_antispoof) { + status = i40e_aq_set_default_vsi(hw, vsi->seid, NULL); + if (status != I40E_SUCCESS) + PMD_DRV_LOG(ERR, "Failed to enable promiscuous"); + return; + } + status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, true, NULL, true); if (status != I40E_SUCCESS) @@ -2456,6 +2487,13 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev) struct i40e_vsi *vsi = pf->main_vsi; int status; + if (pf->support_vf_vlan_antispoof) { + status = i40e_aq_clear_default_vsi(hw, vsi->seid, NULL); + if (status != I40E_SUCCESS) + PMD_DRV_LOG(ERR, "Failed to disable promiscuous"); + return; + } + status = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, false, NULL, true); if (status != I40E_SUCCESS) @@ -10006,8 +10044,11 @@ i40e_dev_sync_phy_type(struct i40e_hw *hw) } static void -i40e_configure_registers(struct i40e_hw *hw) +i40e_configure_registers(struct rte_eth_dev *dev) { + struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + static struct { uint32_t addr; uint64_t val; @@ -10076,6 +10117,21 @@ i40e_configure_registers(struct i40e_hw *hw) PMD_DRV_LOG(DEBUG, "Write 0x%"PRIx64" to the address of " "0x%"PRIx32, reg_table[i].val, reg_table[i].addr); } + + if (pf->support_vf_vlan_antispoof) { + /** + * To enable vlan antispoof, we need write some undocumented + * glboal registers, cast below spell to trigger the magic. + */ + i40e_aq_debug_write_register(hw, 0x00269624, 0xa0C38886, NULL); + i40e_aq_debug_write_register(hw, 0x00269EA4, 0x00003FE0, NULL); + i40e_aq_debug_write_register(hw, 0x002696A4, 0xA0C18886, NULL); + i40e_aq_debug_write_register(hw, 0x00269EE4, 0x0FFF1FFF, NULL); + i40e_aq_debug_write_register(hw, 0x00269F24, 0x00008000, NULL); + i40e_aq_debug_write_register(hw, 0x00269BE8, 0x07000200, NULL); + i40e_aq_debug_write_register(hw, 0x0026CDC8, 0x01010000, NULL); + i40e_aq_debug_write_register(hw, 0x0026CE08, 0x013F0000, NULL); + } } #define I40E_VSI_TSR(_i) (0x00050800 + ((_i) * 4)) @@ -12390,4 +12446,5 @@ i40e_init_log(void) RTE_PMD_REGISTER_PARAM_STRING(net_i40e, QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16" - ETH_I40E_SUPPORT_MULTI_DRIVER "=1"); + ETH_I40E_SUPPORT_MULTI_DRIVER "=1" + ETH_I40E_SUPPORT_VF_VLAN_ANTI_SPOOF "=1"); diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h index 12c0645a7..b06d6051b 100644 --- a/drivers/net/i40e/i40e_ethdev.h +++ b/drivers/net/i40e/i40e_ethdev.h @@ -960,6 +960,7 @@ struct i40e_pf { bool qinq_replace_flag; /* QINQ filter replace is done */ struct i40e_tm_conf tm_conf; bool support_multi_driver; /* 1 - support multiple driver */ + bool support_vf_vlan_antispoof; /* 1 - support vf's vlan antispoof */ /* Dynamic Device Personalization */ bool gtp_support; /* 1 - support GTP-C and GTP-U */ diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c index dd3962d38..cb6dac10a 100644 --- a/drivers/net/i40e/i40e_pf.c +++ b/drivers/net/i40e/i40e_pf.c @@ -1009,15 +1009,31 @@ i40e_pf_host_process_cmd_config_promisc_mode( if (promisc->flags & FLAG_VF_UNICAST_PROMISC) unicast = TRUE; - ret = i40e_aq_set_vsi_unicast_promiscuous(hw, - vf->vsi->seid, unicast, NULL, true); - if (ret != I40E_SUCCESS) - goto send_msg; - if (promisc->flags & FLAG_VF_MULTICAST_PROMISC) multicast = TRUE; - ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid, - multicast, NULL); + + if (vf->pf->support_vf_vlan_antispoof) { + if (unicast && multicast) + ret = i40e_aq_set_default_vsi(hw, vf->vsi->seid, NULL); + else if (!unicast && !multicast) + ret = i40e_aq_clear_default_vsi(hw, + vf->vsi->seid, + NULL); + else + ret = I40E_ERR_DEVICE_NOT_SUPPORTED; + + if (ret != I40E_SUCCESS) + PMD_DRV_LOG(ERR, + "Failed to enable/disable promiscuous"); + } else { + ret = i40e_aq_set_vsi_unicast_promiscuous(hw, + vf->vsi->seid, unicast, NULL, true); + if (ret != I40E_SUCCESS) + goto send_msg; + + ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vf->vsi->seid, + multicast, NULL); + } send_msg: i40e_pf_host_send_msg_to_vf(vf, diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c index e5e4c44ba..171bdc82c 100644 --- a/drivers/net/i40e/rte_pmd_i40e.c +++ b/drivers/net/i40e/rte_pmd_i40e.c @@ -37,36 +37,71 @@ rte_pmd_i40e_ping_vfs(uint16_t port, uint16_t vf) return 0; } -int -rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on) +static int +set_vlan_promisc(struct i40e_hw *hw, + uint16_t seid, + uint16_t vid, + bool enable) { - struct rte_eth_dev *dev; - struct i40e_pf *pf; - struct i40e_vsi *vsi; - struct i40e_hw *hw; - struct i40e_vsi_context ctxt; - int ret; + struct i40e_aq_desc desc; + struct i40e_aqc_set_vsi_promiscuous_modes *cmd = + (struct i40e_aqc_set_vsi_promiscuous_modes *)&desc.params.raw; - RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV); + i40e_fill_default_direct_cmd_desc(&desc, + i40e_aqc_opc_set_vsi_promiscuous_modes); - dev = &rte_eth_devices[port]; + if (enable) + cmd->promiscuous_flags = CPU_TO_LE16(0x8011); - if (!is_i40e_supported(dev)) - return -ENOTSUP; + cmd->valid_flags = CPU_TO_LE16(0x8011); + cmd->seid = CPU_TO_LE16(seid); + cmd->vlan_tag = CPU_TO_LE16(vid | 0x8000); - pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); + return i40e_asq_send_command(hw, &desc, NULL, 0, NULL); +} - if (vf_id >= pf->vf_num || !pf->vfs) { - PMD_DRV_LOG(ERR, "Invalid argument."); - return -EINVAL; - } +static int +set_all_vlan_promisc(struct i40e_vsi *vsi, uint8_t enable) +{ + struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); + uint32_t j, k; + uint16_t vlan_id; + int ret; - vsi = pf->vfs[vf_id].vsi; - if (!vsi) { - PMD_DRV_LOG(ERR, "Invalid VSI."); - return -EINVAL; + for (j = 0; j < I40E_VFTA_SIZE; j++) { + if (!vsi->vfta[j]) + continue; + + for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) { + if (!(vsi->vfta[j] & (1 << k))) + continue; + + vlan_id = j * I40E_UINT32_BIT_SIZE + k; + if (!vlan_id) + continue; + + ret = set_vlan_promisc(hw, vsi->seid, vlan_id, enable); + if (ret != I40E_SUCCESS) { + PMD_DRV_LOG(ERR, + "Failed to set vlan antispoof: vid=%d", + vlan_id); + return ret; + } + } } + return I40E_SUCCESS; +} + +static int +_i40e_set_vf_mac_anti_spoof(struct i40e_pf *pf, + struct i40e_vsi *vsi, + uint8_t on) +{ + struct i40e_hw *hw; + struct i40e_vsi_context ctxt; + int ret; + /* Check if it has been already on or off */ if (vsi->info.valid_sections & rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SECURITY_VALID)) { @@ -88,6 +123,11 @@ rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on) else vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK; + if (pf->support_vf_vlan_antispoof) { + vsi->vlan_anti_spoof_on = on; + set_all_vlan_promisc(vsi, on); + } + memset(&ctxt, 0, sizeof(ctxt)); rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info)); ctxt.seid = vsi->seid; @@ -103,6 +143,36 @@ rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on) } int +rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on) +{ + struct rte_eth_dev *dev; + struct i40e_pf *pf; + struct i40e_vsi *vsi; + + 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); + + if (vf_id >= pf->vf_num || !pf->vfs) { + PMD_DRV_LOG(ERR, "Invalid argument."); + return -EINVAL; + } + + vsi = pf->vfs[vf_id].vsi; + if (!vsi) { + PMD_DRV_LOG(ERR, "Invalid VSI."); + return -EINVAL; + } + + return _i40e_set_vf_mac_anti_spoof(pf, vsi, on); +} + +int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on) { struct rte_eth_dev *dev; @@ -132,6 +202,9 @@ rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on) return -EINVAL; } + if (pf->support_vf_vlan_antispoof) + return _i40e_set_vf_mac_anti_spoof(pf, vsi, on); + /* Check if it has been already on or off */ if (vsi->vlan_anti_spoof_on == on) return 0; /* already on or off */ @@ -384,6 +457,53 @@ rte_pmd_i40e_set_tx_loopback(uint16_t port, uint8_t on) } int +rte_pmd_i40e_set_vf_promisc(uint16_t port, uint16_t vf_id, uint8_t on) +{ + struct rte_eth_dev *dev; + struct i40e_pf *pf; + struct i40e_vsi *vsi; + struct i40e_hw *hw; + 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); + + if (vf_id >= pf->vf_num || !pf->vfs) { + PMD_DRV_LOG(ERR, "Invalid argument."); + return -EINVAL; + } + + vsi = pf->vfs[vf_id].vsi; + if (!vsi) { + PMD_DRV_LOG(ERR, "Invalid VSI."); + return -EINVAL; + } + + if (!pf->support_vf_vlan_antispoof) + return -ENOTSUP; + + hw = I40E_VSI_TO_HW(vsi); + + if (on) + ret = i40e_aq_set_default_vsi(hw, vsi->seid, NULL); + else + ret = i40e_aq_clear_default_vsi(hw, vsi->seid, NULL); + + if (ret != I40E_SUCCESS) { + ret = -ENOTSUP; + PMD_DRV_LOG(ERR, "Failed to set promiscuous mode"); + } + + return ret; +} + +int rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on) { struct rte_eth_dev *dev; @@ -412,6 +532,9 @@ rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on) return -EINVAL; } + if (pf->support_vf_vlan_antispoof) + return -ENOTSUP; + hw = I40E_VSI_TO_HW(vsi); ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid, @@ -453,6 +576,9 @@ rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on) return -EINVAL; } + if (pf->support_vf_vlan_antispoof) + return -ENOTSUP; + hw = I40E_VSI_TO_HW(vsi); ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, @@ -840,6 +966,9 @@ int rte_pmd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id, ret = i40e_vsi_add_vlan(vsi, vlan_id); else ret = i40e_vsi_delete_vlan(vsi, vlan_id); + if (vsi->vlan_anti_spoof_on) + ret = set_vlan_promisc(hw, vsi->seid, + vlan_id, on); } } diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h index be4a6024a..9e99d60b4 100644 --- a/drivers/net/i40e/rte_pmd_i40e.h +++ b/drivers/net/i40e/rte_pmd_i40e.h @@ -395,6 +395,26 @@ int rte_pmd_i40e_set_tx_loopback(uint16_t port, uint8_t on); /** + * Enable/Disable VF promiscuous mode. + * + * @param port + * The port identifier of the Ethernet device. + * @param vf_id + * VF on which to set. + * @param on + * 1 - Enable. + * 0 - Disable. + * @return + * - (0) if successful. + * - (-ENODEV) if *port* invalid. + * - (-EINVAL) if bad parameter. + * - (-ENOTSUP) if support-vf-anti-spoof is off. + */ +int rte_pmd_i40e_set_vf_promisc(uint16_t port, + uint16_t vf_id, + uint8_t on); + +/** * Enable/Disable VF unicast promiscuous mode. * * @param port @@ -408,6 +428,7 @@ int rte_pmd_i40e_set_tx_loopback(uint16_t port, * - (0) if successful. * - (-ENODEV) if *port* invalid. * - (-EINVAL) if bad parameter. + * - (-ENOTSUP) if support-vf-anti-spoof is on. */ int rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, @@ -427,6 +448,7 @@ int rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, * - (0) if successful. * - (-ENODEV) if *port* invalid. * - (-EINVAL) if bad parameter. + * - (-ENOTSUP) if support-vf-anti-spoof is on. */ int rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map index cccd5768c..3df095c73 100644 --- a/drivers/net/i40e/rte_pmd_i40e_version.map +++ b/drivers/net/i40e/rte_pmd_i40e_version.map @@ -64,4 +64,10 @@ DPDK_18.02 { rte_pmd_i40e_inset_get; rte_pmd_i40e_inset_set; -} DPDK_17.11; \ No newline at end of file +} DPDK_17.11; + +DPDK_18.08 { + global: + + rte_pmd_i40e_set_vf_promisc; +} DPDK_18.2;