Skip to content

Commit

Permalink
mlxsw: core_acl_flex_actions: Add mirror sampler action
Browse files Browse the repository at this point in the history
Add core functionality required to support mirror sampler action in the
policy engine. The switch driver (e.g., 'mlxsw_spectrum') is required to
implement the sampler_add() / sampler_del() callbacks that perform the
necessary configuration before the sampler action can be installed. The
next patch will implement it for Spectrum-{2,3}, while Spectrum-1 will
return an error, given it is not supported.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ido Schimmel authored and David S. Miller committed Mar 16, 2021
1 parent 54d0e96 commit ca19ea6
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
131 changes: 131 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2007,3 +2007,134 @@ int mlxsw_afa_block_append_l4port(struct mlxsw_afa_block *block, bool is_dport,
return 0;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_l4port);

/* Mirror Sampler Action
* ---------------------
* The SAMPLER_ACTION is used to mirror packets with a probability (sampling).
*/

#define MLXSW_AFA_SAMPLER_CODE 0x13
#define MLXSW_AFA_SAMPLER_SIZE 1

/* afa_sampler_mirror_agent
* Mirror (SPAN) agent.
*/
MLXSW_ITEM32(afa, sampler, mirror_agent, 0x04, 0, 3);

#define MLXSW_AFA_SAMPLER_RATE_MAX (BIT(24) - 1)

/* afa_sampler_mirror_probability_rate
* Mirroring probability.
* Valid values are 1 to 2^24 - 1
*/
MLXSW_ITEM32(afa, sampler, mirror_probability_rate, 0x08, 0, 24);

static void mlxsw_afa_sampler_pack(char *payload, u8 mirror_agent, u32 rate)
{
mlxsw_afa_sampler_mirror_agent_set(payload, mirror_agent);
mlxsw_afa_sampler_mirror_probability_rate_set(payload, rate);
}

struct mlxsw_afa_sampler {
struct mlxsw_afa_resource resource;
int span_id;
u8 local_port;
bool ingress;
};

static void mlxsw_afa_sampler_destroy(struct mlxsw_afa_block *block,
struct mlxsw_afa_sampler *sampler)
{
mlxsw_afa_resource_del(&sampler->resource);
block->afa->ops->sampler_del(block->afa->ops_priv, sampler->local_port,
sampler->span_id, sampler->ingress);
kfree(sampler);
}

static void mlxsw_afa_sampler_destructor(struct mlxsw_afa_block *block,
struct mlxsw_afa_resource *resource)
{
struct mlxsw_afa_sampler *sampler;

sampler = container_of(resource, struct mlxsw_afa_sampler, resource);
mlxsw_afa_sampler_destroy(block, sampler);
}

static struct mlxsw_afa_sampler *
mlxsw_afa_sampler_create(struct mlxsw_afa_block *block, u8 local_port,
struct psample_group *psample_group, u32 rate,
u32 trunc_size, bool truncate, bool ingress,
struct netlink_ext_ack *extack)
{
struct mlxsw_afa_sampler *sampler;
int err;

sampler = kzalloc(sizeof(*sampler), GFP_KERNEL);
if (!sampler)
return ERR_PTR(-ENOMEM);

err = block->afa->ops->sampler_add(block->afa->ops_priv, local_port,
psample_group, rate, trunc_size,
truncate, ingress, &sampler->span_id,
extack);
if (err)
goto err_sampler_add;

sampler->ingress = ingress;
sampler->local_port = local_port;
sampler->resource.destructor = mlxsw_afa_sampler_destructor;
mlxsw_afa_resource_add(block, &sampler->resource);
return sampler;

err_sampler_add:
kfree(sampler);
return ERR_PTR(err);
}

static int
mlxsw_afa_block_append_allocated_sampler(struct mlxsw_afa_block *block,
u8 mirror_agent, u32 rate)
{
char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_SAMPLER_CODE,
MLXSW_AFA_SAMPLER_SIZE);

if (IS_ERR(act))
return PTR_ERR(act);
mlxsw_afa_sampler_pack(act, mirror_agent, rate);
return 0;
}

int mlxsw_afa_block_append_sampler(struct mlxsw_afa_block *block, u8 local_port,
struct psample_group *psample_group,
u32 rate, u32 trunc_size, bool truncate,
bool ingress,
struct netlink_ext_ack *extack)
{
struct mlxsw_afa_sampler *sampler;
int err;

if (rate > MLXSW_AFA_SAMPLER_RATE_MAX) {
NL_SET_ERR_MSG_MOD(extack, "Sampling rate is too high");
return -EINVAL;
}

sampler = mlxsw_afa_sampler_create(block, local_port, psample_group,
rate, trunc_size, truncate, ingress,
extack);
if (IS_ERR(sampler))
return PTR_ERR(sampler);

err = mlxsw_afa_block_append_allocated_sampler(block, sampler->span_id,
rate);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Cannot append sampler action");
goto err_append_allocated_sampler;
}

return 0;

err_append_allocated_sampler:
mlxsw_afa_sampler_destroy(block, sampler);
return err;
}
EXPORT_SYMBOL(mlxsw_afa_block_append_sampler);
11 changes: 11 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ struct mlxsw_afa_ops {
u16 *p_policer_index,
struct netlink_ext_ack *extack);
void (*policer_del)(void *priv, u16 policer_index);
int (*sampler_add)(void *priv, u8 local_port,
struct psample_group *psample_group, u32 rate,
u32 trunc_size, bool truncate, bool ingress,
int *p_span_id, struct netlink_ext_ack *extack);
void (*sampler_del)(void *priv, u8 local_port, int span_id,
bool ingress);
bool dummy_first_set;
};

Expand Down Expand Up @@ -92,5 +98,10 @@ int mlxsw_afa_block_append_police(struct mlxsw_afa_block *block,
u32 fa_index, u64 rate_bytes_ps, u32 burst,
u16 *p_policer_index,
struct netlink_ext_ack *extack);
int mlxsw_afa_block_append_sampler(struct mlxsw_afa_block *block, u8 local_port,
struct psample_group *psample_group,
u32 rate, u32 trunc_size, bool truncate,
bool ingress,
struct netlink_ext_ack *extack);

#endif

0 comments on commit ca19ea6

Please sign in to comment.