Commit 0d0eb186 authored by Harshita V Rajput's avatar Harshita V Rajput Committed by Jakub Kicinski
Browse files

cxgb4: flower: add support for fragmentation



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

Previously, commit 93a8540a ("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 d11e6311 ("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: default avatarHarshita V Rajput <harshitha.vr@chelsio.com>
Signed-off-by: default avatarPotnuri Bharat Teja <bharat@chelsio.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20251028075255.1391596-1-harshitha.vr@chelsio.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 12a7c6a9
Loading
Loading
Loading
Loading
+24 −16
Original line number Diff line number Diff line
@@ -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);