When building an advanced switch rule, ice_find_dummy_packet() selects the template packet type based on the lookup element list. It currently checks for ICE_TCP_IL to select the inner TCP template, but ignores the case where the user matches on ICE_IPV4_IL with protocol == IPPROTO_TCP without specifying a TCP L4 field. In that case the default UDP template is chosen, causing the rule to fail. Extend the check to also match ICE_IPV4_IL with TCP protocol field fully masked, fixing tc-flower rules such as: tc filter add dev vxlan100 ingress protocol ip prio 0 \\ flower ip_proto tcp action mirred egress redirect dev eth0 Fixes: e33163a40d1a ("ice: switch: convert packet template match code to rodata") Cc: stable@vger.kernel.org Signed-off-by: Michal Swiatkowski Signed-off-by: Aleksandr Loktionov --- drivers/net/ethernet/intel/ice/ice_switch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index bb0f990..c2ac870 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -5587,7 +5587,10 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, for (i = 0; i < lkups_cnt; i++) { if (lkups[i].type == ICE_UDP_ILOS) match |= ICE_PKT_INNER_UDP; - else if (lkups[i].type == ICE_TCP_IL) + else if (lkups[i].type == ICE_TCP_IL || + (lkups[i].type == ICE_IPV4_IL && + lkups[i].h_u.ipv4_hdr.protocol == IPPROTO_TCP && + lkups[i].m_u.ipv4_hdr.protocol == 0xFF)) match |= ICE_PKT_INNER_TCP; else if (lkups[i].type == ICE_IPV6_OFOS) match |= ICE_PKT_OUTER_IPV6; -- 2.52.0