Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ice: Add function to program ethertype based filter rule on VSIs

This patch adds function to program VSI with ethertype based filter rule,
so that all flow control frames would be disallowed from being transmitted
to the client, in order to prevent malicious VSI, especially VF from
sending out PAUSE or PFC frames, and then control other VSIs traffic.

Signed-off-by: Akeem G Abodunrin <akeem.g.abodunrin@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Akeem G Abodunrin and committed by
Jeff Kirsher
d95276ce 8f529ff9

+120
+2
drivers/net/ethernet/intel/ice/ice.h
··· 255 255 256 256 s16 vf_id; /* VF ID for SR-IOV VSIs */ 257 257 258 + u16 ethtype; /* Ethernet protocol for pause frame */ 259 + 258 260 /* RSS config */ 259 261 u16 rss_table_size; /* HW RSS table size */ 260 262 u16 rss_size; /* Allocated RSS queues */
+55
drivers/net/ethernet/intel/ice/ice_lib.c
··· 2251 2251 } 2252 2252 2253 2253 /** 2254 + * ice_vsi_add_rem_eth_mac - Program VSI ethertype based filter with rule 2255 + * @vsi: the VSI being configured 2256 + * @add_rule: boolean value to add or remove ethertype filter rule 2257 + */ 2258 + static void 2259 + ice_vsi_add_rem_eth_mac(struct ice_vsi *vsi, bool add_rule) 2260 + { 2261 + struct ice_fltr_list_entry *list; 2262 + struct ice_pf *pf = vsi->back; 2263 + LIST_HEAD(tmp_add_list); 2264 + enum ice_status status; 2265 + 2266 + list = devm_kzalloc(&pf->pdev->dev, sizeof(*list), GFP_KERNEL); 2267 + if (!list) 2268 + return; 2269 + 2270 + list->fltr_info.lkup_type = ICE_SW_LKUP_ETHERTYPE; 2271 + list->fltr_info.fltr_act = ICE_DROP_PACKET; 2272 + list->fltr_info.flag = ICE_FLTR_TX; 2273 + list->fltr_info.src_id = ICE_SRC_ID_VSI; 2274 + list->fltr_info.vsi_handle = vsi->idx; 2275 + list->fltr_info.l_data.ethertype_mac.ethertype = vsi->ethtype; 2276 + 2277 + INIT_LIST_HEAD(&list->list_entry); 2278 + list_add(&list->list_entry, &tmp_add_list); 2279 + 2280 + if (add_rule) 2281 + status = ice_add_eth_mac(&pf->hw, &tmp_add_list); 2282 + else 2283 + status = ice_remove_eth_mac(&pf->hw, &tmp_add_list); 2284 + 2285 + if (status) 2286 + dev_err(&pf->pdev->dev, 2287 + "Failure Adding or Removing Ethertype on VSI %i error: %d\n", 2288 + vsi->vsi_num, status); 2289 + 2290 + ice_free_fltr_list(&pf->pdev->dev, &tmp_add_list); 2291 + } 2292 + 2293 + /** 2254 2294 * ice_vsi_setup - Set up a VSI by a given type 2255 2295 * @pf: board private structure 2256 2296 * @pi: pointer to the port_info instance ··· 2325 2285 2326 2286 vsi->port_info = pi; 2327 2287 vsi->vsw = pf->first_sw; 2288 + if (vsi->type == ICE_VSI_PF) 2289 + vsi->ethtype = ETH_P_PAUSE; 2290 + 2328 2291 if (vsi->type == ICE_VSI_VF) 2329 2292 vsi->vf_id = vf_id; 2330 2293 ··· 2424 2381 vsi->vsi_num, ret); 2425 2382 goto unroll_vector_base; 2426 2383 } 2384 + 2385 + /* Add switch rule to drop all Tx Flow Control Frames, of look up 2386 + * type ETHERTYPE from VSIs, and restrict malicious VF from sending 2387 + * out PAUSE or PFC frames. If enabled, FW can still send FC frames. 2388 + * The rule is added once for PF VSI in order to create appropriate 2389 + * recipe, since VSI/VSI list is ignored with drop action... 2390 + */ 2391 + if (vsi->type == ICE_VSI_PF) 2392 + ice_vsi_add_rem_eth_mac(vsi, true); 2427 2393 2428 2394 return vsi; 2429 2395 ··· 2791 2739 vsi->idx); 2792 2740 pf->num_avail_hw_msix += pf->num_vf_msix; 2793 2741 } 2742 + 2743 + if (vsi->type == ICE_VSI_PF) 2744 + ice_vsi_add_rem_eth_mac(vsi, false); 2794 2745 2795 2746 ice_remove_vsi_fltr(&pf->hw, vsi->idx); 2796 2747 ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
+59
drivers/net/ethernet/intel/ice/ice_switch.c
··· 1970 1970 } 1971 1971 1972 1972 /** 1973 + * ice_add_eth_mac - Add ethertype and MAC based filter rule 1974 + * @hw: pointer to the hardware structure 1975 + * @em_list: list of ether type MAC filter, MAC is optional 1976 + */ 1977 + enum ice_status 1978 + ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list) 1979 + { 1980 + struct ice_fltr_list_entry *em_list_itr; 1981 + 1982 + if (!em_list || !hw) 1983 + return ICE_ERR_PARAM; 1984 + 1985 + list_for_each_entry(em_list_itr, em_list, list_entry) { 1986 + enum ice_sw_lkup_type l_type = 1987 + em_list_itr->fltr_info.lkup_type; 1988 + 1989 + if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 1990 + l_type != ICE_SW_LKUP_ETHERTYPE) 1991 + return ICE_ERR_PARAM; 1992 + 1993 + em_list_itr->fltr_info.flag = ICE_FLTR_TX; 1994 + em_list_itr->status = ice_add_rule_internal(hw, l_type, 1995 + em_list_itr); 1996 + if (em_list_itr->status) 1997 + return em_list_itr->status; 1998 + } 1999 + return 0; 2000 + } 2001 + 2002 + /** 2003 + * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule 2004 + * @hw: pointer to the hardware structure 2005 + * @em_list: list of ethertype or ethertype MAC entries 2006 + */ 2007 + enum ice_status 2008 + ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list) 2009 + { 2010 + struct ice_fltr_list_entry *em_list_itr, *tmp; 2011 + 2012 + if (!em_list || !hw) 2013 + return ICE_ERR_PARAM; 2014 + 2015 + list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) { 2016 + enum ice_sw_lkup_type l_type = 2017 + em_list_itr->fltr_info.lkup_type; 2018 + 2019 + if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 2020 + l_type != ICE_SW_LKUP_ETHERTYPE) 2021 + return ICE_ERR_PARAM; 2022 + 2023 + em_list_itr->status = ice_remove_rule_internal(hw, l_type, 2024 + em_list_itr); 2025 + if (em_list_itr->status) 2026 + return em_list_itr->status; 2027 + } 2028 + return 0; 2029 + } 2030 + 2031 + /** 1973 2032 * ice_rem_sw_rule_info 1974 2033 * @hw: pointer to the hardware structure 1975 2034 * @rule_head: pointer to the switch list structure that we want to delete
+4
drivers/net/ethernet/intel/ice/ice_switch.h
··· 218 218 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw); 219 219 enum ice_status ice_add_mac(struct ice_hw *hw, struct list_head *m_lst); 220 220 enum ice_status ice_remove_mac(struct ice_hw *hw, struct list_head *m_lst); 221 + enum ice_status 222 + ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list); 223 + enum ice_status 224 + ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list); 221 225 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle); 222 226 enum ice_status 223 227 ice_add_vlan(struct ice_hw *hw, struct list_head *m_list);