|
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
|
|
|
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
|
|
struct net_bridge_port *p;
|
|
|
struct net_bridge *br;
|
|
|
+ bool notified = false;
|
|
|
bool changed_addr;
|
|
|
int err;
|
|
|
|
|
@@ -67,7 +68,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
|
|
|
break;
|
|
|
|
|
|
case NETDEV_CHANGE:
|
|
|
- br_port_carrier_check(p);
|
|
|
+ br_port_carrier_check(p, ¬ified);
|
|
|
break;
|
|
|
|
|
|
case NETDEV_FEAT_CHANGE:
|
|
@@ -76,8 +77,10 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
|
|
|
|
|
|
case NETDEV_DOWN:
|
|
|
spin_lock_bh(&br->lock);
|
|
|
- if (br->dev->flags & IFF_UP)
|
|
|
+ if (br->dev->flags & IFF_UP) {
|
|
|
br_stp_disable_port(p);
|
|
|
+ notified = true;
|
|
|
+ }
|
|
|
spin_unlock_bh(&br->lock);
|
|
|
break;
|
|
|
|
|
@@ -85,6 +88,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
|
|
|
if (netif_running(br->dev) && netif_oper_up(dev)) {
|
|
|
spin_lock_bh(&br->lock);
|
|
|
br_stp_enable_port(p);
|
|
|
+ notified = true;
|
|
|
spin_unlock_bh(&br->lock);
|
|
|
}
|
|
|
break;
|
|
@@ -110,8 +114,8 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
|
|
|
}
|
|
|
|
|
|
/* Events that may cause spanning tree to refresh */
|
|
|
- if (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
|
|
|
- event == NETDEV_CHANGE || event == NETDEV_DOWN)
|
|
|
+ if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
|
|
|
+ event == NETDEV_CHANGE || event == NETDEV_DOWN))
|
|
|
br_ifinfo_notify(RTM_NEWLINK, NULL, p);
|
|
|
|
|
|
return NOTIFY_DONE;
|