net: bridge: ignore switchdev events for LAG ports which didn't request replay
There is a slight inconvenience in the switchdev replay helpers added recently, and this is when: ip link add br0 type bridge ip link add bond0 type bond ip link set bond0 master br0 bridge vlan add dev bond0 vid 100 ip link set swp0 master bond0 ip link set swp1 master bond0 Since the underlying driver (currently only DSA) asks for a replay of VLANs when swp0 and swp1 join the LAG because it is bridged, what will happen is that DSA will try to react twice on the VLAN event for swp0. This is not really a huge problem right now, because most drivers accept duplicates since the bridge itself does, but it will become a problem when we add support for replaying switchdev object deletions. Let's fix this by adding a blank void *ctx in the replay helpers, which will be passed on by the bridge in the switchdev notifications. If the context is NULL, everything is the same as before. But if the context is populated with a valid pointer, the underlying switchdev driver (currently DSA) can use the pointer to 'see through' the bridge port (which in the example above is bond0) and 'know' that the event is only for a particular physical port offloading that bridge port, and not for all of them. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
69bfac968a
commit
0d2cfbd41c
@@ -71,7 +71,8 @@ bool br_multicast_has_router_adjacent(struct net_device *dev, int proto);
|
||||
bool br_multicast_enabled(const struct net_device *dev);
|
||||
bool br_multicast_router(const struct net_device *dev);
|
||||
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
|
||||
struct notifier_block *nb, struct netlink_ext_ack *extack);
|
||||
const void *ctx, struct notifier_block *nb,
|
||||
struct netlink_ext_ack *extack);
|
||||
#else
|
||||
static inline int br_multicast_list_adjacent(struct net_device *dev,
|
||||
struct list_head *br_ip_list)
|
||||
@@ -104,7 +105,7 @@ static inline bool br_multicast_router(const struct net_device *dev)
|
||||
return false;
|
||||
}
|
||||
static inline int br_mdb_replay(struct net_device *br_dev,
|
||||
struct net_device *dev,
|
||||
struct net_device *dev, const void *ctx,
|
||||
struct notifier_block *nb,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@@ -120,7 +121,8 @@ int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto);
|
||||
int br_vlan_get_info(const struct net_device *dev, u16 vid,
|
||||
struct bridge_vlan_info *p_vinfo);
|
||||
int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
|
||||
struct notifier_block *nb, struct netlink_ext_ack *extack);
|
||||
const void *ctx, struct notifier_block *nb,
|
||||
struct netlink_ext_ack *extack);
|
||||
#else
|
||||
static inline bool br_vlan_enabled(const struct net_device *dev)
|
||||
{
|
||||
@@ -149,7 +151,7 @@ static inline int br_vlan_get_info(const struct net_device *dev, u16 vid,
|
||||
}
|
||||
|
||||
static inline int br_vlan_replay(struct net_device *br_dev,
|
||||
struct net_device *dev,
|
||||
struct net_device *dev, const void *ctx,
|
||||
struct notifier_block *nb,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@@ -166,7 +168,7 @@ bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag);
|
||||
u8 br_port_get_stp_state(const struct net_device *dev);
|
||||
clock_t br_get_ageing_time(struct net_device *br_dev);
|
||||
int br_fdb_replay(struct net_device *br_dev, struct net_device *dev,
|
||||
struct notifier_block *nb);
|
||||
const void *ctx, struct notifier_block *nb);
|
||||
#else
|
||||
static inline struct net_device *
|
||||
br_fdb_find_port(const struct net_device *br_dev,
|
||||
@@ -197,7 +199,7 @@ static inline clock_t br_get_ageing_time(struct net_device *br_dev)
|
||||
}
|
||||
|
||||
static inline int br_fdb_replay(struct net_device *br_dev,
|
||||
struct net_device *dev,
|
||||
struct net_device *dev, const void *ctx,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
Reference in New Issue
Block a user