net: bridge: avoid duplicate notification on up/down/change netdev events

While handling netdevice events, br_device_event() sometimes uses
br_stp_(disable|enable)_port which unconditionally send a notification,
but then a second notification for the same event is sent at the end of
the br_device_event() function. To avoid sending duplicate notifications
in such cases, check if one has already been sent (i.e.
br_stp_enable/disable_port have been called).
The patch is based on a change by Satish Ashok.

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Nikolay Aleksandrov 2018-05-03 13:47:24 +03:00 committed by David S. Miller
parent 2e51855194
commit faa1cd8298
3 changed files with 17 additions and 8 deletions

View file

@ -64,7 +64,7 @@ static int port_cost(struct net_device *dev)
/* Check for port carrier transitions. */
void br_port_carrier_check(struct net_bridge_port *p)
void br_port_carrier_check(struct net_bridge_port *p, bool *notified)
{
struct net_device *dev = p->dev;
struct net_bridge *br = p->br;
@ -73,16 +73,21 @@ void br_port_carrier_check(struct net_bridge_port *p)
netif_running(dev) && netif_oper_up(dev))
p->path_cost = port_cost(dev);
*notified = false;
if (!netif_running(br->dev))
return;
spin_lock_bh(&br->lock);
if (netif_running(dev) && netif_oper_up(dev)) {
if (p->state == BR_STATE_DISABLED)
if (p->state == BR_STATE_DISABLED) {
br_stp_enable_port(p);
*notified = true;
}
} else {
if (p->state != BR_STATE_DISABLED)
if (p->state != BR_STATE_DISABLED) {
br_stp_disable_port(p);
*notified = true;
}
}
spin_unlock_bh(&br->lock);
}