i40e/i40evf: Add a workaround to drop all flow control frames
authorAnjali Singhai Jain <anjali.singhai@intel.com>
Thu, 1 Oct 2015 18:37:34 +0000 (14:37 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 23 Oct 2015 11:17:55 +0000 (04:17 -0700)
This patch adds a workaround to drop any flow control frames from being
transmitted from any VSI. FW can still send flow control frames if flow
control is enabled.

With this patch in place a malicious VF cannot send flow control or PFC
packets out on the wire.

Change-ID: I4303b24e98b93066d2767fec24dfe78be591c277
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_prototype.h
drivers/net/ethernet/intel/i40evf/i40e_prototype.h

index c51f2fb9471635ce0c5a5a6c4e1f9493cf89383e..5d533d12a0450ef02d1f4f6f07a8873a217e37ce 100644 (file)
@@ -3828,6 +3828,28 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
        return status;
 }
 
+/**
+ * i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
+ * @hw: pointer to the hw struct
+ * @seid: VSI seid to add ethertype filter from
+ **/
+#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
+void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
+                                                   u16 seid)
+{
+       u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
+                  I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
+                  I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
+       u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
+       i40e_status status;
+
+       status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
+                                                      seid, 0, true, NULL,
+                                                      NULL);
+       if (status)
+               hw_dbg(hw, "Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
+}
+
 /**
  * i40e_aq_alternate_read
  * @hw: pointer to the hardware structure
index cc8c0aeab9bb7961002ead7a1564c4fd2e993d2a..d05254c741d0ae5492da44b629c7169702a4c9b0 100644 (file)
@@ -6837,6 +6837,15 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
        if (pf->flags & I40E_FLAG_MSIX_ENABLED)
                ret = i40e_setup_misc_vector(pf);
 
+       /* Add a filter to drop all Flow control frames from any VSI from being
+        * transmitted. By doing so we stop a malicious VF from sending out
+        * PAUSE or PFC frames and potentially controlling traffic for other
+        * PF/VF VSIs.
+        * The FW can still send Flow control frames if enabled.
+        */
+       i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
+                                                      pf->main_vsi_seid);
+
        /* restart the VSIs that were rebuilt and running before the reset */
        i40e_pf_unquiesce_all_vsi(pf);
 
@@ -10585,6 +10594,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
        pf->hw.phy.phy_types = le32_to_cpu(abilities.phy_type);
 
+       /* Add a filter to drop all Flow control frames from any VSI from being
+        * transmitted. By doing so we stop a malicious VF from sending out
+        * PAUSE or PFC frames and potentially controlling traffic for other
+        * PF/VF VSIs.
+        * The FW can still send Flow control frames if enabled.
+        */
+       i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
+                                                      pf->main_vsi_seid);
+
        /* print a string summarizing features */
        i40e_print_features(pf);
 
index 10bf2ba8bc15bef0e6991e7e86f8a7aa5bd90762..bb9d583e5416fdf469b7853a92ce8c435901bafd 100644 (file)
@@ -322,4 +322,6 @@ i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
                               void *buff, u16 *ret_buff_size,
                               u8 *ret_next_table, u32 *ret_next_index,
                               struct i40e_asq_cmd_details *cmd_details);
+void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
+                                                   u16 vsi_seid);
 #endif /* _I40E_PROTOTYPE_H_ */
index 8ed0edfbc12541ff410ac541ea685313135cc302..cbd9a1b078abf6caaa959218e0b4a4920c414d02 100644 (file)
@@ -101,4 +101,6 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
                                u16 vsi_seid, u16 queue, bool is_add,
                                struct i40e_control_filter_stats *stats,
                                struct i40e_asq_cmd_details *cmd_details);
+void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
+                                                   u16 vsi_seid);
 #endif /* _I40E_PROTOTYPE_H_ */