Commit 54a92385 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

mlxsw: spectrum_qdisc: Offload action trap for qevents

When offloading action trap on a qevent, pass to_dev of NULL to the SPAN
module to trigger the mirror to the CPU port. Query the buffer drops
policer and use it for policing of the trapped traffic.
Signed-off-by: default avatarPetr Machata <petrm@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6687e953
...@@ -984,6 +984,10 @@ struct mlxsw_sp_mall_mirror_entry { ...@@ -984,6 +984,10 @@ struct mlxsw_sp_mall_mirror_entry {
int span_id; int span_id;
}; };
struct mlxsw_sp_mall_trap_entry {
int span_id;
};
struct mlxsw_sp_mall_entry { struct mlxsw_sp_mall_entry {
struct list_head list; struct list_head list;
unsigned long cookie; unsigned long cookie;
...@@ -992,6 +996,7 @@ struct mlxsw_sp_mall_entry { ...@@ -992,6 +996,7 @@ struct mlxsw_sp_mall_entry {
bool ingress; bool ingress;
union { union {
struct mlxsw_sp_mall_mirror_entry mirror; struct mlxsw_sp_mall_mirror_entry mirror;
struct mlxsw_sp_mall_trap_entry trap;
struct mlxsw_sp_port_sample sample; struct mlxsw_sp_port_sample sample;
}; };
struct rcu_head rcu; struct rcu_head rcu;
...@@ -1199,6 +1204,8 @@ int ...@@ -1199,6 +1204,8 @@ int
mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core, mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core,
const struct devlink_trap_policer *policer, const struct devlink_trap_policer *policer,
u64 *p_drops); u64 *p_drops);
int mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id,
bool *p_enabled, u16 *p_hw_id);
static inline struct net *mlxsw_sp_net(struct mlxsw_sp *mlxsw_sp) static inline struct net *mlxsw_sp_net(struct mlxsw_sp *mlxsw_sp)
{ {
......
...@@ -1289,19 +1289,18 @@ struct mlxsw_sp_qevent_binding { ...@@ -1289,19 +1289,18 @@ struct mlxsw_sp_qevent_binding {
static LIST_HEAD(mlxsw_sp_qevent_block_cb_list); static LIST_HEAD(mlxsw_sp_qevent_block_cb_list);
static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_qevent_span_configure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mall_entry *mall_entry, struct mlxsw_sp_mall_entry *mall_entry,
struct mlxsw_sp_qevent_binding *qevent_binding) struct mlxsw_sp_qevent_binding *qevent_binding,
const struct mlxsw_sp_span_agent_parms *agent_parms,
int *p_span_id)
{ {
struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port;
struct mlxsw_sp_span_trigger_parms trigger_parms = {}; struct mlxsw_sp_span_trigger_parms trigger_parms = {};
struct mlxsw_sp_span_agent_parms agent_parms = {
.to_dev = mall_entry->mirror.to_dev,
};
int span_id; int span_id;
int err; int err;
err = mlxsw_sp_span_agent_get(mlxsw_sp, &span_id, &agent_parms); err = mlxsw_sp_span_agent_get(mlxsw_sp, &span_id, agent_parms);
if (err) if (err)
return err; return err;
...@@ -1320,7 +1319,7 @@ static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp, ...@@ -1320,7 +1319,7 @@ static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
goto err_trigger_enable; goto err_trigger_enable;
mall_entry->mirror.span_id = span_id; *p_span_id = span_id;
return 0; return 0;
err_trigger_enable: err_trigger_enable:
...@@ -1333,13 +1332,13 @@ static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp, ...@@ -1333,13 +1332,13 @@ static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp,
return err; return err;
} }
static void mlxsw_sp_qevent_mirror_deconfigure(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_qevent_span_deconfigure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mall_entry *mall_entry, struct mlxsw_sp_qevent_binding *qevent_binding,
struct mlxsw_sp_qevent_binding *qevent_binding) int span_id)
{ {
struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port = qevent_binding->mlxsw_sp_port;
struct mlxsw_sp_span_trigger_parms trigger_parms = { struct mlxsw_sp_span_trigger_parms trigger_parms = {
.span_id = mall_entry->mirror.span_id, .span_id = span_id,
}; };
mlxsw_sp_span_trigger_disable(mlxsw_sp_port, qevent_binding->span_trigger, mlxsw_sp_span_trigger_disable(mlxsw_sp_port, qevent_binding->span_trigger,
...@@ -1347,7 +1346,51 @@ static void mlxsw_sp_qevent_mirror_deconfigure(struct mlxsw_sp *mlxsw_sp, ...@@ -1347,7 +1346,51 @@ static void mlxsw_sp_qevent_mirror_deconfigure(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_span_agent_unbind(mlxsw_sp, qevent_binding->span_trigger, mlxsw_sp_port, mlxsw_sp_span_agent_unbind(mlxsw_sp, qevent_binding->span_trigger, mlxsw_sp_port,
&trigger_parms); &trigger_parms);
mlxsw_sp_span_analyzed_port_put(mlxsw_sp_port, true); mlxsw_sp_span_analyzed_port_put(mlxsw_sp_port, true);
mlxsw_sp_span_agent_put(mlxsw_sp, mall_entry->mirror.span_id); mlxsw_sp_span_agent_put(mlxsw_sp, span_id);
}
static int mlxsw_sp_qevent_mirror_configure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mall_entry *mall_entry,
struct mlxsw_sp_qevent_binding *qevent_binding)
{
struct mlxsw_sp_span_agent_parms agent_parms = {
.to_dev = mall_entry->mirror.to_dev,
};
return mlxsw_sp_qevent_span_configure(mlxsw_sp, mall_entry, qevent_binding,
&agent_parms, &mall_entry->mirror.span_id);
}
static void mlxsw_sp_qevent_mirror_deconfigure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mall_entry *mall_entry,
struct mlxsw_sp_qevent_binding *qevent_binding)
{
mlxsw_sp_qevent_span_deconfigure(mlxsw_sp, qevent_binding, mall_entry->mirror.span_id);
}
static int mlxsw_sp_qevent_trap_configure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mall_entry *mall_entry,
struct mlxsw_sp_qevent_binding *qevent_binding)
{
struct mlxsw_sp_span_agent_parms agent_parms = {};
int err;
err = mlxsw_sp_trap_group_policer_hw_id_get(mlxsw_sp,
DEVLINK_TRAP_GROUP_GENERIC_ID_BUFFER_DROPS,
&agent_parms.policer_enable,
&agent_parms.policer_id);
if (err)
return err;
return mlxsw_sp_qevent_span_configure(mlxsw_sp, mall_entry, qevent_binding,
&agent_parms, &mall_entry->trap.span_id);
}
static void mlxsw_sp_qevent_trap_deconfigure(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_mall_entry *mall_entry,
struct mlxsw_sp_qevent_binding *qevent_binding)
{
mlxsw_sp_qevent_span_deconfigure(mlxsw_sp, qevent_binding, mall_entry->trap.span_id);
} }
static int mlxsw_sp_qevent_entry_configure(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_qevent_entry_configure(struct mlxsw_sp *mlxsw_sp,
...@@ -1357,6 +1400,8 @@ static int mlxsw_sp_qevent_entry_configure(struct mlxsw_sp *mlxsw_sp, ...@@ -1357,6 +1400,8 @@ static int mlxsw_sp_qevent_entry_configure(struct mlxsw_sp *mlxsw_sp,
switch (mall_entry->type) { switch (mall_entry->type) {
case MLXSW_SP_MALL_ACTION_TYPE_MIRROR: case MLXSW_SP_MALL_ACTION_TYPE_MIRROR:
return mlxsw_sp_qevent_mirror_configure(mlxsw_sp, mall_entry, qevent_binding); return mlxsw_sp_qevent_mirror_configure(mlxsw_sp, mall_entry, qevent_binding);
case MLXSW_SP_MALL_ACTION_TYPE_TRAP:
return mlxsw_sp_qevent_trap_configure(mlxsw_sp, mall_entry, qevent_binding);
default: default:
/* This should have been validated away. */ /* This should have been validated away. */
WARN_ON(1); WARN_ON(1);
...@@ -1371,6 +1416,8 @@ static void mlxsw_sp_qevent_entry_deconfigure(struct mlxsw_sp *mlxsw_sp, ...@@ -1371,6 +1416,8 @@ static void mlxsw_sp_qevent_entry_deconfigure(struct mlxsw_sp *mlxsw_sp,
switch (mall_entry->type) { switch (mall_entry->type) {
case MLXSW_SP_MALL_ACTION_TYPE_MIRROR: case MLXSW_SP_MALL_ACTION_TYPE_MIRROR:
return mlxsw_sp_qevent_mirror_deconfigure(mlxsw_sp, mall_entry, qevent_binding); return mlxsw_sp_qevent_mirror_deconfigure(mlxsw_sp, mall_entry, qevent_binding);
case MLXSW_SP_MALL_ACTION_TYPE_TRAP:
return mlxsw_sp_qevent_trap_deconfigure(mlxsw_sp, mall_entry, qevent_binding);
default: default:
WARN_ON(1); WARN_ON(1);
return; return;
...@@ -1490,6 +1537,8 @@ static int mlxsw_sp_qevent_mall_replace(struct mlxsw_sp *mlxsw_sp, ...@@ -1490,6 +1537,8 @@ static int mlxsw_sp_qevent_mall_replace(struct mlxsw_sp *mlxsw_sp,
if (act->id == FLOW_ACTION_MIRRED) { if (act->id == FLOW_ACTION_MIRRED) {
mall_entry->type = MLXSW_SP_MALL_ACTION_TYPE_MIRROR; mall_entry->type = MLXSW_SP_MALL_ACTION_TYPE_MIRROR;
mall_entry->mirror.to_dev = act->dev; mall_entry->mirror.to_dev = act->dev;
} else if (act->id == FLOW_ACTION_TRAP) {
mall_entry->type = MLXSW_SP_MALL_ACTION_TYPE_TRAP;
} else { } else {
NL_SET_ERR_MSG(f->common.extack, "Unsupported action"); NL_SET_ERR_MSG(f->common.extack, "Unsupported action");
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
......
...@@ -1675,6 +1675,32 @@ mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core, ...@@ -1675,6 +1675,32 @@ mlxsw_sp_trap_policer_counter_get(struct mlxsw_core *mlxsw_core,
return 0; return 0;
} }
int mlxsw_sp_trap_group_policer_hw_id_get(struct mlxsw_sp *mlxsw_sp, u16 id,
bool *p_enabled, u16 *p_hw_id)
{
struct mlxsw_sp_trap_policer_item *pol_item;
struct mlxsw_sp_trap_group_item *gr_item;
u32 pol_id;
gr_item = mlxsw_sp_trap_group_item_lookup(mlxsw_sp, id);
if (!gr_item)
return -ENOENT;
pol_id = gr_item->group.init_policer_id;
if (!pol_id) {
*p_enabled = false;
return 0;
}
pol_item = mlxsw_sp_trap_policer_item_lookup(mlxsw_sp, pol_id);
if (WARN_ON(!pol_item))
return -ENOENT;
*p_enabled = true;
*p_hw_id = pol_item->hw_id;
return 0;
}
static const struct mlxsw_sp_trap_group_item static const struct mlxsw_sp_trap_group_item
mlxsw_sp1_trap_group_items_arr[] = { mlxsw_sp1_trap_group_items_arr[] = {
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment