From 75c78500ddad74b229cd0691496b8549490496a2 Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Tue, 15 Sep 2009 02:37:40 -0700 Subject: [PATCH] bonding: remap muticast addresses without using dev_close() and dev_open() This patch fixes commit e36b9d16c6a6d0f59803b3ef04ff3c22c3844c10. The approach there is to call dev_close()/dev_open() whenever the device type is changed in order to remap the device IP multicast addresses to HW multicast addresses. This approach suffers from 2 drawbacks: *. It assumes tha the device is UP when calling dev_close(), or otherwise dev_close() has no affect. It is worth to mention that initscripts (Redhat) and sysconfig (Suse) doesn't act the same in this matter. *. dev_close() has other side affects, like deleting entries from the routing table, which might be unnecessary. The fix here is to directly remap the IP multicast addresses to HW multicast addresses for a bonding device that changes its type, and nothing else. Reported-by: Jason Gunthorpe Signed-off-by: Moni Shoua Signed-off-by: David S. Miller diff -Nur linux-2.6.18.i686.0002/drivers/net/bonding/bond_main.c linux-2.6.18.i686/drivers/net/bonding/bond_main.c --- linux-2.6.18.i686.0002/drivers/net/bonding/bond_main.c 2013-01-17 13:54:39.000000000 +0800 +++ linux-2.6.18.i686/drivers/net/bonding/bond_main.c 2013-01-17 14:07:49.000000000 +0800 @@ -1103,7 +1103,7 @@ write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); - netdev_bonding_change(bond->dev); + netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); diff -Nur linux-2.6.18.i686.0002/include/linux/netdevice.h linux-2.6.18.i686/include/linux/netdevice.h --- linux-2.6.18.i686.0002/include/linux/netdevice.h 2013-01-17 13:53:54.000000000 +0800 +++ linux-2.6.18.i686/include/linux/netdevice.h 2013-01-17 14:09:02.000000000 +0800 @@ -1004,7 +1004,8 @@ extern void dev_set_promiscuity(struct net_device *dev, int inc); extern void dev_set_allmulti(struct net_device *dev, int inc); extern void netdev_state_change(struct net_device *dev); -extern void netdev_bonding_change(struct net_device *dev); +extern void netdev_bonding_change(struct net_device *dev, + unsigned long event); extern void netdev_features_change(struct net_device *dev); /* Load a device via the kmod */ extern void dev_load(const char *name); diff -Nur linux-2.6.18.i686.0002/net/core/dev.c linux-2.6.18.i686/net/core/dev.c --- linux-2.6.18.i686.0002/net/core/dev.c 2013-01-17 13:53:54.000000000 +0800 +++ linux-2.6.18.i686/net/core/dev.c 2013-01-17 14:11:29.000000000 +0800 @@ -797,9 +797,9 @@ } } -void netdev_bonding_change(struct net_device *dev) +void netdev_bonding_change(struct net_device *dev, unsigned long event) { - call_netdevice_notifiers(NETDEV_BONDING_FAILOVER, dev); + call_netdevice_notifiers(event, dev); } EXPORT_SYMBOL(netdev_bonding_change);