Skip to content

Commit

Permalink
net/mlx5e: Add tc action infrastructure
Browse files Browse the repository at this point in the history
Add an infrastructure to help parsing tc actions in a generic way.

Supporting an action parser means implementing struct mlx5e_tc_act
for that action.

The infrastructure will give the possibility to be generic when parsing tc
actions, i.e. parse_tc_nic_actions() and parse_tc_fdb_actions().
To parse tc actions a user needs to allocate a parse_state instance
and pass it when iterating over the tc actions parsers.
If a parser doesn't exists then a user can treat it as unsupported.

To add an action parser a user needs to implement two callbacks.
The can_offload() callback to quickly check if an action can be offloaded.
The parse_action() callback to do actual parsing and prepare for offload.

Add implementation for drop, trap, mark and accept action parsers with this
commit to act as examples and implement usage of the new infrastructure for
those actions.

Signed-off-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Oz Shlomo <ozsh@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
  • Loading branch information
Roi Dayan authored and Saeed Mahameed committed Dec 15, 2021
1 parent 6cf7a1a commit fad5479
Show file tree
Hide file tree
Showing 9 changed files with 297 additions and 47 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.o \
en/tc_tun_vxlan.o en/tc_tun_gre.o en/tc_tun_geneve.o \
en/tc_tun_mplsoudp.o diag/en_tc_tracepoint.o \
en/tc/post_act.o en/tc/int_port.o

mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en/tc/act/act.o en/tc/act/drop.o en/tc/act/trap.o \
en/tc/act/accept.o en/tc/act/mark.o

mlx5_core-$(CONFIG_MLX5_TC_CT) += en/tc_ct.o
mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o

Expand Down
31 changes: 31 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/accept.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// 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_accept(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
int act_index)
{
return true;
}

static int
tc_act_parse_accept(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
struct mlx5e_priv *priv,
struct mlx5_flow_attr *attr)
{
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
MLX5_FLOW_CONTEXT_ACTION_COUNT;
attr->flags |= MLX5_ESW_ATTR_FLAG_ACCEPT;

return 0;
}

struct mlx5e_tc_act mlx5e_tc_act_accept = {
.can_offload = tc_act_can_offload_accept,
.parse_action = tc_act_parse_accept,
};
72 changes: 72 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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"
#include "mlx5_core.h"

/* Must be aligned with enum flow_action_id. */
static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
&mlx5e_tc_act_accept,
&mlx5e_tc_act_drop,
&mlx5e_tc_act_trap,
};

/* Must be aligned with enum flow_action_id. */
static struct mlx5e_tc_act *tc_acts_nic[NUM_FLOW_ACTIONS] = {
&mlx5e_tc_act_accept,
&mlx5e_tc_act_drop,
NULL, /* FLOW_ACTION_TRAP, */
NULL, /* FLOW_ACTION_GOTO, */
NULL, /* FLOW_ACTION_REDIRECT, */
NULL, /* FLOW_ACTION_MIRRED, */
NULL, /* FLOW_ACTION_REDIRECT_INGRESS, */
NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
NULL, /* FLOW_ACTION_VLAN_PUSH, */
NULL, /* FLOW_ACTION_VLAN_POP, */
NULL, /* FLOW_ACTION_VLAN_MANGLE, */
NULL, /* FLOW_ACTION_TUNNEL_ENCAP, */
NULL, /* FLOW_ACTION_TUNNEL_DECAP, */
NULL, /* FLOW_ACTION_MANGLE, */
NULL, /* FLOW_ACTION_ADD, */
NULL, /* FLOW_ACTION_CSUM, */
&mlx5e_tc_act_mark,
};

/**
* mlx5e_tc_act_get() - Get an action parser for an action id.
* @act_id: Flow action id.
* @ns_type: flow namespace type.
*/
struct mlx5e_tc_act *
mlx5e_tc_act_get(enum flow_action_id act_id,
enum mlx5_flow_namespace_type ns_type)
{
struct mlx5e_tc_act **tc_acts;

tc_acts = ns_type == MLX5_FLOW_NAMESPACE_FDB ? tc_acts_fdb : tc_acts_nic;

return tc_acts[act_id];
}

/**
* mlx5e_tc_act_init_parse_state() - Init a new parse_state.
* @parse_state: Parsing state.
* @flow: mlx5e tc flow being handled.
* @flow_action: flow action to parse.
* @extack: to set an error msg.
*
* The same parse_state should be passed to action parsers
* for tracking the current parsing state.
*/
void
mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state,
struct mlx5e_tc_flow *flow,
struct flow_action *flow_action,
struct netlink_ext_ack *extack)
{
memset(parse_state, 0, sizeof(*parse_state));
parse_state->flow = flow;
parse_state->num_actions = flow_action->num_entries;
parse_state->extack = extack;
}
45 changes: 45 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
/* Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */

#ifndef __MLX5_EN_TC_ACT_H__
#define __MLX5_EN_TC_ACT_H__

#include <net/flow_offload.h>
#include <linux/netlink.h>
#include "eswitch.h"

struct mlx5_flow_attr;

struct mlx5e_tc_act_parse_state {
unsigned int num_actions;
struct mlx5e_tc_flow *flow;
struct netlink_ext_ack *extack;
};

struct mlx5e_tc_act {
bool (*can_offload)(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
int act_index);

int (*parse_action)(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
struct mlx5e_priv *priv,
struct mlx5_flow_attr *attr);
};

extern struct mlx5e_tc_act mlx5e_tc_act_drop;
extern struct mlx5e_tc_act mlx5e_tc_act_trap;
extern struct mlx5e_tc_act mlx5e_tc_act_accept;
extern struct mlx5e_tc_act mlx5e_tc_act_mark;

struct mlx5e_tc_act *
mlx5e_tc_act_get(enum flow_action_id act_id,
enum mlx5_flow_namespace_type ns_type);

void
mlx5e_tc_act_init_parse_state(struct mlx5e_tc_act_parse_state *parse_state,
struct mlx5e_tc_flow *flow,
struct flow_action *flow_action,
struct netlink_ext_ack *extack);

#endif /* __MLX5_EN_TC_ACT_H__ */
30 changes: 30 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/drop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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_drop(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
int act_index)
{
return true;
}

static int
tc_act_parse_drop(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
struct mlx5e_priv *priv,
struct mlx5_flow_attr *attr)
{
attr->action |= MLX5_FLOW_CONTEXT_ACTION_DROP |
MLX5_FLOW_CONTEXT_ACTION_COUNT;

return 0;
}

struct mlx5e_tc_act mlx5e_tc_act_drop = {
.can_offload = tc_act_can_offload_drop,
.parse_action = tc_act_parse_drop,
};
35 changes: 35 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mark.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

#include "act.h"
#include "en_tc.h"

static bool
tc_act_can_offload_mark(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
int act_index)
{
if (act->mark & ~MLX5E_TC_FLOW_ID_MASK) {
NL_SET_ERR_MSG_MOD(parse_state->extack, "Bad flow mark, only 16 bit supported");
return false;
}

return true;
}

static int
tc_act_parse_mark(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
struct mlx5e_priv *priv,
struct mlx5_flow_attr *attr)
{
attr->nic_attr->flow_tag = act->mark;
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;

return 0;
}

struct mlx5e_tc_act mlx5e_tc_act_mark = {
.can_offload = tc_act_can_offload_mark,
.parse_action = tc_act_parse_mark,
};
38 changes: 38 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/trap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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_trap(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
int act_index)
{
struct netlink_ext_ack *extack = parse_state->extack;

if (parse_state->num_actions != 1) {
NL_SET_ERR_MSG_MOD(extack, "action trap is supported as a sole action only");
return false;
}

return true;
}

static int
tc_act_parse_trap(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act,
struct mlx5e_priv *priv,
struct mlx5_flow_attr *attr)
{
attr->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
MLX5_FLOW_CONTEXT_ACTION_COUNT;
attr->flags |= MLX5_ESW_ATTR_FLAG_SLOW_PATH;

return 0;
}

struct mlx5e_tc_act mlx5e_tc_act_trap = {
.can_offload = tc_act_can_offload_trap,
.parse_action = tc_act_parse_trap,
};
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define __MLX5_EN_TC_PRIV_H__

#include "en_tc.h"
#include "en/tc/act/act.h"

#define MLX5E_TC_FLOW_BASE (MLX5E_TC_FLAG_LAST_EXPORTED_BIT + 1)

Expand Down Expand Up @@ -37,6 +38,7 @@ struct mlx5e_tc_flow_parse_attr {
struct mlx5e_tc_mod_hdr_acts mod_hdr_acts;
int mirred_ifindex[MLX5_MAX_FLOW_FWD_VPORTS];
struct ethhdr eth;
struct mlx5e_tc_act_parse_state parse_state;
};

/* Helper struct for accessing a struct containing list_head array.
Expand Down
Loading

0 comments on commit fad5479

Please sign in to comment.