// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2020 Mellanox Technologies Inc. All rights reserved. */

#include "mlx5_core.h"
#include "eswitch.h"
#include "helper.h"
#include "ofld.h"

static bool
esw_acl_ingress_prio_tag_enabled(struct mlx5_eswitch *esw,
				 const struct mlx5_vport *vport)
{
	return (MLX5_CAP_GEN(esw->dev, prio_tag_required) &&
		mlx5_eswitch_is_vf_vport(esw, vport->vport));
}

static int esw_acl_ingress_prio_tag_create(struct mlx5_eswitch *esw,
					   struct mlx5_vport *vport)
{
	struct mlx5_flow_act flow_act = {};
	struct mlx5_flow_spec *spec;
	int err = 0;

	/* For prio tag mode, there is only 1 FTEs:
	 * 1) Untagged packets - push prio tag VLAN and modify metadata if
	 * required, allow
	 * Unmatched traffic is allowed by default
	 */
	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
	if (!spec)
		return -ENOMEM;

	/* Untagged packets - push prio tag VLAN, allow */
	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.cvlan_tag);
	MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 0);
	spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS;
	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH |
			  MLX5_FLOW_CONTEXT_ACTION_ALLOW;
	flow_act.vlan[0].ethtype = ETH_P_8021Q;
	flow_act.vlan[0].vid = 0;
	flow_act.vlan[0].prio = 0;

	if (vport->ingress.offloads.modify_metadata_rule) {
		flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
		flow_act.modify_hdr = vport->ingress.offloads.modify_metadata;
	}

	vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec,
							&flow_act, NULL, 0);
	if (IS_ERR(vport->ingress.allow_rule)) {
		err = PTR_ERR(vport->ingress.allow_rule);
		esw_warn(esw->dev,
			 "vport[%d] configure ingress untagged allow rule, err(%d)\n",
			 vport->vport, err);
		vport->ingress.allow_rule = NULL;
	}

	kvfree(spec);
	return err;
}

static int esw_acl_ingress_mod_metadata_create(struct mlx5_eswitch *esw,
					       struct mlx5_vport *vport)
{
	u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
	struct mlx5_flow_act flow_act = {};
	int err = 0;
	u32 key;

	key = mlx5_eswitch_get_vport_metadata_for_match(esw, vport->vport);
	key >>= ESW_SOURCE_PORT_METADATA_OFFSET;

	MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);
	MLX5_SET(set_action_in, action, field,
		 MLX5_ACTION_IN_FIELD_METADATA_REG_C_0);
	MLX5_SET(set_action_in, action, data, key);
	MLX5_SET(set_action_in, action, offset,
		 ESW_SOURCE_PORT_METADATA_OFFSET);
	MLX5_SET(set_action_in, action, length,
		 ESW_SOURCE_PORT_METADATA_BITS);

	vport->ingress.offloads.modify_metadata =
		mlx5_modify_header_alloc(esw->dev, MLX5_FLOW_NAMESPACE_ESW_INGRESS,
					 1, action);
	if (IS_ERR(vport->ingress.offloads.modify_metadata)) {
		err = PTR_ERR(vport->ingress.offloads.modify_metadata);
		esw_warn(esw->dev,
			 "failed to alloc modify header for vport %d ingress acl (%d)\n",
			 vport->vport, err);
		return err;
	}

	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR | MLX5_FLOW_CONTEXT_ACTION_ALLOW;
	flow_act.modify_hdr = vport->ingress.offloads.modify_metadata;
	flow_act.fg = vport->ingress.offloads.metadata_allmatch_grp;
	vport->ingress.offloads.modify_metadata_rule =
				mlx5_add_flow_rules(vport->ingress.acl,
						    NULL, &flow_act, NULL, 0);
	if (IS_ERR(vport->ingress.offloads.modify_metadata_rule)) {
		err = PTR_ERR(vport->ingress.offloads.modify_metadata_rule);
		esw_warn(esw->dev,
			 "failed to add setting metadata rule for vport %d ingress acl, err(%d)\n",
			 vport->vport, err);
		mlx5_modify_header_dealloc(esw->dev, vport->ingress.offloads.modify_metadata);
		vport->ingress.offloads.modify_metadata_rule = NULL;
	}
	return err;
}

static void esw_acl_ingress_mod_metadata_destroy(struct mlx5_eswitch *esw,
						 struct mlx5_vport *vport)
{
	if (!vport->ingress.offloads.modify_metadata_rule)
		return;

	mlx5_del_flow_rules(vport->ingress.offloads.modify_metadata_rule);
	mlx5_modify_header_dealloc(esw->dev, vport->ingress.offloads.modify_metadata);
	vport->ingress.offloads.modify_metadata_rule = NULL;
}

