forked from mirrors/linux
		
	ice: Add direction metadata
Currently it is possible to create a filter which breaks TX traffic, e.g.: tc filter add dev $PF1 ingress protocol ip prio 1 flower ip_proto udp dst_port $PORT action mirred egress redirect dev $VF1_PR This adds a rule which might match both TX and RX traffic, and in TX path the PF will actually receive the traffic, which breaks communication. To fix this, add a match on direction metadata flag when adding a tc rule. Because of the way metadata is currently handled, a duplicate lookup word would appear if VLAN metadata is also added. The lookup would still work correctly, but one word would be wasted. To prevent it, lookup 0 now always contains all metadata. When any metadata needs to be added, it is added to lookup 0 and lookup count is not incremented. This way, two flags residing in the same word will take up one word, instead of two. Note: the drop action is also affected, i.e. it will now only work in one direction. Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
		
							parent
							
								
									505a1fdada
								
							
						
					
					
						commit
						0960a27bd4
					
				
					 4 changed files with 28 additions and 19 deletions
				
			
		| 
						 | 
					@ -287,6 +287,7 @@ struct ice_nvgre_hdr {
 | 
				
			||||||
 * M = EVLAN (0x8100) - Outer L2 header has EVLAN (ethernet type 0x8100)
 | 
					 * M = EVLAN (0x8100) - Outer L2 header has EVLAN (ethernet type 0x8100)
 | 
				
			||||||
 * N = EVLAN (0x9100) - Outer L2 header has EVLAN (ethernet type 0x9100)
 | 
					 * N = EVLAN (0x9100) - Outer L2 header has EVLAN (ethernet type 0x9100)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#define ICE_PKT_FROM_NETWORK	BIT(3)
 | 
				
			||||||
#define ICE_PKT_VLAN_STAG	BIT(12)
 | 
					#define ICE_PKT_VLAN_STAG	BIT(12)
 | 
				
			||||||
#define ICE_PKT_VLAN_ITAG	BIT(13)
 | 
					#define ICE_PKT_VLAN_ITAG	BIT(13)
 | 
				
			||||||
#define ICE_PKT_VLAN_EVLAN	(BIT(14) | BIT(15))
 | 
					#define ICE_PKT_VLAN_EVLAN	(BIT(14) | BIT(15))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6058,14 +6058,21 @@ ice_adv_add_update_vsi_list(struct ice_hw *hw,
 | 
				
			||||||
void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
 | 
					void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lkup->type = ICE_HW_METADATA;
 | 
						lkup->type = ICE_HW_METADATA;
 | 
				
			||||||
	lkup->m_u.metadata.flags[ICE_PKT_FLAGS_TUNNEL] =
 | 
						lkup->m_u.metadata.flags[ICE_PKT_FLAGS_TUNNEL] |=
 | 
				
			||||||
		cpu_to_be16(ICE_PKT_TUNNEL_MASK);
 | 
							cpu_to_be16(ICE_PKT_TUNNEL_MASK);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						lkup->type = ICE_HW_METADATA;
 | 
				
			||||||
 | 
						lkup->m_u.metadata.flags[ICE_PKT_FLAGS_VLAN] |=
 | 
				
			||||||
 | 
							cpu_to_be16(ICE_PKT_FROM_NETWORK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
 | 
					void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lkup->type = ICE_HW_METADATA;
 | 
						lkup->type = ICE_HW_METADATA;
 | 
				
			||||||
	lkup->m_u.metadata.flags[ICE_PKT_FLAGS_VLAN] =
 | 
						lkup->m_u.metadata.flags[ICE_PKT_FLAGS_VLAN] |=
 | 
				
			||||||
		cpu_to_be16(ICE_PKT_VLAN_MASK);
 | 
							cpu_to_be16(ICE_PKT_VLAN_MASK);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -359,6 +359,7 @@ int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Switch/bridge related commands */
 | 
					/* Switch/bridge related commands */
 | 
				
			||||||
void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup);
 | 
					void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup);
 | 
				
			||||||
 | 
					void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup);
 | 
				
			||||||
void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup);
 | 
					void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup);
 | 
				
			||||||
void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup);
 | 
					void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup);
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,8 @@
 | 
				
			||||||
#include "ice_lib.h"
 | 
					#include "ice_lib.h"
 | 
				
			||||||
#include "ice_protocol_type.h"
 | 
					#include "ice_protocol_type.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ICE_TC_METADATA_LKUP_IDX 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * ice_tc_count_lkups - determine lookup count for switch filter
 | 
					 * ice_tc_count_lkups - determine lookup count for switch filter
 | 
				
			||||||
 * @flags: TC-flower flags
 | 
					 * @flags: TC-flower flags
 | 
				
			||||||
| 
						 | 
					@ -19,7 +21,13 @@ static int
 | 
				
			||||||
ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 | 
					ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 | 
				
			||||||
		   struct ice_tc_flower_fltr *fltr)
 | 
							   struct ice_tc_flower_fltr *fltr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int lkups_cnt = 0;
 | 
						int lkups_cnt = 1; /* 0th lookup is metadata */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Always add metadata as the 0th lookup. Included elements:
 | 
				
			||||||
 | 
						 * - Direction flag (always present)
 | 
				
			||||||
 | 
						 * - ICE_TC_FLWR_FIELD_VLAN_TPID (present if specified)
 | 
				
			||||||
 | 
						 * - Tunnel flag (present if tunnel)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (flags & ICE_TC_FLWR_FIELD_TENANT_ID)
 | 
						if (flags & ICE_TC_FLWR_FIELD_TENANT_ID)
 | 
				
			||||||
		lkups_cnt++;
 | 
							lkups_cnt++;
 | 
				
			||||||
| 
						 | 
					@ -54,10 +62,6 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 | 
				
			||||||
	if (flags & (ICE_TC_FLWR_FIELD_VLAN | ICE_TC_FLWR_FIELD_VLAN_PRIO))
 | 
						if (flags & (ICE_TC_FLWR_FIELD_VLAN | ICE_TC_FLWR_FIELD_VLAN_PRIO))
 | 
				
			||||||
		lkups_cnt++;
 | 
							lkups_cnt++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* is VLAN TPID specified */
 | 
					 | 
				
			||||||
	if (flags & ICE_TC_FLWR_FIELD_VLAN_TPID)
 | 
					 | 
				
			||||||
		lkups_cnt++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* is CVLAN specified? */
 | 
						/* is CVLAN specified? */
 | 
				
			||||||
	if (flags & (ICE_TC_FLWR_FIELD_CVLAN | ICE_TC_FLWR_FIELD_CVLAN_PRIO))
 | 
						if (flags & (ICE_TC_FLWR_FIELD_CVLAN | ICE_TC_FLWR_FIELD_CVLAN_PRIO))
 | 
				
			||||||
		lkups_cnt++;
 | 
							lkups_cnt++;
 | 
				
			||||||
| 
						 | 
					@ -84,10 +88,6 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 | 
				
			||||||
		     ICE_TC_FLWR_FIELD_SRC_L4_PORT))
 | 
							     ICE_TC_FLWR_FIELD_SRC_L4_PORT))
 | 
				
			||||||
		lkups_cnt++;
 | 
							lkups_cnt++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* matching for tunneled packets in metadata */
 | 
					 | 
				
			||||||
	if (fltr->tunnel_type != TNL_LAST)
 | 
					 | 
				
			||||||
		lkups_cnt++;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return lkups_cnt;
 | 
						return lkups_cnt;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,10 +176,9 @@ static u16 ice_check_supported_vlan_tpid(u16 vlan_tpid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
 | 
					ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
 | 
				
			||||||
			 struct ice_adv_lkup_elem *list)
 | 
								 struct ice_adv_lkup_elem *list, int i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ice_tc_flower_lyr_2_4_hdrs *hdr = &fltr->outer_headers;
 | 
						struct ice_tc_flower_lyr_2_4_hdrs *hdr = &fltr->outer_headers;
 | 
				
			||||||
	int i = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (flags & ICE_TC_FLWR_FIELD_TENANT_ID) {
 | 
						if (flags & ICE_TC_FLWR_FIELD_TENANT_ID) {
 | 
				
			||||||
		u32 tenant_id;
 | 
							u32 tenant_id;
 | 
				
			||||||
| 
						 | 
					@ -329,8 +328,7 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* always fill matching on tunneled packets in metadata */
 | 
						/* always fill matching on tunneled packets in metadata */
 | 
				
			||||||
	ice_rule_add_tunnel_metadata(&list[i]);
 | 
						ice_rule_add_tunnel_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
 | 
				
			||||||
	i++;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return i;
 | 
						return i;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -358,13 +356,16 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 | 
				
			||||||
	struct ice_tc_flower_lyr_2_4_hdrs *headers = &tc_fltr->outer_headers;
 | 
						struct ice_tc_flower_lyr_2_4_hdrs *headers = &tc_fltr->outer_headers;
 | 
				
			||||||
	bool inner = false;
 | 
						bool inner = false;
 | 
				
			||||||
	u16 vlan_tpid = 0;
 | 
						u16 vlan_tpid = 0;
 | 
				
			||||||
	int i = 0;
 | 
						int i = 1; /* 0th lookup is metadata */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rule_info->vlan_type = vlan_tpid;
 | 
						rule_info->vlan_type = vlan_tpid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Always add direction metadata */
 | 
				
			||||||
 | 
						ice_rule_add_direction_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rule_info->tun_type = ice_sw_type_from_tunnel(tc_fltr->tunnel_type);
 | 
						rule_info->tun_type = ice_sw_type_from_tunnel(tc_fltr->tunnel_type);
 | 
				
			||||||
	if (tc_fltr->tunnel_type != TNL_LAST) {
 | 
						if (tc_fltr->tunnel_type != TNL_LAST) {
 | 
				
			||||||
		i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list);
 | 
							i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list, i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		headers = &tc_fltr->inner_headers;
 | 
							headers = &tc_fltr->inner_headers;
 | 
				
			||||||
		inner = true;
 | 
							inner = true;
 | 
				
			||||||
| 
						 | 
					@ -431,8 +432,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 | 
				
			||||||
		rule_info->vlan_type =
 | 
							rule_info->vlan_type =
 | 
				
			||||||
				ice_check_supported_vlan_tpid(vlan_tpid);
 | 
									ice_check_supported_vlan_tpid(vlan_tpid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ice_rule_add_vlan_metadata(&list[i]);
 | 
							ice_rule_add_vlan_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
 | 
				
			||||||
		i++;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (flags & (ICE_TC_FLWR_FIELD_CVLAN | ICE_TC_FLWR_FIELD_CVLAN_PRIO)) {
 | 
						if (flags & (ICE_TC_FLWR_FIELD_CVLAN | ICE_TC_FLWR_FIELD_CVLAN_PRIO)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue