Commit a8d52b02 authored by Jianbo Liu's avatar Jianbo Liu Committed by Saeed Mahameed
Browse files

net/mlx5e: TC, Support offloading police action



Add parsing support by implementing struct mlx5e_tc_act for police
action.

TC rule with police actions is broken down into several rules in
different tables. One rule with the original match in the original
flow table, which set fte_id, do metering, and jump to the post_meter
table. If there are more police actions, more rules are created for
each of them. Besides, a last rule is created in the end.

In post_meter table, there are two pre-defined rules, one is to drop
packet if its packet color is RED, the other is to jump back to
post_act table. As fte_id is updated before jumping, the rule for next
meter is matched to do another round of metering (if there are
multiple meters in the flow rule). Otherwise, last fte_id is matched
and do the original actions.

Signed-off-by: default avatarJianbo Liu <jianbol@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Reviewed-by: default avatarAriel Levkovich <lariel@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 03a92a93
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/a
					en/tc/act/vlan.o en/tc/act/vlan_mangle.o en/tc/act/mpls.o \
					en/tc/act/mirred.o en/tc/act/mirred_nic.o \
					en/tc/act/ct.o en/tc/act/sample.o en/tc/act/ptype.o \
					en/tc/act/redirect_ingress.o
					en/tc/act/redirect_ingress.o en/tc/act/police.o

ifneq ($(CONFIG_MLX5_TC_CT),)
	mlx5_core-y			     += en/tc_ct.o en/tc/ct_fs_dmfs.o
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
	NULL, /* FLOW_ACTION_WAKE, */
	NULL, /* FLOW_ACTION_QUEUE, */
	&mlx5e_tc_act_sample,
	NULL, /* FLOW_ACTION_POLICE, */
	&mlx5e_tc_act_police,
	&mlx5e_tc_act_ct,
	NULL, /* FLOW_ACTION_CT_METADATA, */
	&mlx5e_tc_act_mpls_push,
+1 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ extern struct mlx5e_tc_act mlx5e_tc_act_ct;
extern struct mlx5e_tc_act mlx5e_tc_act_sample;
extern struct mlx5e_tc_act mlx5e_tc_act_ptype;
extern struct mlx5e_tc_act mlx5e_tc_act_redirect_ingress;
extern struct mlx5e_tc_act mlx5e_tc_act_police;

struct mlx5e_tc_act *
mlx5e_tc_act_get(enum flow_action_id act_id,
+61 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

#include "act.h"
#include "en/tc_priv.h"

static bool
tc_act_can_offload_police(struct mlx5e_tc_act_parse_state *parse_state,
			  const struct flow_action_entry *act,
			  int act_index,
			  struct mlx5_flow_attr *attr)
{
	if (mlx5e_policer_validate(parse_state->flow_action, act,
				   parse_state->extack))
		return false;

	return !!mlx5e_get_flow_meters(parse_state->flow->priv->mdev);
}

static int
tc_act_parse_police(struct mlx5e_tc_act_parse_state *parse_state,
		    const struct flow_action_entry *act,
		    struct mlx5e_priv *priv,
		    struct mlx5_flow_attr *attr)
{
	struct mlx5e_flow_meter_params *params;

	params = &attr->meter_attr.params;
	params->index = act->hw_index;
	if (act->police.rate_bytes_ps) {
		params->mode = MLX5_RATE_LIMIT_BPS;
		/* change rate to bits per second */
		params->rate = act->police.rate_bytes_ps << 3;
		params->burst = act->police.burst;
	} else if (act->police.rate_pkt_ps) {
		params->mode = MLX5_RATE_LIMIT_PPS;
		params->rate = act->police.rate_pkt_ps;
		params->burst = act->police.burst_pkt;
	} else {
		return -EOPNOTSUPP;
	}

	attr->action |= MLX5_FLOW_CONTEXT_ACTION_EXECUTE_ASO;
	attr->exe_aso_type = MLX5_EXE_ASO_FLOW_METER;

	return 0;
}

static bool
tc_act_is_multi_table_act_police(struct mlx5e_priv *priv,
				 const struct flow_action_entry *act,
				 struct mlx5_flow_attr *attr)
{
	return true;
}

struct mlx5e_tc_act mlx5e_tc_act_police = {
	.can_offload = tc_act_can_offload_police,
	.parse_action = tc_act_parse_police,
	.is_multi_table_act = tc_act_is_multi_table_act_police,
};
+6 −0
Original line number Diff line number Diff line
@@ -389,6 +389,12 @@ mlx5e_tc_meter_put(struct mlx5e_flow_meter_handle *meter)
	mutex_unlock(&flow_meters->sync_lock);
}

struct mlx5_flow_table *
mlx5e_tc_meter_get_post_meter_ft(struct mlx5e_flow_meters *flow_meters)
{
	return mlx5e_post_meter_get_ft(flow_meters->post_meter);
}

struct mlx5e_flow_meters *
mlx5e_flow_meters_init(struct mlx5e_priv *priv,
		       enum mlx5_flow_namespace_type ns_type,
Loading