bonding: flush unicast and multicast lists when changing type
authorJiri Pirko <jpirko@redhat.com>
Fri, 19 Mar 2010 04:00:23 +0000 (04:00 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Mar 2010 01:31:34 +0000 (18:31 -0700)
After the type change, addresses in unicast and multicast lists wouldn't make
sense, not to mention possible different lenghts. So flush both lists here.

Note "dev_addr_discard" will be very soon replaced by "dev_mc_flush" (once
mc_list conversion will be done).

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/bonding/bond_main.c
include/linux/netdevice.h
net/core/dev.c

index cbe9e353d46a9fab051beb88f2a477d2d27296ce..c2aceaab01433ae2b9b2629f16566bf7e011e165 100644 (file)
@@ -1490,6 +1490,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                                goto err_undo_flags;
                        }
 
+                       /* Flush unicast and multicast addresses */
+                       dev_unicast_flush(bond_dev);
+                       dev_addr_discard(bond_dev);
+
                        if (slave_dev->type != ARPHRD_ETHER)
                                bond_setup_by_slave(bond_dev, slave_dev);
                        else
index 9fc6ee8e750814182a220c68b47cc6105ab241fa..c96c41e08e3774bab7b0be940d14cc27969d445e 100644 (file)
@@ -1994,10 +1994,12 @@ extern int              dev_unicast_delete(struct net_device *dev, void *addr);
 extern int             dev_unicast_add(struct net_device *dev, void *addr);
 extern int             dev_unicast_sync(struct net_device *to, struct net_device *from);
 extern void            dev_unicast_unsync(struct net_device *to, struct net_device *from);
+extern void            dev_unicast_flush(struct net_device *dev);
 extern int             dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
 extern int             dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly);
 extern int             dev_mc_sync(struct net_device *to, struct net_device *from);
 extern void            dev_mc_unsync(struct net_device *to, struct net_device *from);
+extern void            dev_addr_discard(struct net_device *dev);
 extern int             __dev_addr_delete(struct dev_addr_list **list, int *count, void *addr, int alen, int all);
 extern int             __dev_addr_add(struct dev_addr_list **list, int *count, void *addr, int alen, int newonly);
 extern int             __dev_addr_sync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count);
index c0e260870c0a1c81ec5e150b64b0b35a9bf58ea5..fe2a754238a902dfb1fcb5c8e9e02cde8f3388ee 100644 (file)
@@ -4457,12 +4457,13 @@ void dev_unicast_unsync(struct net_device *to, struct net_device *from)
 }
 EXPORT_SYMBOL(dev_unicast_unsync);
 
-static void dev_unicast_flush(struct net_device *dev)
+void dev_unicast_flush(struct net_device *dev)
 {
        netif_addr_lock_bh(dev);
        __hw_addr_flush(&dev->uc);
        netif_addr_unlock_bh(dev);
 }
+EXPORT_SYMBOL(dev_unicast_flush);
 
 static void dev_unicast_init(struct net_device *dev)
 {
@@ -4484,7 +4485,7 @@ static void __dev_addr_discard(struct dev_addr_list **list)
        }
 }
 
-static void dev_addr_discard(struct net_device *dev)
+void dev_addr_discard(struct net_device *dev)
 {
        netif_addr_lock_bh(dev);
 
@@ -4493,6 +4494,7 @@ static void dev_addr_discard(struct net_device *dev)
 
        netif_addr_unlock_bh(dev);
 }
+EXPORT_SYMBOL(dev_addr_discard);
 
 /**
  *     dev_get_flags - get flags reported to userspace