Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *      Device event handling
  3  *      Linux ethernet bridge
  4  *
  5  *      Authors:
  6  *      Lennert Buytenhek               <buytenh@gnu.org>
  7  *
  8  *      This program is free software; you can redistribute it and/or
  9  *      modify it under the terms of the GNU General Public License
 10  *      as published by the Free Software Foundation; either version
 11  *      2 of the License, or (at your option) any later version.
 12  */
 13 
 14 #include <linux/kernel.h>
 15 #include <linux/rtnetlink.h>
 16 #include <net/net_namespace.h>
 17 
 18 #include "br_private.h"
 19 
 20 static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr);
 21 
 22 struct notifier_block br_device_notifier = {
 23         .notifier_call = br_device_event
 24 };
 25 
 26 /*
 27  * Handle changes in state of network devices enslaved to a bridge.
 28  *
 29  * Note: don't care about up/down if bridge itself is down, because
 30  *     port state is checked when bridge is brought up.
 31  */
 32 static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
 33 {
 34         struct net_device *dev = ptr;
 35         struct net_bridge_port *p = dev->br_port;
 36         struct net_bridge *br;
 37 
 38         /* not a port of a bridge */
 39         if (p == NULL)
 40                 return NOTIFY_DONE;
 41 
 42         br = p->br;
 43 
 44         switch (event) {
 45         case NETDEV_CHANGEMTU:
 46                 dev_set_mtu(br->dev, br_min_mtu(br));
 47                 break;
 48 
 49         case NETDEV_CHANGEADDR:
 50                 spin_lock_bh(&br->lock);
 51                 br_fdb_changeaddr(p, dev->dev_addr);
 52                 br_stp_recalculate_bridge_id(br);
 53                 spin_unlock_bh(&br->lock);
 54                 break;
 55 
 56         case NETDEV_CHANGE:
 57                 br_port_carrier_check(p);
 58                 break;
 59 
 60         case NETDEV_FEAT_CHANGE:
 61                 spin_lock_bh(&br->lock);
 62                 if (netif_running(br->dev))
 63                         br_features_recompute(br);
 64                 spin_unlock_bh(&br->lock);
 65                 break;
 66 
 67         case NETDEV_DOWN:
 68                 spin_lock_bh(&br->lock);
 69                 if (br->dev->flags & IFF_UP)
 70                         br_stp_disable_port(p);
 71                 spin_unlock_bh(&br->lock);
 72                 break;
 73 
 74         case NETDEV_UP:
 75                 if (netif_carrier_ok(dev) && (br->dev->flags & IFF_UP)) {
 76                         spin_lock_bh(&br->lock);
 77                         br_stp_enable_port(p);
 78                         spin_unlock_bh(&br->lock);
 79                 }
 80                 break;
 81 
 82         case NETDEV_UNREGISTER:
 83                 br_del_if(br, dev);
 84                 break;
 85         }
 86 
 87         /* Events that may cause spanning tree to refresh */
 88         if (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
 89             event == NETDEV_CHANGE || event == NETDEV_DOWN)
 90                 br_ifinfo_notify(RTM_NEWLINK, p);
 91 
 92         return NOTIFY_DONE;
 93 }
 94 
  This page was automatically generated by the LXR engine.