bonding: check return value of nofitier when changing type
authorJiri Pirko <jpirko@redhat.com>
Wed, 10 Mar 2010 10:29:35 +0000 (10:29 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 19 Mar 2010 03:00:02 +0000 (20:00 -0700)
This patch adds the possibility to refuse the bonding type change for
other subsystems (such as for example bridge, vlan, etc.)

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 7eeb18751d67592eef914e92bbff7f35b2819f65..cbe9e353d46a9fab051beb88f2a477d2d27296ce 100644 (file)
@@ -1480,8 +1480,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                                 bond_dev->name,
                                 bond_dev->type, slave_dev->type);
 
-                       netdev_bonding_change(bond_dev,
-                                             NETDEV_PRE_TYPE_CHANGE);
+                       res = netdev_bonding_change(bond_dev,
+                                                   NETDEV_PRE_TYPE_CHANGE);
+                       res = notifier_to_errno(res);
+                       if (res) {
+                               pr_err("%s: refused to change device type\n",
+                                      bond_dev->name);
+                               res = -EBUSY;
+                               goto err_undo_flags;
+                       }
 
                        if (slave_dev->type != ARPHRD_ETHER)
                                bond_setup_by_slave(bond_dev, slave_dev);
index 726ecd1af535cc77d6e01f271131145cf101a53b..813bed723f58bfae538257c35cfd6848c93c9ecb 100644 (file)
@@ -2005,7 +2005,7 @@ extern void               __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct
 extern int             dev_set_promiscuity(struct net_device *dev, int inc);
 extern int             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 int             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 */
index 1a7e1d1d5ad95304830385d0775733db910f56b5..d1f027c41e73db3490e3e9577edcd01d17aa7d8f 100644 (file)
@@ -1084,9 +1084,9 @@ void netdev_state_change(struct net_device *dev)
 }
 EXPORT_SYMBOL(netdev_state_change);
 
-void netdev_bonding_change(struct net_device *dev, unsigned long event)
+int netdev_bonding_change(struct net_device *dev, unsigned long event)
 {
-       call_netdevice_notifiers(event, dev);
+       return call_netdevice_notifiers(event, dev);
 }
 EXPORT_SYMBOL(netdev_bonding_change);