Commit 163b766f authored by Roi Dayan's avatar Roi Dayan Committed by Saeed Mahameed
Browse files

net/mlx5e: Add mpls push/pop to tc action infra



Add parsing support by implementing struct mlx5e_tc_act
for this action.

Signed-off-by: default avatarRoi Dayan <roid@nvidia.com>
Reviewed-by: default avatarOz Shlomo <ozsh@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 8ee72638
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ mlx5_core-$(CONFIG_MLX5_CLS_ACT) += en_tc.o en/rep/tc.o en/rep/neigh.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 en/tc/act/goto.o \
					en/tc/act/tun.o en/tc/act/csum.o en/tc/act/pedit.o \
					en/tc/act/vlan.o en/tc/act/vlan_mangle.o
					en/tc/act/vlan.o en/tc/act/vlan_mangle.o en/tc/act/mpls.o

mlx5_core-$(CONFIG_MLX5_TC_CT)	     += en/tc_ct.o
mlx5_core-$(CONFIG_MLX5_TC_SAMPLE)   += en/tc/sample.o
+11 −0
Original line number Diff line number Diff line
@@ -23,6 +23,17 @@ static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
	&mlx5e_tc_act_pedit,
	&mlx5e_tc_act_pedit,
	&mlx5e_tc_act_csum,
	NULL, /* FLOW_ACTION_MARK, */
	NULL, /* FLOW_ACTION_PTYPE, */
	NULL, /* FLOW_ACTION_PRIORITY, */
	NULL, /* FLOW_ACTION_WAKE, */
	NULL, /* FLOW_ACTION_QUEUE, */
	NULL, /* FLOW_ACTION_SAMPLE, */
	NULL, /* FLOW_ACTION_POLICE, */
	NULL, /* FLOW_ACTION_CT, */
	NULL, /* FLOW_ACTION_CT_METADATA, */
	&mlx5e_tc_act_mpls_push,
	&mlx5e_tc_act_mpls_pop,
};

/* Must be aligned with enum flow_action_id. */
+3 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ struct mlx5e_tc_act_parse_state {
	struct netlink_ext_ack *extack;
	bool encap;
	bool decap;
	bool mpls_push;
	const struct ip_tunnel_info *tun_info;
	struct pedit_headers_action hdrs[__PEDIT_CMD_MAX];
};
@@ -44,6 +45,8 @@ extern struct mlx5e_tc_act mlx5e_tc_act_csum;
extern struct mlx5e_tc_act mlx5e_tc_act_pedit;
extern struct mlx5e_tc_act mlx5e_tc_act_vlan;
extern struct mlx5e_tc_act mlx5e_tc_act_vlan_mangle;
extern struct mlx5e_tc_act mlx5e_tc_act_mpls_push;
extern struct mlx5e_tc_act mlx5e_tc_act_mpls_pop;

struct mlx5e_tc_act *
mlx5e_tc_act_get(enum flow_action_id act_id,
+86 −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 <net/bareudp.h>
#include "act.h"
#include "en/tc_priv.h"

static bool
tc_act_can_offload_mpls_push(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;
	struct mlx5e_priv *priv = parse_state->flow->priv;

	if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev, reformat_l2_to_l3_tunnel) ||
	    act->mpls_push.proto != htons(ETH_P_MPLS_UC)) {
		NL_SET_ERR_MSG_MOD(extack, "mpls push is supported only for mpls_uc protocol");
		return false;
	}

	return true;
}

static int
tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
		       const struct flow_action_entry *act,
		       struct mlx5e_priv *priv,
		       struct mlx5_flow_attr *attr)
{
	parse_state->mpls_push = true;

	return 0;
}

static bool
tc_act_can_offload_mpls_pop(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;
	struct mlx5e_tc_flow *flow = parse_state->flow;
	struct net_device *filter_dev;

	filter_dev = flow->attr->parse_attr->filter_dev;

	/* we only support mpls pop if it is the first action
	 * and the filter net device is bareudp. Subsequent
	 * actions can be pedit and the last can be mirred
	 * egress redirect.
	 */
	if (act_index) {
		NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only as first action");
		return false;
	}

	if (!netif_is_bareudp(filter_dev)) {
		NL_SET_ERR_MSG_MOD(extack, "mpls pop supported only on bareudp devices");
		return false;
	}

	return true;
}

static int
tc_act_parse_mpls_pop(struct mlx5e_tc_act_parse_state *parse_state,
		      const struct flow_action_entry *act,
		      struct mlx5e_priv *priv,
		      struct mlx5_flow_attr *attr)
{
	attr->parse_attr->eth.h_proto = act->mpls_pop.proto;
	attr->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
	flow_flag_set(parse_state->flow, L3_TO_L2_DECAP);

	return 0;
}

struct mlx5e_tc_act mlx5e_tc_act_mpls_push = {
	.can_offload = tc_act_can_offload_mpls_push,
	.parse_action = tc_act_parse_mpls_push,
};

struct mlx5e_tc_act mlx5e_tc_act_mpls_pop = {
	.can_offload = tc_act_can_offload_mpls_pop,
	.parse_action = tc_act_parse_mpls_pop,
};
+1 −33
Original line number Diff line number Diff line
@@ -3481,7 +3481,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
	struct mlx5e_tc_act *tc_act;
	int err, i, if_count = 0;
	bool ptype_host = false;
	bool mpls_push = false;

	err = flow_action_supported(flow_action, extack);
	if (err)
@@ -3505,37 +3504,6 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,

			ptype_host = true;
			break;
		case FLOW_ACTION_MPLS_PUSH:
			if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
							reformat_l2_to_l3_tunnel) ||
			    act->mpls_push.proto != htons(ETH_P_MPLS_UC)) {
				NL_SET_ERR_MSG_MOD(extack,
						   "mpls push is supported only for mpls_uc protocol");
				return -EOPNOTSUPP;
			}
			mpls_push = true;
			break;
		case FLOW_ACTION_MPLS_POP:
			/* we only support mpls pop if it is the first action
			 * and the filter net device is bareudp. Subsequent
			 * actions can be pedit and the last can be mirred
			 * egress redirect.
			 */
			if (i) {
				NL_SET_ERR_MSG_MOD(extack,
						   "mpls pop supported only as first action");
				return -EOPNOTSUPP;
			}
			if (!netif_is_bareudp(parse_attr->filter_dev)) {
				NL_SET_ERR_MSG_MOD(extack,
						   "mpls pop supported only on bareudp devices");
				return -EOPNOTSUPP;
			}

			parse_attr->eth.h_proto = act->mpls_pop.proto;
			attr->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
			flow_flag_set(flow, L3_TO_L2_DECAP);
			break;
		case FLOW_ACTION_REDIRECT_INGRESS: {
			struct net_device *out_dev;

@@ -3594,7 +3562,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
				return -EINVAL;
			}

			if (mpls_push && !netif_is_bareudp(out_dev)) {
			if (parse_state->mpls_push && !netif_is_bareudp(out_dev)) {
				NL_SET_ERR_MSG_MOD(extack,
						   "mpls is supported only through a bareudp device");
				return -EOPNOTSUPP;