All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/4] [bonding 2.4] Support old commands over new bonding ioctl
@ 2004-01-08 16:25 Amir Noam
  0 siblings, 0 replies; only message in thread
From: Amir Noam @ 2004-01-08 16:25 UTC (permalink / raw)
  To: Jeff Garzik, Jay Vosburgh; +Cc: bonding-devel, netdev

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:03:27 2004
+++ b/drivers/net/bonding/bond_main.c	Thu Jan  8 18:03:29 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;
@@ -3214,6 +3294,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;
@@ -3224,6 +3305,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);
@@ -3245,7 +3330,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);
@@ -3289,13 +3373,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:03:27 2004
+++ b/include/linux/if_bonding.h	Thu Jan  8 18:03:29 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 */
 
 /*

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2004-01-08 16:25 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-08 16:25 [PATCH 4/4] [bonding 2.4] Support old commands over new bonding ioctl Amir Noam

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.