@@ -4640,7 +4640,7 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
if (span_entry)
mlxsw_sp_span_entry_invalidate(mlxsw_sp, span_entry);
}
- mlxsw_sp_span_respin(mlxsw_sp);
+ mlxsw_sp_span_respin(mlxsw_sp, NULL);
if (mlxsw_sp_netdev_is_ipip_ol(mlxsw_sp, dev))
err = mlxsw_sp_netdevice_ipip_ol_event(mlxsw_sp, dev,
@@ -2397,7 +2397,7 @@ static void mlxsw_sp_router_neigh_event_work(struct work_struct *work)
read_unlock_bh(&n->lock);
rtnl_lock();
- mlxsw_sp_span_respin(mlxsw_sp);
+ mlxsw_sp_span_respin(mlxsw_sp, NULL);
entry_connected = nud_state & NUD_VALID && !dead;
neigh_entry = mlxsw_sp_neigh_entry_lookup(mlxsw_sp, n);
@@ -5677,7 +5677,7 @@ static void mlxsw_sp_router_fib4_event_work(struct work_struct *work)
/* Protect internal structures from changes */
rtnl_lock();
- mlxsw_sp_span_respin(mlxsw_sp);
+ mlxsw_sp_span_respin(mlxsw_sp, NULL);
switch (fib_work->event) {
case FIB_EVENT_ENTRY_REPLACE: /* fall through */
@@ -5721,7 +5721,7 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
int err;
rtnl_lock();
- mlxsw_sp_span_respin(mlxsw_sp);
+ mlxsw_sp_span_respin(mlxsw_sp, NULL);
switch (fib_work->event) {
case FIB_EVENT_ENTRY_REPLACE: /* fall through */
@@ -81,6 +81,7 @@ void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp)
static int
mlxsw_sp_span_entry_phys_parms(const struct net_device *to_dev,
+ const struct switchdev_obj_port_vlan *vlan,
struct mlxsw_sp_span_parms *sparmsp)
{
sparmsp->dest_port = netdev_priv(to_dev);
@@ -169,12 +170,13 @@ mlxsw_sp_span_entry_unoffloadable(struct mlxsw_sp_span_parms *sparmsp)
static __maybe_unused int
mlxsw_sp_span_entry_tunnel_parms_common(struct net_device *l3edev,
- union mlxsw_sp_l3addr saddr,
- union mlxsw_sp_l3addr daddr,
- union mlxsw_sp_l3addr gw,
- __u8 ttl,
- struct neigh_table *tbl,
- struct mlxsw_sp_span_parms *sparmsp)
+ union mlxsw_sp_l3addr saddr,
+ union mlxsw_sp_l3addr daddr,
+ union mlxsw_sp_l3addr gw,
+ __u8 ttl,
+ struct neigh_table *tbl,
+ const struct switchdev_obj_port_vlan *vlan,
+ struct mlxsw_sp_span_parms *sparmsp)
{
unsigned char dmac[ETH_ALEN];
@@ -230,6 +232,7 @@ mlxsw_sp_span_gretap4_route(const struct net_device *to_dev,
static int
mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev,
+ const struct switchdev_obj_port_vlan *vlan,
struct mlxsw_sp_span_parms *sparmsp)
{
struct ip_tunnel_parm tparm = mlxsw_sp_ipip_netdev_parms4(to_dev);
@@ -252,7 +255,7 @@ mlxsw_sp_span_entry_gretap4_parms(const struct net_device *to_dev,
l3edev = mlxsw_sp_span_gretap4_route(to_dev, &saddr.addr4, &gw.addr4);
return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
tparm.iph.ttl,
- &arp_tbl, sparmsp);
+ &arp_tbl, vlan, sparmsp);
}
static int
@@ -330,6 +333,7 @@ mlxsw_sp_span_gretap6_route(const struct net_device *to_dev,
static int
mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev,
+ const struct switchdev_obj_port_vlan *vlan,
struct mlxsw_sp_span_parms *sparmsp)
{
struct __ip6_tnl_parm tparm = mlxsw_sp_ipip_netdev_parms6(to_dev);
@@ -352,7 +356,7 @@ mlxsw_sp_span_entry_gretap6_parms(const struct net_device *to_dev,
l3edev = mlxsw_sp_span_gretap6_route(to_dev, &saddr.addr6, &gw.addr6);
return mlxsw_sp_span_entry_tunnel_parms_common(l3edev, saddr, daddr, gw,
tparm.hop_limit,
- &nd_tbl, sparmsp);
+ &nd_tbl, vlan, sparmsp);
}
static int
@@ -407,6 +411,7 @@ struct mlxsw_sp_span_entry_ops *const mlxsw_sp_span_entry_types[] = {
static int
mlxsw_sp_span_entry_nop_parms(const struct net_device *to_dev,
+ const struct switchdev_obj_port_vlan *vlan,
struct mlxsw_sp_span_parms *sparmsp)
{
return mlxsw_sp_span_entry_unoffloadable(sparmsp);
@@ -760,7 +765,7 @@ int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
return -EOPNOTSUPP;
}
- err = ops->parms(to_dev, &sparms);
+ err = ops->parms(to_dev, NULL, &sparms);
if (err)
return err;
@@ -799,7 +804,8 @@ void mlxsw_sp_span_mirror_del(struct mlxsw_sp_port *from, int span_id,
mlxsw_sp_span_inspected_port_del(from, span_entry, type, bind);
}
-void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
+void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp,
+ const struct switchdev_obj_port_vlan *vlan)
{
int i;
int err;
@@ -812,7 +818,7 @@ void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp)
if (!curr->ref_count)
continue;
- err = curr->ops->parms(curr->to_dev, &sparms);
+ err = curr->ops->parms(curr->to_dev, vlan, &sparms);
if (err)
continue;
@@ -36,6 +36,7 @@
#include <linux/types.h>
#include <linux/if_ether.h>
+#include <net/switchdev.h>
#include "spectrum_router.h"
@@ -79,6 +80,7 @@ struct mlxsw_sp_span_entry {
struct mlxsw_sp_span_entry_ops {
bool (*can_handle)(const struct net_device *to_dev);
int (*parms)(const struct net_device *to_dev,
+ const struct switchdev_obj_port_vlan *vlan,
struct mlxsw_sp_span_parms *sparmsp);
int (*configure)(struct mlxsw_sp_span_entry *span_entry,
struct mlxsw_sp_span_parms sparms);
@@ -87,7 +89,8 @@ struct mlxsw_sp_span_entry_ops {
int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_span_fini(struct mlxsw_sp *mlxsw_sp);
-void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp);
+void mlxsw_sp_span_respin(struct mlxsw_sp *mlxsw_sp,
+ const struct switchdev_obj_port_vlan *vlan);
int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,
const struct net_device *to_dev,
Because switchdev events are emitted before the changes are applied to the bridge, mlxsw_sp_span_entry_ops.parms() callback wouldn't see the updated value of VLAN flags when respinning due to change in those flags. Thus add a parameter of type struct switchdev_obj_port_vlan to mlxsw_sp_span_respin() and propagate to the parms callback. Pass NULL from all current callers. Signed-off-by: Petr Machata <petrm@mellanox.com> --- Notes: Changes from v1 to v2: - New patch. drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 6 ++--- .../net/ethernet/mellanox/mlxsw/spectrum_span.c | 28 +++++++++++++--------- .../net/ethernet/mellanox/mlxsw/spectrum_span.h | 5 +++- 4 files changed, 25 insertions(+), 16 deletions(-)