Received: with ECARTIS (v1.0.0; list netdev); Thu, 08 Jan 2004 08:31:32 -0800 (PST) Received: from hermes.iil.intel.com (hermes.iil.intel.com [192.198.152.99]) by oss.sgi.com (8.12.10/8.12.9) with SMTP id i08GVDTa012934 for ; Thu, 8 Jan 2004 08:31:15 -0800 Received: from petasus.iil.intel.com (petasus.iil.intel.com [143.185.77.3]) by hermes.iil.intel.com (8.12.9-20030918-01/8.12.9/d: large-outer.mc,v 1.6 2003/12/18 18:57:17 root Exp $) with ESMTP id i08GUwek013210; Thu, 8 Jan 2004 16:30:58 GMT Received: from hasmsxvs01.iil.intel.com (hasmsxvs01.iil.intel.com [143.185.63.58]) by petasus.iil.intel.com (8.12.9-20030918-01/8.12.9/d: large-inner.mc,v 1.8 2003/12/18 18:57:16 root Exp $) with SMTP id i08GUwxX001629; Thu, 8 Jan 2004 16:30:58 GMT Received: from sun111.npdj.intel.com ([10.12.254.111]) by hasmsxvs01.iil.intel.com (SAVSMTP 3.1.2.35) with SMTP id M2004010818305719342 ; Thu, 08 Jan 2004 18:30:57 +0200 Received: from jrslxjul4.npdj.intel.com (jrslxjul4 [10.12.220.54]) by sun111.npdj.intel.com (8.12.10/8.12.9/MailSET/Hub) with ESMTP id i08GUthb004074; Thu, 8 Jan 2004 18:30:56 +0200 (IST) From: Amir Noam To: "Jeff Garzik" , "Jay Vosburgh" Subject: [PATCH 4/4] [bonding 2.6] Support old commands over new bonding ioctl Date: Thu, 8 Jan 2004 18:30:55 +0200 User-Agent: KMail/1.5.3 Cc: , MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200401081830.55891.amir.noam@intel.com> X-Scanned-By: MIMEDefang 2.31 (www . roaringpenguin . com / mimedefang) X-archive-position: 2280 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: amir.noam@intel.com Precedence: bulk X-list: netdev Content-Length: 4415 Lines: 177 Support old commands (enslave, release, change-active) over the new bonding ioctl (SIOCBONDDEVICE). diff -Nuarp a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c --- a/drivers/net/bonding/bond_main.c Thu Jan 8 18:06:53 2004 +++ b/drivers/net/bonding/bond_main.c Thu Jan 8 18:06:54 2004 @@ -1955,6 +1955,86 @@ static int bond_ethtool_ioctl(struct net } } +static int bond_ioctl_slave_dev(struct bonding *bond, int cmd, void *addr) +{ + struct bond_ioctl_cmd bond_cmd; + struct net_device *slave_dev; + int prev_abi_ver = app_abi_ver; + int prev_orig_abi_ver = orig_app_abi_ver; + int res = 0; + + if (copy_from_user(&bond_cmd, addr, sizeof(bond_cmd))) { + return -EFAULT; + } + + bond_cmd.ifname[IFNAMSIZ - 1] = 0; + + slave_dev = dev_get_by_name(bond_cmd.ifname); + if (!slave_dev) { + return -ENODEV; + } + + /* This is for backward compatibility only. + * Unconditionaly set both global abi_ver vars so we can block + * old ioctls in bond_do_ioctl(). + */ + orig_app_abi_ver = bond_cmd.abi_ver; + app_abi_ver = bond_cmd.abi_ver; + + switch (cmd) { + case BOND_CMD_ENSLAVE: + res = bond_enslave(bond->dev, slave_dev, bond_cmd.abi_ver); + break; + + case BOND_CMD_RELEASE: + res = bond_release(bond->dev, slave_dev); + break; + + case BOND_CMD_CHANGE_ACTIVE: + res = bond_ioctl_change_active(bond->dev, slave_dev); + break; + + default: + res = -EOPNOTSUPP; + break; + } + + dev_put(slave_dev); + + if (res < 0) { + /* The ioctl failed, so there's no point in changing the + * orig_app_abi_ver. We'll restore it's value just in case + * we've changed it earlier in this function. + */ + app_abi_ver = prev_abi_ver; + orig_app_abi_ver = prev_orig_abi_ver; + } + + return res; +} + +static int bond_ioctl_device(struct bonding *bond, void *addr) +{ + u32 cmd; + + if (get_user(cmd, (u32 *) addr)) { + return -EFAULT; + } + + switch (cmd) { + case BOND_CMD_ENSLAVE: + case BOND_CMD_RELEASE: + case BOND_CMD_CHANGE_ACTIVE: + /* these ioctl cmds receive a slave name as an arg */ + return bond_ioctl_slave_dev(bond, cmd, addr); + + default: + return -EOPNOTSUPP; + } + + return 0; +} + static int bond_info_query(struct net_device *bond_dev, struct ifbond *info) { struct bonding *bond = bond_dev->priv; @@ -3213,6 +3293,7 @@ static struct net_device_stats *bond_get static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) { + struct bonding *bond = bond_dev->priv; struct net_device *slave_dev = NULL; struct ifbond *u_binfo = NULL, k_binfo; struct ifslave *u_sinfo = NULL, k_sinfo; @@ -3223,6 +3304,10 @@ static int bond_do_ioctl(struct net_devi dprintk("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd); + if (!capable(CAP_NET_ADMIN)) { + return -EPERM; + } + switch (cmd) { case SIOCETHTOOL: return bond_ethtool_ioctl(bond_dev, ifr); @@ -3244,7 +3329,6 @@ static int bond_do_ioctl(struct net_devi } if (mii->reg_num == 1) { - struct bonding *bond = bond_dev->priv; mii->val_out = 0; read_lock_bh(&bond->lock); read_lock(&bond->curr_slave_lock); @@ -3288,13 +3372,19 @@ static int bond_do_ioctl(struct net_devi } return res; + case SIOCBONDDEVICE: + return bond_ioctl_device(bond, ifr->ifr_data); + default: /* Go on */ break; } - if (!capable(CAP_NET_ADMIN)) { - return -EPERM; + if (orig_app_abi_ver > 2) { + /* Refuse to support old ioctls if the app has already + * declared it is new enough for SIOCBONDDEVICE commands. + */ + return -EOPNOTSUPP; } if (orig_app_abi_ver == -1) { diff -Nuarp a/include/linux/if_bonding.h b/include/linux/if_bonding.h --- a/include/linux/if_bonding.h Thu Jan 8 18:06:53 2004 +++ b/include/linux/if_bonding.h Thu Jan 8 18:06:54 2004 @@ -112,6 +112,9 @@ struct ad_info { #define BOND_CMD_DRV_INFO 0x00000001 #define BOND_CMD_ADD_BOND 0x00000002 #define BOND_CMD_DEL_BOND 0x00000003 +#define BOND_CMD_ENSLAVE 0x00000004 +#define BOND_CMD_RELEASE 0x00000005 +#define BOND_CMD_CHANGE_ACTIVE 0x00000006 /** * bond_ioctl_drv_info @@ -127,6 +130,19 @@ struct bond_ioctl_drv_info { char reserved[32]; }; +/** + * bond_ioctl_cmd + * + * %BOND_CMD_ENSLAVE, %BOND_CMD_RELEASE and %BOND_CMD_CHANGE_ACTIVE pass the + * name of the slave to work on in @ifname. + */ +struct bond_ioctl_cmd { + __u32 cmd; + __u32 abi_ver; + __u32 num_prms; + char ifname[IFNAMSIZ]; +}; + #endif /* _LINUX_IF_BONDING_H */ /*