aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorMoni Shoua <monis@voltaire.com>2009-09-15 05:37:40 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-15 05:37:40 -0400
commit75c78500ddad74b229cd0691496b8549490496a2 (patch)
tree5249219d68627421e4717c4e8f03f8b4bbad2e92 /net/ipv4
parent481a8199142c050b72bff8a1956a49fd0a75bbe0 (diff)
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 <jgunthorpe@obsidianresearch.com> Signed-off-by: Moni Shoua <monis@voltaire.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/devinet.c6
-rw-r--r--net/ipv4/igmp.c22
2 files changed, 28 insertions, 0 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 3863c3a4223f..07336c6201f0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1087,6 +1087,12 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1087 case NETDEV_DOWN: 1087 case NETDEV_DOWN:
1088 ip_mc_down(in_dev); 1088 ip_mc_down(in_dev);
1089 break; 1089 break;
1090 case NETDEV_BONDING_OLDTYPE:
1091 ip_mc_unmap(in_dev);
1092 break;
1093 case NETDEV_BONDING_NEWTYPE:
1094 ip_mc_remap(in_dev);
1095 break;
1090 case NETDEV_CHANGEMTU: 1096 case NETDEV_CHANGEMTU:
1091 if (inetdev_valid_mtu(dev->mtu)) 1097 if (inetdev_valid_mtu(dev->mtu))
1092 break; 1098 break;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 01b4284ed694..d41e5de79a82 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1298,6 +1298,28 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
1298 } 1298 }
1299} 1299}
1300 1300
1301/* Device changing type */
1302
1303void ip_mc_unmap(struct in_device *in_dev)
1304{
1305 struct ip_mc_list *i;
1306
1307 ASSERT_RTNL();
1308
1309 for (i = in_dev->mc_list; i; i = i->next)
1310 igmp_group_dropped(i);
1311}
1312
1313void ip_mc_remap(struct in_device *in_dev)
1314{
1315 struct ip_mc_list *i;
1316
1317 ASSERT_RTNL();
1318
1319 for (i = in_dev->mc_list; i; i = i->next)
1320 igmp_group_added(i);
1321}
1322
1301/* Device going down */ 1323/* Device going down */
1302 1324
1303void ip_mc_down(struct in_device *in_dev) 1325void ip_mc_down(struct in_device *in_dev)