cxgb4: flower: add support for fragmentation

This patch adds support for matching fragmented packets in tc flower
filters.

Previously, commit 93a8540aac ("cxgb4: flower: validate control flags")
added a check using flow_rule_match_has_control_flags() to reject
any rules with control flags, as the driver did not support
fragmentation at that time.

Now, with this patch, support for FLOW_DIS_IS_FRAGMENT is added:
- The driver checks for control flags using
  flow_rule_is_supp_control_flags(), as recommended in
  commit d11e631194 ("flow_offload: add control flag checking helpers").
- If the fragmentation flag is present, the driver sets `fs->val.frag` and
  `fs->mask.frag` accordingly in the filter specification.

Since fragmentation is now supported, the earlier check that rejected all
control flags (flow_rule_match_has_control_flags()) has been removed.

Signed-off-by: Harshita V Rajput <harshitha.vr@chelsio.com>
Signed-off-by: Potnuri Bharat Teja <bharat@chelsio.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20251028075255.1391596-1-harshitha.vr@chelsio.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
pull/1354/merge
Harshita V Rajput 2025-10-28 13:22:55 +05:30 committed by Jakub Kicinski
parent 12a7c6a993
commit 0d0eb18642
1 changed files with 24 additions and 16 deletions

View File

@ -161,20 +161,9 @@ static struct ch_tc_flower_entry *ch_flower_lookup(struct adapter *adap,
static void cxgb4_process_flow_match(struct net_device *dev,
struct flow_rule *rule,
u16 addr_type,
struct ch_filter_specification *fs)
{
u16 addr_type = 0;
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
struct flow_match_control match;
flow_rule_match_control(rule, &match);
addr_type = match.key->addr_type;
} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
}
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
struct flow_match_basic match;
@ -327,9 +316,6 @@ static int cxgb4_validate_flow_match(struct netlink_ext_ack *extack,
return -EOPNOTSUPP;
}
if (flow_rule_match_has_control_flags(rule, extack))
return -EOPNOTSUPP;
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
struct flow_match_basic match;
@ -858,6 +844,7 @@ int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
{
struct adapter *adap = netdev2adap(dev);
struct filter_ctx ctx;
u16 addr_type = 0;
u8 inet_family;
int fidx, ret;
@ -867,7 +854,28 @@ int cxgb4_flow_rule_replace(struct net_device *dev, struct flow_rule *rule,
if (cxgb4_validate_flow_match(extack, rule))
return -EOPNOTSUPP;
cxgb4_process_flow_match(dev, rule, fs);
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
struct flow_match_control match;
flow_rule_match_control(rule, &match);
addr_type = match.key->addr_type;
if (match.mask->flags & FLOW_DIS_IS_FRAGMENT) {
fs->val.frag = match.key->flags & FLOW_DIS_IS_FRAGMENT;
fs->mask.frag = true;
}
if (!flow_rule_is_supp_control_flags(FLOW_DIS_IS_FRAGMENT,
match.mask->flags, extack))
return -EOPNOTSUPP;
} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
}
cxgb4_process_flow_match(dev, rule, addr_type, fs);
cxgb4_process_flow_actions(dev, &rule->action, fs);
fs->hash = is_filter_exact_match(adap, fs);