Commit df31c91c authored by Amir Noam's avatar Amir Noam Committed by Stephen Hemminger

[PATCH] [bonding 2.6] Enhance netdev notification handling

parent f2240db0
...@@ -408,6 +408,18 @@ ...@@ -408,6 +408,18 @@
* and free it separately; use standard list operations instead * and free it separately; use standard list operations instead
* of pre-allocated array of bonds. * of pre-allocated array of bonds.
* Version to 2.3.0. * 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> #include <linux/config.h>
...@@ -452,8 +464,8 @@ ...@@ -452,8 +464,8 @@
#include "bond_3ad.h" #include "bond_3ad.h"
#include "bond_alb.h" #include "bond_alb.h"
#define DRV_VERSION "2.3.0" #define DRV_VERSION "2.4.0"
#define DRV_RELDATE "August 6, 2003" #define DRV_RELDATE "August 7, 2003"
#define DRV_NAME "bonding" #define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
...@@ -572,7 +584,6 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev); ...@@ -572,7 +584,6 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev);
static void bond_mii_monitor(struct net_device *dev); static void bond_mii_monitor(struct net_device *dev);
static void loadbalance_arp_monitor(struct net_device *dev); static void loadbalance_arp_monitor(struct net_device *dev);
static void activebackup_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_list_destroy(struct bonding *bond);
static void bond_mc_add(bonding_t *bond, void *addr, int alen); static void bond_mc_add(bonding_t *bond, void *addr, int alen);
static void bond_mc_delete(bonding_t *bond, void *addr, int alen); static void bond_mc_delete(bonding_t *bond, void *addr, int alen);
...@@ -3491,7 +3502,6 @@ static int bond_read_proc(char *buf, char **start, off_t off, int count, int *eo ...@@ -3491,7 +3502,6 @@ static int bond_read_proc(char *buf, char **start, off_t off, int count, int *eo
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
static int bond_create_proc_info(struct bonding *bond) static int bond_create_proc_info(struct bonding *bond)
{ {
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
...@@ -3656,21 +3666,134 @@ bond_change_mtu(struct net_device *dev, int newmtu) ...@@ -3656,21 +3666,134 @@ bond_change_mtu(struct net_device *dev, int newmtu)
return error; 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; struct net_device *master = event_dev->master;
if ((event == NETDEV_UNREGISTER) && (master != NULL)) { switch (event) {
bond_release(master, event_dev); 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; 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 = { static struct notifier_block bond_netdev_notifier = {
.notifier_call = bond_event, .notifier_call = bond_netdev_event,
}; };
static void bond_deinit(struct net_device *dev) static void bond_deinit(struct net_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment