]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
mlxsw: spectrum_span: Add APIs to get / put a SPAN agent
authorIdo Schimmel <idosch@mellanox.com>
Thu, 30 Apr 2020 17:01:08 +0000 (20:01 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 30 Apr 2020 20:02:32 +0000 (13:02 -0700)
Given a netdev that packets should be mirrored to, create a SPAN agent
and return its identifier to the caller.

The SPAN agent is reference counted, as multiple tc-mirred actions can
point to the same destination netdev.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.h

index ae3c8a1e9a43468193fa427686a2d5547d5d0812..c4159f4a66e2b9d7cf6e1f4e0295a72863de4b6a 100644 (file)
@@ -1039,3 +1039,46 @@ void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
                return;
        mlxsw_core_schedule_work(&mlxsw_sp->span->work);
 }
+
+int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
+                           const struct net_device *to_dev, int *p_span_id)
+{
+       const struct mlxsw_sp_span_entry_ops *ops;
+       struct mlxsw_sp_span_entry *span_entry;
+       struct mlxsw_sp_span_parms sparms;
+       int err;
+
+       ASSERT_RTNL();
+
+       ops = mlxsw_sp_span_entry_ops(mlxsw_sp, to_dev);
+       if (!ops) {
+               dev_err(mlxsw_sp->bus_info->dev, "Cannot mirror to requested destination\n");
+               return -EOPNOTSUPP;
+       }
+
+       memset(&sparms, 0, sizeof(sparms));
+       err = ops->parms_set(to_dev, &sparms);
+       if (err)
+               return err;
+
+       span_entry = mlxsw_sp_span_entry_get(mlxsw_sp, to_dev, ops, sparms);
+       if (!span_entry)
+               return -ENOBUFS;
+
+       *p_span_id = span_entry->id;
+
+       return 0;
+}
+
+void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id)
+{
+       struct mlxsw_sp_span_entry *span_entry;
+
+       ASSERT_RTNL();
+
+       span_entry = mlxsw_sp_span_entry_find_by_id(mlxsw_sp, span_id);
+       if (WARN_ON_ONCE(!span_entry))
+               return;
+
+       mlxsw_sp_span_entry_put(mlxsw_sp, span_entry);
+}
index d23abdf957fa221c7d177b1d4f99ff3c228e267b..b79de9a125bba87b97bc5c0623047bd33d7ac8f7 100644 (file)
@@ -77,4 +77,8 @@ void mlxsw_sp_span_entry_invalidate(struct mlxsw_sp *mlxsw_sp,
 int mlxsw_sp_span_port_mtu_update(struct mlxsw_sp_port *port, u16 mtu);
 void mlxsw_sp_span_speed_update_work(struct work_struct *work);
 
+int mlxsw_sp_span_agent_get(struct mlxsw_sp *mlxsw_sp,
+                           const struct net_device *to_dev, int *p_span_id);
+void mlxsw_sp_span_agent_put(struct mlxsw_sp *mlxsw_sp, int span_id);
+
 #endif