[BRIDGE] br_if: Fix oops in port_carrier_check
[linux-drm-fsl-dcu.git] / net / bridge / br_notify.c
index a43a9c1d50d7daa21c732523e9d2cdb3d36e3a9e..3311c4e30829ed93c6e3ce2d004f956eb8e60758 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/rtnetlink.h>
 
 #include "br_private.h"
 
@@ -25,7 +26,7 @@ struct notifier_block br_device_notifier = {
 
 /*
  * Handle changes in state of network devices enslaved to a bridge.
- * 
+ *
  * Note: don't care about up/down if bridge itself is down, because
  *     port state is checked when bridge is brought up.
  */
@@ -49,20 +50,23 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
 
        case NETDEV_CHANGEADDR:
                br_fdb_changeaddr(p, dev->dev_addr);
+               br_ifinfo_notify(RTM_NEWLINK, p);
                br_stp_recalculate_bridge_id(br);
                break;
 
        case NETDEV_CHANGE:
                if (br->dev->flags & IFF_UP)
-                       schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE);
+                       if (schedule_delayed_work(&p->carrier_check,
+                                               BR_PORT_DEBOUNCE))
+                               dev_hold(dev);
                break;
 
        case NETDEV_FEAT_CHANGE:
-               if (br->dev->flags & IFF_UP) 
+               if (br->dev->flags & IFF_UP)
                        br_features_recompute(br);
 
                /* could do recursive feature change notification
-                * but who would care?? 
+                * but who would care??
                 */
                break;
 
@@ -72,7 +76,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
                break;
 
        case NETDEV_UP:
-               if (netif_carrier_ok(dev) && (br->dev->flags & IFF_UP)) 
+               if (netif_carrier_ok(dev) && (br->dev->flags & IFF_UP))
                        br_stp_enable_port(p);
                break;
 
@@ -80,7 +84,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
                spin_unlock_bh(&br->lock);
                br_del_if(br, dev);
                goto done;
-       } 
+       }
        spin_unlock_bh(&br->lock);
 
  done: