[dpdk-dev] i40e: workaround for Security issue in SR-IOV mode

Message ID 1443170678-7249-1-git-send-email-jingjing.wu@intel.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Jingjing Wu Sept. 25, 2015, 8:44 a.m. UTC
  In SR-IOV mode a VF sending LFC or PFC would throttle the entire port.
The workaround is to add a filter to drop pause frames from VFs from
sending pause frames.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
  

Comments

Vladislav Zolotarov Sept. 25, 2015, 12:28 p.m. UTC | #1
On Sep 25, 2015 11:44 AM, "Jingjing Wu" <jingjing.wu@intel.com> wrote:
>
> In SR-IOV mode a VF sending LFC or PFC would throttle the entire port.
> The workaround is to add a filter to drop pause frames from VFs from
> sending pause frames.

This is a very strange approach - this would silently disable the Tx FC
while a user would think it's enabled. Wouldn't the right approach be to
let the user decide weather to enable this feature or even better - allow
PF to disable this feature in the VF?

>
> Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
> ---
>  drivers/net/i40e/i40e_ethdev.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>
> diff --git a/drivers/net/i40e/i40e_ethdev.c
b/drivers/net/i40e/i40e_ethdev.c
> index 2dd9fdc..6cc2172 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -382,6 +382,30 @@ static inline void i40e_flex_payload_reg_init(struct
i40e_hw *hw)
>         I40E_WRITE_REG(hw, I40E_GLQF_PIT(17), 0x00007440);
>  }
>
> +#define I40E_FLOW_CONTROL_ETHERTYPE  0x8808
> +
> +/*
> + * Add a ethertype filter to drop all flow control frames transimited
> + * from VSIs.
> +*/
> +static void
> +i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
> +{
> +       struct i40e_hw *hw = I40E_PF_TO_HW(pf);
> +       uint16_t flags = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
> +                       I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
> +                       I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
> +       int ret;
> +
> +       ret = i40e_aq_add_rem_control_packet_filter(hw, NULL,
> +                               I40E_FLOW_CONTROL_ETHERTYPE, flags,
> +                               pf->main_vsi_seid, 0,
> +                               TRUE, NULL, NULL);
> +       if (ret)
> +               PMD_INIT_LOG(ERR, "Failed to add filter to drop flow
control "
> +                                 " frames from VSIs.");
> +}
> +
>  static int
>  eth_i40e_dev_init(struct rte_eth_dev *dev)
>  {
> @@ -584,6 +608,12 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
>
>         /* enable uio intr after callback register */
>         rte_intr_enable(&(pci_dev->intr_handle));
> +       /*
> +        * Add a ethertype filter to drop all flow control frames
transimited
> +        * from VSIs. This is used to workaround the issue -- in SR-IOV
mode
> +        * where a VF sending LFC or PFC would throttle the entire port.
> +        */
> +       i40e_add_tx_flow_control_drop_filter(pf);
>
>         /* initialize mirror rule list */
>         TAILQ_INIT(&pf->mirror_list);
> --
> 2.4.0
>
  
Jingjing Wu Oct. 8, 2015, 2:17 a.m. UTC | #2
>>

>> In SR-IOV mode a VF sending LFC or PFC would throttle the entire port.

>> The workaround is to add a filter to drop pause frames from VFs from

>> sending pause frames.

>This is a very strange approach - this would silently disable the Tx FC while a user would think it's enabled. Wouldn't the right approach be to let the user decide weather to enable this feature or even better - allow PF to disable this feature in the VF? 


So, even we let VF sending Tx, it does not make sense at all.  As my understanding, Flow control is used for full-duplex point-to-point connections. How about VF? What is its peer for the point-to-point connect? So if we enable it, it will be a security risk if attacker sends FC on VFs. 

Thanks
Jingjing
  
Vladislav Zolotarov Oct. 8, 2015, 2:53 p.m. UTC | #3
On 10/08/15 05:17, Wu, Jingjing wrote:
>>> In SR-IOV mode a VF sending LFC or PFC would throttle the entire port.
>>> The workaround is to add a filter to drop pause frames from VFs from
>>> sending pause frames.
>> This is a very strange approach - this would silently disable the Tx FC while a user would think it's enabled. Wouldn't the right approach be to let the user decide weather to enable this feature or even better - allow PF to disable this feature in the VF?
> So, even we let VF sending Tx, it does not make sense at all.  As my understanding, Flow control is used for full-duplex point-to-point connections. How about VF? What is its peer for the point-to-point connect? So if we enable it, it will be a security risk if attacker sends FC on VFs.

I'll start start from the end: AFAIR FC frames are not forwarded, they 
only throttle the sender on the side that receives the PAUSE frame. 
Therefore it's quite trickery to create a PAUSE-frame attack as I see it 
- u'll have to hack the switch next to the host u attack. So, let's drop 
the "security" risk argument for now... ;)

Regarding VF sending FC frames being useless: this depends on the setup 
demands. If drops in the VF on the MAC level are not acceptable then it 
makes the whole lot of sense, just like it makes sense with a PF in the 
same situation. Of course, as a result the whole (switch) link will be 
throttled however that's the price to pay and System Administrators 
should be well aware of it.

If, on the other hand, System Administrator doesn't want FC it may just 
not enable it on this VF. If memory serves me well FC is disabled by 
default in DPDK.

thanks,
vlad

>
> Thanks
> Jingjing
  

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 2dd9fdc..6cc2172 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -382,6 +382,30 @@  static inline void i40e_flex_payload_reg_init(struct i40e_hw *hw)
 	I40E_WRITE_REG(hw, I40E_GLQF_PIT(17), 0x00007440);
 }
 
+#define I40E_FLOW_CONTROL_ETHERTYPE  0x8808
+
+/*
+ * Add a ethertype filter to drop all flow control frames transimited
+ * from VSIs.
+*/
+static void
+i40e_add_tx_flow_control_drop_filter(struct i40e_pf *pf)
+{
+	struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+	uint16_t flags = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
+			I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
+			I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
+	int ret;
+
+	ret = i40e_aq_add_rem_control_packet_filter(hw, NULL,
+				I40E_FLOW_CONTROL_ETHERTYPE, flags,
+				pf->main_vsi_seid, 0,
+				TRUE, NULL, NULL);
+	if (ret)
+		PMD_INIT_LOG(ERR, "Failed to add filter to drop flow control "
+				  " frames from VSIs.");
+}
+
 static int
 eth_i40e_dev_init(struct rte_eth_dev *dev)
 {
@@ -584,6 +608,12 @@  eth_i40e_dev_init(struct rte_eth_dev *dev)
 
 	/* enable uio intr after callback register */
 	rte_intr_enable(&(pci_dev->intr_handle));
+	/*
+	 * Add a ethertype filter to drop all flow control frames transimited
+	 * from VSIs. This is used to workaround the issue -- in SR-IOV mode
+	 * where a VF sending LFC or PFC would throttle the entire port.
+	 */
+	i40e_add_tx_flow_control_drop_filter(pf);
 
 	/* initialize mirror rule list */
 	TAILQ_INIT(&pf->mirror_list);