netdev
[Top] [All Lists]

[PATCH 8/10] [bonding 2.6] Enhance netdev notification handling

To: bonding-devel@xxxxxxxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxx
Subject: [PATCH 8/10] [bonding 2.6] Enhance netdev notification handling
From: Amir Noam <amir.noam@xxxxxxxxx>
Date: Thu, 11 Sep 2003 17:43:38 +0300
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: KMail/1.4.3
diff -Nuarp a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c   Thu Sep 11 16:48:36 2003
+++ b/drivers/net/bonding/bond_main.c   Thu Sep 11 16:48:37 2003
@@ -408,6 +408,18 @@
  *       and free it separately; use standard list operations instead
  *       of pre-allocated array of bonds.
  *       Version to 2.3.0.
+ *
+ * 2003/08/07 - Jay Vosburgh <fubar at us dot ibm dot com>,
+ *            Amir Noam <amir.noam at intel dot com> and
+ *            Shmulik Hen <shmulik.hen at intel dot com>
+ *     - Propagating master's settings: Distinguish between modes that
+ *       use a primary slave from those that don't, and propagate settings
+ *       accordingly; Consolidate change_active opeartions and add
+ *       reselect_active and find_best opeartions; Decouple promiscuous
+ *       handling from the multicast mode setting; Add support for changing
+ *       HW address and MTU with proper unwind; Consolidate procfs code,
+ *       add CHANGENAME handler; Enhance netdev notification handling.
+ *       Version to 2.4.0.
  */
 
 #include <linux/config.h>
@@ -452,8 +464,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION    "2.3.0"
-#define DRV_RELDATE    "August 6, 2003"
+#define DRV_VERSION    "2.4.0"
+#define DRV_RELDATE    "August 7, 2003"
 #define DRV_NAME       "bonding"
 #define DRV_DESCRIPTION        "Ethernet Channel Bonding Driver"
 
@@ -572,7 +584,6 @@ static struct net_device_stats *bond_get
 static void bond_mii_monitor(struct net_device *dev);
 static void loadbalance_arp_monitor(struct net_device *dev);
 static void activebackup_arp_monitor(struct net_device *dev);
-static int bond_event(struct notifier_block *this, unsigned long event, void 
*ptr);
 static void bond_mc_list_destroy(struct bonding *bond);
 static void bond_mc_add(bonding_t *bond, void *addr, int alen);
 static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
@@ -3465,7 +3476,6 @@ static int bond_read_proc(char *buf, cha
 }
 #endif /* CONFIG_PROC_FS */
 
-
 static int bond_create_proc_info(struct bonding *bond)
 {
 #ifdef CONFIG_PROC_FS
@@ -3630,21 +3640,134 @@ unwind:
        return error;
 }
 
-static int bond_event(struct notifier_block *this, unsigned long event, 
-                       void *ptr)
+/*
+ * Change device name
+ */
+static inline int bond_event_changename(struct bonding *bond)
+{
+       int error;
+
+       bond_destroy_proc_info(bond);
+       error = bond_create_proc_info(bond);
+       if (error) {
+               return NOTIFY_BAD;
+       }
+       return NOTIFY_DONE;
+}
+
+static int bond_master_netdev_event(unsigned long event, struct net_device 
*event_dev)
+{
+       struct bonding *bond, *event_bond = NULL;
+
+       list_for_each_entry(bond, &bond_dev_list, bond_list) {
+               if (bond == event_dev->priv) {
+                       event_bond = bond;
+                       break;
+               }
+       }
+
+       if (event_bond == NULL) {
+               return NOTIFY_DONE;
+       }
+
+       switch (event) {
+       case NETDEV_CHANGENAME:
+               return bond_event_changename(event_bond);
+       case NETDEV_UNREGISTER:
+               /*
+                * TODO: remove a bond from the list?
+                */
+               break;
+       default:
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static int bond_slave_netdev_event(unsigned long event, struct net_device 
*event_dev)
 {
-       struct net_device *event_dev = (struct net_device *)ptr;
        struct net_device *master = event_dev->master;
 
-       if ((event == NETDEV_UNREGISTER) && (master != NULL)) {
-               bond_release(master, event_dev);
+       switch (event) {
+       case NETDEV_UNREGISTER:
+               if (master != NULL) {
+                       bond_release(master, event_dev);
+               }
+               break;
+       case NETDEV_CHANGE:
+               /*
+                * TODO: is this what we get if somebody
+                * sets up a hierarchical bond, then rmmod's
+                * one of the slave bonding devices?
+                */
+               break;
+       case NETDEV_DOWN:
+               /*
+                * ... Or is it this?
+                */
+               break;
+       case NETDEV_CHANGEMTU:
+               /*
+                * TODO: Should slaves be allowed to
+                * independently alter their MTU?  For
+                * an active-backup bond, slaves need
+                * not be the same type of device, so
+                * MTUs may vary.  For other modes,
+                * slaves arguably should have the
+                * same MTUs. To do this, we'd need to
+                * take over the slave's change_mtu
+                * function for the duration of their
+                * servitude.
+                */
+               break;
+       case NETDEV_CHANGENAME:
+               /*
+                * TODO: handle changing the primary's name
+                */
+               break;
+       default:
+               break;
        }
 
        return NOTIFY_DONE;
 }
 
+/*
+ * bond_netdev_event: handle netdev notifier chain events.
+ *
+ * This function receives events for the netdev chain.  The caller (an
+ * ioctl handler calling notifier_call_chain) holds the necessary
+ * locks for us to safely manipulate the slave devices (RTNL lock,
+ * dev_probe_lock).
+ */
+static int bond_netdev_event(struct notifier_block *this, unsigned long event, 
void *ptr)
+{
+       struct net_device *event_dev = (struct net_device *)ptr;
+       unsigned short flags;
+       int res = NOTIFY_DONE;
+
+       dprintk(KERN_INFO "bond_netdev_event n_b %p ev %lx ptr %p\n",
+               this, event, ptr);
+
+       flags = event_dev->flags & (IFF_MASTER | IFF_SLAVE);
+       switch (flags) {
+       case IFF_MASTER:
+               res = bond_master_netdev_event(event, event_dev);
+               break;
+       case IFF_SLAVE:
+               res = bond_slave_netdev_event(event, event_dev);
+               break;
+       default:
+               /* A master that is also a slave ? */
+               break;
+       }
+
+       return res;
+}
+
 static struct notifier_block bond_netdev_notifier = {
-       .notifier_call = bond_event,
+       .notifier_call = bond_netdev_event,
 };
 
 static void bond_deinit(struct net_device *dev)



<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 8/10] [bonding 2.6] Enhance netdev notification handling, Amir Noam <=