Commit 8300f225 authored by Roi Dayan's avatar Roi Dayan Committed by Saeed Mahameed
Browse files

net/mlx5e: Create new flow attr for multi table actions



Some TC actions use post actions for their implementation.
For example CT and sample actions.

Create a new flow attr after each multi table action and
create a post action rule for it.

First flow attr being offloaded normally and linked to the next
attr (post action rule) with setting an id on reg_c.
Post action rules match the id on reg_c and continue to the next one.

The flow counter is allocated on the last rule.

Signed-off-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 314e1105
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

#include "act.h"
#include "en/tc/post_act.h"
#include "en/tc_priv.h"
#include "mlx5_core.h"

@@ -101,3 +102,75 @@ mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state,
	parse_state->num_actions = flow_action->num_entries;
	parse_state->extack = extack;
}

void
mlx5e_tc_act_reorder_flow_actions(struct flow_action *flow_action,
				  struct mlx5e_tc_flow_action *flow_action_reorder)
{
	struct flow_action_entry *act;
	int i, j = 0;

	flow_action_for_each(i, act, flow_action) {
		/* Add CT action to be first. */
		if (act->id == FLOW_ACTION_CT)
			flow_action_reorder->entries[j++] = act;
	}

	flow_action_for_each(i, act, flow_action) {
		if (act->id == FLOW_ACTION_CT)
			continue;
		flow_action_reorder->entries[j++] = act;
	}
}

int
mlx5e_tc_act_post_parse(struct mlx5e_tc_act_parse_state *parse_state,
			struct flow_action *flow_action,
			struct mlx5_flow_attr *attr,
			enum mlx5_flow_namespace_type ns_type)
{
	struct flow_action_entry *act;
	struct mlx5e_tc_act *tc_act;
	struct mlx5e_priv *priv;
	int err = 0, i;

	priv = parse_state->flow->priv;

	flow_action_for_each(i, act, flow_action) {
		tc_act = mlx5e_tc_act_get(act->id, ns_type);
		if (!tc_act || !tc_act->post_parse ||
		    !tc_act->can_offload(parse_state, act, i, attr))
			continue;

		err = tc_act->post_parse(parse_state, priv, attr);
		if (err)
			goto out;
	}

out:
	return err;
}

int
mlx5e_tc_act_set_next_post_act(struct mlx5e_tc_flow *flow,
			       struct mlx5_flow_attr *attr,
			       struct mlx5_flow_attr *next_attr)
{
	struct mlx5_core_dev *mdev = flow->priv->mdev;
	struct mlx5e_tc_mod_hdr_acts *mod_acts;
	int err;

	mod_acts = &attr->parse_attr->mod_hdr_acts;

	/* Set handle on current post act rule to next post act rule. */
	err = mlx5e_tc_post_act_set_handle(mdev, next_attr->post_act_handle, mod_acts);
	if (err) {
		mlx5_core_warn(mdev, "Failed setting post action handle");
		return err;
	}

	attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
			MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;

	return 0;
}
+24 −0
Original line number Diff line number Diff line
@@ -42,6 +42,15 @@ struct mlx5e_tc_act {
	int (*post_parse)(struct mlx5e_tc_act_parse_state *parse_state,
			  struct mlx5e_priv *priv,
			  struct mlx5_flow_attr *attr);

	bool (*is_multi_table_act)(struct mlx5e_priv *priv,
				   const struct flow_action_entry *act,
				   struct mlx5_flow_attr *attr);
};

struct mlx5e_tc_flow_action {
	unsigned int num_entries;
	struct flow_action_entry **entries;
};

extern struct mlx5e_tc_act mlx5e_tc_act_drop;
@@ -74,4 +83,19 @@ mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state,
			      struct flow_action *flow_action,
			      struct netlink_ext_ack *extack);

void
mlx5e_tc_act_reorder_flow_actions(struct flow_action *flow_action,
				  struct mlx5e_tc_flow_action *flow_action_reorder);

int
mlx5e_tc_act_post_parse(struct mlx5e_tc_act_parse_state *parse_state,
			struct flow_action *flow_action,
			struct mlx5_flow_attr *attr,
			enum mlx5_flow_namespace_type ns_type);

int
mlx5e_tc_act_set_next_post_act(struct mlx5e_tc_flow *flow,
			       struct mlx5_flow_attr *attr,
			       struct mlx5_flow_attr *next_attr);

#endif /* __MLX5_EN_TC_ACT_H__ */
+0 −6
Original line number Diff line number Diff line
@@ -140,15 +140,9 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *at
		goto err_xarray;

	handle->attr = post_attr;
	err = mlx5e_tc_post_act_offload(post_act, handle);
	if (err)
		goto err_rule;


	return handle;

err_rule:
	xa_erase(&post_act->ids, handle->id);
err_xarray:
	kfree(post_attr);
	kfree(handle);
+3 −0
Original line number Diff line number Diff line
@@ -533,6 +533,9 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample,
			err = PTR_ERR(post_act_handle);
			goto err_post_act;
		}
		err = mlx5e_tc_post_act_offload(tc_psample->post_act, post_act_handle);
		if (err)
			goto err_post_rule;
		sample_flow->post_act_handle = post_act_handle;
	} else {
		err = add_post_rule(esw, sample_flow, spec, attr, &default_tbl_id);
+3 −0
Original line number Diff line number Diff line
@@ -1823,6 +1823,9 @@ __mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *ct_priv,
		ct_dbg("Failed to allocate post action handle");
		goto err_post_act_handle;
	}
	err = mlx5e_tc_post_act_offload(ct_priv->post_act, handle);
	if (err)
		goto err_alloc_pre;
	ct_flow->post_act_handle = handle;

	/* Base flow attributes of both rules on original rule attribute */
Loading