static int esw_acl_ingress_src_port_drop_create(struct mlx5_eswitch *esw,
						struct mlx5_vport *vport)
{
	struct mlx5_flow_act flow_act = {};
	struct mlx5_flow_handle *flow_rule;
	int err = 0;

	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
	flow_act.fg = vport->ingress.offloads.drop_grp;
	flow_rule = mlx5_add_flow_rules(vport->ingress.acl, NULL, &flow_act, NULL, 0);
	if (IS_ERR(flow_rule)) {
		err = PTR_ERR(flow_rule);
		goto out;
	}

	vport->ingress.offloads.drop_rule = flow_rule;
out:
	return err;
}

static void esw_acl_ingress_src_port_drop_destroy(struct mlx5_eswitch *esw,
						  struct mlx5_vport *vport)
{
	if (!vport->ingress.offloads.drop_rule)
		return;

	mlx5_del_flow_rules(vport->ingress.offloads.drop_rule);
	vport->ingress.offloads.drop_rule = NULL;
}

static int esw_acl_ingress_ofld_rules_create(struct mlx5_eswitch *esw,
					     struct mlx5_vport *vport)
{
	int err;

	if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
		err = esw_acl_ingress_mod_metadata_create(esw, vport);
		if (err) {
			esw_warn(esw->dev,
				 "vport(%d) create ingress modify metadata, err(%d)\n",
				 vport->vport, err);
			return err;
		}
	}

	if (esw_acl_ingress_prio_tag_enabled(esw, vport)) {
		err = esw_acl_ingress_prio_tag_create(esw, vport);
		if (err) {
			esw_warn(esw->dev,
				 "vport(%d) create ingress prio tag rule, err(%d)\n",
				 vport->vport, err);
			goto prio_tag_err;
		}
	}

	return 0;

prio_tag_err:
	esw_acl_ingress_mod_metadata_destroy(esw, vport);
	return err;
}

static void esw_acl_ingress_ofld_rules_destroy(struct mlx5_eswitch *esw,
					       struct mlx5_vport *vport)
{
	esw_acl_ingress_allow_rule_destroy(vport);
	esw_acl_ingress_mod_metadata_destroy(esw, vport);
	esw_acl_ingress_src_port_drop_destroy(esw, vport);
}

static int esw_acl_ingress_ofld_groups_create(struct mlx5_eswitch *esw,
					      struct mlx5_vport *vport)
{
	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
	struct mlx5_flow_group *g;
	void *match_criteria;
	u32 *flow_group_in;
	u32 flow_index = 0;
	int ret = 0;

	flow_group_in = kvzalloc(inlen, GFP_KERNEL);
	if (!flow_group_in)
		return -ENOMEM;

	if (vport->vport == MLX5_VPORT_UPLINK) {
		/* This group can hold an FTE to drop all traffic.
		 * Need in case LAG is enabled.
		 */
		MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
		MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);

		g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
		if (IS_ERR(g)) {
			ret = PTR_ERR(g);
			esw_warn(esw->dev, "vport[%d] ingress create drop flow group, err(%d)\n",
				 vport->vport, ret);
			goto drop_err;
		}
		vport->ingress.offloads.drop_grp = g;
		flow_index++;
	}

	if (esw_acl_ingress_prio_tag_enabled(esw, vport)) {
		/* This group is to hold FTE to match untagged packets when prio_tag
		 * is enabled.
		 */
		memset(flow_group_in, 0, inlen);
		match_criteria = MLX5_ADDR_OF(create_flow_group_in,
					      flow_group_in, match_criteria);
		MLX5_SET(create_flow_group_in, flow_group_in,
			 match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
		MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.cvlan_tag);
		MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
		MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);

		g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
		if (IS_ERR(g)) {
			ret = PTR_ERR(g);
			esw_warn(esw->dev, "vport[%d] ingress create untagged flow group, err(%d)\n",
				 vport->vport, ret);
			goto prio_tag_err;
		}
		vport->ingress.offloads.metadata_prio_tag_grp = g;
		flow_index++;
	}

	if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
		/* This group holds an FTE with no match to add metadata for
		 * tagged packets if prio-tag is enabled, or for all untagged
		 * traffic in case prio-tag is disabled.
		 */
		memset(flow_group_in, 0, inlen);
		MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
		MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);

		g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
		if (IS_ERR(g)) {
			ret = PTR_ERR(g);
			esw_warn(esw->dev, "vport[%d] ingress create drop flow group, err(%d)\n",
				 vport->vport, ret);
			goto metadata_err;
		}
		vport->ingress.offloads.metadata_allmatch_grp = g;
	}

	kvfree(flow_group_in);
	return 0;

