Commit 353def80 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum_span: Prevent duplicate mirrors

In net commit 8175f7c4736f ("mlxsw: spectrum: Prevent duplicate
mirrors") we prevented the user from mirroring more than once from a
single binding point (port-direction pair).

The fix was essentially reverted in a merge conflict resolution when net
was merged into net-next. Restore it.

Fixes: 03fe2deb ("Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net")
Signed-off-by: default avatarPetr Machata <petrm@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f452518c
...@@ -600,13 +600,17 @@ int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu) ...@@ -600,13 +600,17 @@ int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu)
} }
static struct mlxsw_sp_span_inspected_port * static struct mlxsw_sp_span_inspected_port *
mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port, mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_entry *span_entry) enum mlxsw_sp_span_type type,
struct mlxsw_sp_port *port,
bool bind)
{ {
struct mlxsw_sp_span_inspected_port *p; struct mlxsw_sp_span_inspected_port *p;
list_for_each_entry(p, &span_entry->bound_ports_list, list) list_for_each_entry(p, &span_entry->bound_ports_list, list)
if (port->local_port == p->local_port) if (type == p->type &&
port->local_port == p->local_port &&
bind == p->bound)
return p; return p;
return NULL; return NULL;
} }
...@@ -636,8 +640,22 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port, ...@@ -636,8 +640,22 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
struct mlxsw_sp_span_inspected_port *inspected_port; struct mlxsw_sp_span_inspected_port *inspected_port;
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
char sbib_pl[MLXSW_REG_SBIB_LEN]; char sbib_pl[MLXSW_REG_SBIB_LEN];
int i;
int err; int err;
/* A given (source port, direction) can only be bound to one analyzer,
* so if a binding is requested, check for conflicts.
*/
if (bind)
for (i = 0; i < mlxsw_sp->span.entries_count; i++) {
struct mlxsw_sp_span_entry *curr =
&mlxsw_sp->span.entries[i];
if (mlxsw_sp_span_entry_bound_port_find(curr, type,
port, bind))
return -EEXIST;
}
/* if it is an egress SPAN, bind a shared buffer to it */ /* if it is an egress SPAN, bind a shared buffer to it */
if (type == MLXSW_SP_SPAN_EGRESS) { if (type == MLXSW_SP_SPAN_EGRESS) {
u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp, u32 buffsize = mlxsw_sp_span_mtu_to_buffsize(mlxsw_sp,
...@@ -665,6 +683,7 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port, ...@@ -665,6 +683,7 @@ mlxsw_sp_span_inspected_port_add(struct mlxsw_sp_port *port,
} }
inspected_port->local_port = port->local_port; inspected_port->local_port = port->local_port;
inspected_port->type = type; inspected_port->type = type;
inspected_port->bound = bind;
list_add_tail(&inspected_port->list, &span_entry->bound_ports_list); list_add_tail(&inspected_port->list, &span_entry->bound_ports_list);
return 0; return 0;
...@@ -691,7 +710,8 @@ mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port, ...@@ -691,7 +710,8 @@ mlxsw_sp_span_inspected_port_del(struct mlxsw_sp_port *port,
struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;
char sbib_pl[MLXSW_REG_SBIB_LEN]; char sbib_pl[MLXSW_REG_SBIB_LEN];
inspected_port = mlxsw_sp_span_entry_bound_port_find(port, span_entry); inspected_port = mlxsw_sp_span_entry_bound_port_find(span_entry, type,
port, bind);
if (!inspected_port) if (!inspected_port)
return; return;
......
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