Commit 16f80360 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso Committed by David S. Miller
Browse files

net: flow_offload: skip hw stats check for FLOW_ACTION_HW_STATS_DONT_CARE



This patch adds FLOW_ACTION_HW_STATS_DONT_CARE which tells the driver
that the frontend does not need counters, this hw stats type request
never fails. The FLOW_ACTION_HW_STATS_DISABLED type explicitly requests
the driver to disable the stats, however, if the driver cannot disable
counters, it bails out.

TCA_ACT_HW_STATS_* maintains the 1:1 mapping with FLOW_ACTION_HW_STATS_*
except by disabled which is mapped to FLOW_ACTION_HW_STATS_DISABLED
(this is 0 in tc). Add tc_act_hw_stats() to perform the mapping between
TCA_ACT_HW_STATS_* and FLOW_ACTION_HW_STATS_*.

Fixes: 319a1d19 ("flow_offload: check for basic action hw stats type")
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b0956956
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp,
		err = mlxsw_sp_acl_rulei_act_count(mlxsw_sp, rulei, extack);
		if (err)
			return err;
	} else if (act->hw_stats != FLOW_ACTION_HW_STATS_DISABLED) {
	} else if (act->hw_stats != FLOW_ACTION_HW_STATS_DISABLED &&
		   act->hw_stats != FLOW_ACTION_HW_STATS_DONT_CARE) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported action HW stats type");
		return -EOPNOTSUPP;
	}
+8 −1
Original line number Diff line number Diff line
@@ -166,15 +166,18 @@ enum flow_action_mangle_base {
enum flow_action_hw_stats_bit {
	FLOW_ACTION_HW_STATS_IMMEDIATE_BIT,
	FLOW_ACTION_HW_STATS_DELAYED_BIT,
	FLOW_ACTION_HW_STATS_DISABLED_BIT,
};

enum flow_action_hw_stats {
	FLOW_ACTION_HW_STATS_DISABLED = 0,
	FLOW_ACTION_HW_STATS_DONT_CARE = 0,
	FLOW_ACTION_HW_STATS_IMMEDIATE =
		BIT(FLOW_ACTION_HW_STATS_IMMEDIATE_BIT),
	FLOW_ACTION_HW_STATS_DELAYED = BIT(FLOW_ACTION_HW_STATS_DELAYED_BIT),
	FLOW_ACTION_HW_STATS_ANY = FLOW_ACTION_HW_STATS_IMMEDIATE |
				   FLOW_ACTION_HW_STATS_DELAYED,
	FLOW_ACTION_HW_STATS_DISABLED =
		BIT(FLOW_ACTION_HW_STATS_DISABLED_BIT),
};

typedef void (*action_destr)(void *priv);
@@ -325,7 +328,11 @@ __flow_action_hw_stats_check(const struct flow_action *action,
		return true;
	if (!flow_action_mixed_hw_stats_check(action, extack))
		return false;

	action_entry = flow_action_first_entry_get(action);
	if (action_entry->hw_stats == FLOW_ACTION_HW_STATS_DONT_CARE)
		return true;

	if (!check_allow_bit &&
	    action_entry->hw_stats != FLOW_ACTION_HW_STATS_ANY) {
		NL_SET_ERR_MSG_MOD(extack, "Driver supports only default HW stats type \"any\"");
+12 −2
Original line number Diff line number Diff line
@@ -3523,6 +3523,16 @@ static void tcf_sample_get_group(struct flow_action_entry *entry,
#endif
}

static enum flow_action_hw_stats tc_act_hw_stats(u8 hw_stats)
{
	if (WARN_ON_ONCE(hw_stats > TCA_ACT_HW_STATS_ANY))
		return FLOW_ACTION_HW_STATS_DONT_CARE;
	else if (!hw_stats)
		return FLOW_ACTION_HW_STATS_DISABLED;

	return hw_stats;
}

int tc_setup_flow_action(struct flow_action *flow_action,
			 const struct tcf_exts *exts)
{
@@ -3546,7 +3556,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
		if (err)
			goto err_out_locked;

		entry->hw_stats = act->hw_stats;
		entry->hw_stats = tc_act_hw_stats(act->hw_stats);

		if (is_tcf_gact_ok(act)) {
			entry->id = FLOW_ACTION_ACCEPT;
@@ -3614,7 +3624,7 @@ int tc_setup_flow_action(struct flow_action *flow_action,
				entry->mangle.mask = tcf_pedit_mask(act, k);
				entry->mangle.val = tcf_pedit_val(act, k);
				entry->mangle.offset = tcf_pedit_offset(act, k);
				entry->hw_stats = act->hw_stats;
				entry->hw_stats = tc_act_hw_stats(act->hw_stats);
				entry = &flow_action->entries[++j];
			}
		} else if (is_tcf_csum(act)) {