Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 079c9f39 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller
Browse files

mlxsw: spectrum: Keep mirror netdev in mlxsw_sp_span_entry



Currently the only mirror action supported by mlxsw is mirror to another
mlxsw physical port. Correspondingly, span_entry, which tracks each
mlxsw mirror in the system, currently holds a u8 number of the
destination port.

To extend this system to mirror to gretap and ip6gretap netdevices, have
struct mlxsw_sp_span_entry actually hold the destination netdevice
itself.

This change then trickles down in obvious manner to SPAN module API and
mirror-related interfaces in struct mlxsw_afa_ops.

To prevent use of invalid pointer, NETDEV_UNREGISTER needs to be hooked
and the corresponding SPAN entry invalidated.

Signed-off-by: default avatarPetr Machata <petrm@mellanox.com>
Reviewed-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7b2ef81f
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -863,9 +863,8 @@ mlxsw_afa_mirror_destructor(struct mlxsw_afa_block *block,
}

static struct mlxsw_afa_mirror *
mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
			u8 local_in_port, u8 local_out_port,
			bool ingress)
mlxsw_afa_mirror_create(struct mlxsw_afa_block *block, u8 local_in_port,
			const struct net_device *out_dev, bool ingress)
{
	struct mlxsw_afa_mirror *mirror;
	int err;
@@ -875,7 +874,7 @@ mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
		return ERR_PTR(-ENOMEM);

	err = block->afa->ops->mirror_add(block->afa->ops_priv,
					  local_in_port, local_out_port,
					  local_in_port, out_dev,
					  ingress, &mirror->span_id);
	if (err)
		goto err_mirror_add;
@@ -907,13 +906,13 @@ mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
}

int
mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
			      u8 local_in_port, u8 local_out_port, bool ingress)
mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block, u8 local_in_port,
			      const struct net_device *out_dev, bool ingress)
{
	struct mlxsw_afa_mirror *mirror;
	int err;

	mirror = mlxsw_afa_mirror_create(block, local_in_port, local_out_port,
	mirror = mlxsw_afa_mirror_create(block, local_in_port, out_dev,
					 ingress);
	if (IS_ERR(mirror))
		return PTR_ERR(mirror);
+5 −2
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#define _MLXSW_CORE_ACL_FLEX_ACTIONS_H

#include <linux/types.h>
#include <linux/netdevice.h>

struct mlxsw_afa;
struct mlxsw_afa_block;
@@ -48,7 +49,8 @@ struct mlxsw_afa_ops {
	void (*kvdl_fwd_entry_del)(void *priv, u32 kvdl_index);
	int (*counter_index_get)(void *priv, unsigned int *p_counter_index);
	void (*counter_index_put)(void *priv, unsigned int counter_index);
	int (*mirror_add)(void *priv, u8 locol_in_port, u8 local_out_port,
	int (*mirror_add)(void *priv, u8 local_in_port,
			  const struct net_device *out_dev,
			  bool ingress, int *p_span_id);
	void (*mirror_del)(void *priv, u8 local_in_port, int span_id,
			   bool ingress);
@@ -70,7 +72,8 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
					    u16 trap_id);
int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
				  u8 local_in_port, u8 local_out_port,
				  u8 local_in_port,
				  const struct net_device *out_dev,
				  bool ingress);
int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
			       u8 local_port, bool in_port);
+8 −3
Original line number Diff line number Diff line
@@ -1258,7 +1258,6 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
				      bool ingress)
{
	enum mlxsw_sp_span_type span_type;
	struct mlxsw_sp_port *to_port;
	struct net_device *to_dev;

	to_dev = tcf_mirred_dev(a);
@@ -1271,11 +1270,10 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port,
		netdev_err(mlxsw_sp_port->dev, "Cannot mirror to a non-spectrum port");
		return -EOPNOTSUPP;
	}
	to_port = netdev_priv(to_dev);

	mirror->ingress = ingress;
	span_type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
	return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_port, span_type,
	return mlxsw_sp_span_mirror_add(mlxsw_sp_port, to_dev, span_type,
					true, &mirror->span_id);
}

@@ -4638,10 +4636,17 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
				    unsigned long event, void *ptr)
{
	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
	struct mlxsw_sp_span_entry *span_entry;
	struct mlxsw_sp *mlxsw_sp;
	int err = 0;

	mlxsw_sp = container_of(nb, struct mlxsw_sp, netdevice_nb);
	if (event == NETDEV_UNREGISTER) {
		span_entry = mlxsw_sp_span_entry_find_by_port(mlxsw_sp, dev);
		if (span_entry)
			mlxsw_sp_span_entry_invalidate(mlxsw_sp, span_entry);
	}

	if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev))
		err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev,
						       event, ptr);
+1 −1
Original line number Diff line number Diff line
@@ -590,7 +590,7 @@ int mlxsw_sp_acl_rulei_act_mirror(struct mlxsw_sp *mlxsw_sp,

	return mlxsw_afa_block_append_mirror(rulei->act_block,
					     in_port->local_port,
					     out_port->local_port,
					     out_dev,
					     binding->ingress);
}

+4 −4
Original line number Diff line number Diff line
@@ -126,18 +126,18 @@ mlxsw_sp_act_counter_index_put(void *priv, unsigned int counter_index)
}

static int
mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port, u8 local_out_port,
mlxsw_sp_act_mirror_add(void *priv, u8 local_in_port,
			const struct net_device *out_dev,
			bool ingress, int *p_span_id)
{
	struct mlxsw_sp_port *in_port, *out_port;
	struct mlxsw_sp_port *in_port;
	struct mlxsw_sp *mlxsw_sp = priv;
	enum mlxsw_sp_span_type type;

	type = ingress ? MLXSW_SP_SPAN_INGRESS : MLXSW_SP_SPAN_EGRESS;
	out_port = mlxsw_sp->ports[local_out_port];
	in_port = mlxsw_sp->ports[local_in_port];

	return mlxsw_sp_span_mirror_add(in_port, out_port, type,
	return mlxsw_sp_span_mirror_add(in_port, out_dev, type,
					false, p_span_id);
}

Loading