Commit 0960a27b authored by Marcin Szycik's avatar Marcin Szycik Committed by Tony Nguyen

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: default avatarMarcin Szycik <marcin.szycik@linux.intel.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Tested-by: default avatarSujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 505a1fda
...@@ -287,6 +287,7 @@ struct ice_nvgre_hdr { ...@@ -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, ...@@ -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); ...@@ -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 @@ ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment