]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cxgb4: flower: add support for fragmentation
authorHarshita V Rajput <harshitha.vr@chelsio.com>
Tue, 28 Oct 2025 07:52:55 +0000 (13:22 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 31 Oct 2025 02:07:44 +0000 (19:07 -0700)
This patch adds support for matching fragmented packets in tc flower
filters.

Previously, commit 93a8540aac72 ("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 d11e63119432 ("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>
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c

index 0765d000eaef08c5082a0d0a945d26679f2d97cc..e2b5554531b57847c20aa76308ecc59f5e941317 100644 (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);