metadata_err:
	if (!IS_ERR_OR_NULL(vport->ingress.offloads.metadata_prio_tag_grp)) {
		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_prio_tag_grp);
		vport->ingress.offloads.metadata_prio_tag_grp = NULL;
	}
prio_tag_err:
	if (!IS_ERR_OR_NULL(vport->ingress.offloads.drop_grp)) {
		mlx5_destroy_flow_group(vport->ingress.offloads.drop_grp);
		vport->ingress.offloads.drop_grp = NULL;
	}
drop_err:
	kvfree(flow_group_in);
	return ret;
}

static void esw_acl_ingress_ofld_groups_destroy(struct mlx5_vport *vport)
{
	if (vport->ingress.offloads.metadata_allmatch_grp) {
		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_allmatch_grp);
		vport->ingress.offloads.metadata_allmatch_grp = NULL;
	}

	if (vport->ingress.offloads.metadata_prio_tag_grp) {
		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_prio_tag_grp);
		vport->ingress.offloads.metadata_prio_tag_grp = NULL;
	}

	if (vport->ingress.offloads.drop_grp) {
		mlx5_destroy_flow_group(vport->ingress.offloads.drop_grp);
		vport->ingress.offloads.drop_grp = NULL;
	}
}

int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw,
			       struct mlx5_vport *vport)
{
	int num_ftes = 0;
	int err;

	if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
	    !esw_acl_ingress_prio_tag_enabled(esw, vport))
		return 0;

	esw_acl_ingress_allow_rule_destroy(vport);

	if (mlx5_eswitch_vport_match_metadata_enabled(esw))
		num_ftes++;
	if (vport->vport == MLX5_VPORT_UPLINK)
		num_ftes++;
	if (esw_acl_ingress_prio_tag_enabled(esw, vport))
		num_ftes++;

	vport->ingress.acl = esw_acl_table_create(esw, vport,
						  MLX5_FLOW_NAMESPACE_ESW_INGRESS,
						  num_ftes);
	if (IS_ERR(vport->ingress.acl)) {
		err = PTR_ERR(vport->ingress.acl);
		vport->ingress.acl = NULL;
		return err;
	}

	err = esw_acl_ingress_ofld_groups_create(esw, vport);
	if (err)
		goto group_err;

	esw_debug(esw->dev,
		  "vport[%d] configure ingress rules\n", vport->vport);

	err = esw_acl_ingress_ofld_rules_create(esw, vport);
	if (err)
		goto rules_err;

	return 0;

rules_err:
	esw_acl_ingress_ofld_groups_destroy(vport);
group_err:
	esw_acl_ingress_table_destroy(vport);
	return err;
}

void esw_acl_ingress_ofld_cleanup(struct mlx5_eswitch *esw,
				  struct mlx5_vport *vport)
{
	esw_acl_ingress_ofld_rules_destroy(esw, vport);
	esw_acl_ingress_ofld_groups_destroy(vport);
	esw_acl_ingress_table_destroy(vport);
}

/* Caller must hold rtnl_lock */
int mlx5_esw_acl_ingress_vport_bond_update(struct mlx5_eswitch *esw, u16 vport_num,
					   u32 metadata)
{
	struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num);
	int err;

	if (WARN_ON_ONCE(IS_ERR(vport))) {
		esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num);
		err = PTR_ERR(vport);
		goto out;
	}

	esw_acl_ingress_ofld_rules_destroy(esw, vport);

	vport->metadata = metadata ? metadata : vport->default_metadata;

	/* Recreate ingress acl rules with vport->metadata */
	err = esw_acl_ingress_ofld_rules_create(esw, vport);
	if (err)
		goto out;

	return 0;

out:
	vport->metadata = vport->default_metadata;
	return err;
}

int mlx5_esw_acl_ingress_vport_drop_rule_create(struct mlx5_eswitch *esw, u16 vport_num)
{
	struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num);

	if (IS_ERR(vport)) {
		esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num);
		return PTR_ERR(vport);
	}

	return esw_acl_ingress_src_port_drop_create(esw, vport);
}

void mlx5_esw_acl_ingress_vport_drop_rule_destroy(struct mlx5_eswitch *esw, u16 vport_num)
{
	struct mlx5_vport *vport = mlx5_eswitch_get_vport(esw, vport_num);

	if (WARN_ON_ONCE(IS_ERR(vport))) {
		esw_warn(esw->dev, "vport(%d) invalid!\n", vport_num);
		return;
	}

	esw_acl_ingress_src_port_drop_destroy(esw, vport);
}
