> -----Original Message----- > From: Petr Oros <[email protected]> > Sent: Wednesday, September 16, 2026 4:41 PM > To: [email protected] > Cc: Oros, Petr <[email protected]>; Loktionov, Aleksandr > <[email protected]>; Nguyen, Anthony L > <[email protected]>; Kitszel, Przemyslaw > <[email protected]>; Andrew Lunn <[email protected]>; > David S. Miller <[email protected]>; Eric Dumazet > <[email protected]>; Jakub Kicinski <[email protected]>; Paolo Abeni > <[email protected]>; Kushwaha, Priyalee <[email protected]>; > Kiran Patil <[email protected]>; Drewek, Wojciech > <[email protected]>; Michal Swiatkowski > <[email protected]>; Simon Horman <[email protected]>; > [email protected]; [email protected] > Subject: [PATCH iwl-next v2 1/2] ice: fix TC flower filters matching more than > the ip_proto key > > ice_parse_cls_flower() stores the ip_proto key from the flow rule but never > programs a matching lookup unless the filter also matches on L4 ports or the > L2TPv3 session ID. A filter like: > > tc filter add dev $pf ingress protocol ip flower skip_sw \ > ip_proto udp action drop > > is silently programmed into the hardware as a match on eth_type ipv4 alone > and drops every IPv4 packet, not just UDP. > > Program the IP protocol match through the protocol field of the IPv4 header > lookup and the next header field of the IPv6 header lookup, the same lookups > that are already used for ToS and TTL. The OS default and comms DDP > packages provide no profile that extracts the IPv6 next header word, so the > IPv6 rule programming currently fails with "Required profiles not found" and > the filter falls back to software evaluation instead of over-matching, and the > offload starts working with a DDP package that can extract it. Note that the > lookup matches the next header byte of the base IPv6 header, so packets > carrying extension headers are not matched in hardware and fall back to > software evaluation, which under-matches only for skip_sw filters. > > GTP tunnel and PPPoE filters rewrite the parsed ethertype, the IP header > lookups are not available there, so reject an unconsumed ip_proto for them > instead of silently widening the match. Filters where ip_proto is implied by > an > L4 ports or L2TPv3 session ID lookup are not affected. Based on an earlier > unapplied patch from Michal Swiatkowski that implemented the IPv4 part [1]. > > Link: https://lore.kernel.org/intel-wired-lan/20240222123956.2393-3- > [email protected]/ [1] > Fixes: 0d08a441fb1a ("ice: ndo_setup_tc implementation for PF") > Reviewed-by: Aleksandr Loktionov <[email protected]> > Signed-off-by: Petr Oros <[email protected]> > --- > v2: > - no code changes, collect Reviewed-by from Aleksandr Loktionov > > v1: https://lore.kernel.org/all/20260910154824.3603687-2- > [email protected]/ > drivers/net/ethernet/intel/ice/ice_tc_lib.c | 37 +++++++++++++++++++-- > drivers/net/ethernet/intel/ice/ice_tc_lib.h | 1 + > 2 files changed, 35 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c > b/drivers/net/ethernet/intel/ice/ice_tc_lib.c > index d20357c0412731..fbd8cbad150a98 100644 > --- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c > +++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c > @@ -78,7 +78,8 @@ static int ice_tc_count_lkups(u32 flags, struct > ice_tc_flower_fltr *fltr) > ICE_TC_FLWR_FIELD_DEST_IPV6 | > ICE_TC_FLWR_FIELD_SRC_IPV6)) > lkups_cnt++; > > - if (flags & (ICE_TC_FLWR_FIELD_IP_TOS | > ICE_TC_FLWR_FIELD_IP_TTL)) > + if (flags & (ICE_TC_FLWR_FIELD_IP_TOS | ICE_TC_FLWR_FIELD_IP_TTL > | > + ICE_TC_FLWR_FIELD_IP_PROTO)) > lkups_cnt++; > > /* are L2TPv3 options specified? */ > @@ -552,7 +553,8 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags, > } > > if (headers->l2_key.n_proto == htons(ETH_P_IP) && > - (flags & (ICE_TC_FLWR_FIELD_IP_TOS | > ICE_TC_FLWR_FIELD_IP_TTL))) { > + (flags & (ICE_TC_FLWR_FIELD_IP_TOS | ICE_TC_FLWR_FIELD_IP_TTL > | > + ICE_TC_FLWR_FIELD_IP_PROTO))) { > list[i].type = ice_proto_type_from_ipv4(inner); > > if (flags & ICE_TC_FLWR_FIELD_IP_TOS) { @@ -567,11 > +569,19 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags, > headers->l3_mask.ttl; > } > > + if (flags & ICE_TC_FLWR_FIELD_IP_PROTO) { > + list[i].h_u.ipv4_hdr.protocol = > + headers->l3_key.ip_proto; > + list[i].m_u.ipv4_hdr.protocol = > + headers->l3_mask.ip_proto; > + } > + > i++; > } > > if (headers->l2_key.n_proto == htons(ETH_P_IPV6) && > - (flags & (ICE_TC_FLWR_FIELD_IP_TOS | > ICE_TC_FLWR_FIELD_IP_TTL))) { > + (flags & (ICE_TC_FLWR_FIELD_IP_TOS | ICE_TC_FLWR_FIELD_IP_TTL > | > + ICE_TC_FLWR_FIELD_IP_PROTO))) { > struct ice_ipv6_hdr *hdr_h, *hdr_m; > > hdr_h = &list[i].h_u.ipv6_hdr; > @@ -592,6 +602,11 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags, > hdr_m->hop_limit = headers->l3_mask.ttl; > } > > + if (flags & ICE_TC_FLWR_FIELD_IP_PROTO) { > + hdr_h->next_hdr = headers->l3_key.ip_proto; > + hdr_m->next_hdr = headers->l3_mask.ip_proto; > + } > + > i++; > } > > @@ -1737,6 +1752,9 @@ ice_parse_cls_flower(struct net_device *filter_dev, > struct ice_vsi *vsi, > headers->l2_key.n_proto = cpu_to_be16(n_proto_key); > headers->l2_mask.n_proto = cpu_to_be16(n_proto_mask); > headers->l3_key.ip_proto = match.key->ip_proto; > + headers->l3_mask.ip_proto = match.mask->ip_proto; > + if (match.mask->ip_proto) > + fltr->flags |= ICE_TC_FLWR_FIELD_IP_PROTO; > } > > if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { > @@ -1910,6 +1928,19 @@ ice_parse_cls_flower(struct net_device > *filter_dev, struct ice_vsi *vsi, > } > } > > + if (fltr->flags & (ICE_TC_FLWR_FIELD_DEST_L4_PORT | > + ICE_TC_FLWR_FIELD_SRC_L4_PORT | > + ICE_TC_FLWR_FIELD_L2TPV3_SESSID)) > + fltr->flags &= ~ICE_TC_FLWR_FIELD_IP_PROTO; > + > + if ((fltr->flags & ICE_TC_FLWR_FIELD_IP_PROTO) && > + headers->l2_key.n_proto != htons(ETH_P_IP) && > + headers->l2_key.n_proto != htons(ETH_P_IPV6)) { > + NL_SET_ERR_MSG_MOD(fltr->extack, > + "IP protocol match is not supported with > GTP or PPPoE"); > + return -EOPNOTSUPP; > + } > + > /* Ingress filter on representor results in an egress filter in HW > * and vice versa > */ > diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.h > b/drivers/net/ethernet/intel/ice/ice_tc_lib.h > index 8a3ab2f22af9ba..752af65e70b7bf 100644 > --- a/drivers/net/ethernet/intel/ice/ice_tc_lib.h > +++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.h > @@ -38,6 +38,7 @@ > #define ICE_TC_FLWR_FIELD_CVLAN_PRIO BIT(28) > #define ICE_TC_FLWR_FIELD_VLAN_TPID BIT(29) > #define ICE_TC_FLWR_FIELD_PFCP_OPTS BIT(30) > +#define ICE_TC_FLWR_FIELD_IP_PROTO BIT(31) > > #define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF > > -- > 2.55.0
Tested-by: Patryk Holda <[email protected]>
