bonding: Fix up parameter parsing
authorJay Vosburgh <fubar@us.ibm.com>
Fri, 18 Jan 2008 00:25:01 +0000 (16:25 -0800)
committerJeff Garzik <jeff@garzik.org>
Fri, 18 Jan 2008 19:38:38 +0000 (14:38 -0500)
A recent change to add an additional hash policy modified
bond_parse_parm, but it now does not correctly match parameters passed in
via sysfs.

Rewrote bond_parse_parm to handle (a) parameter matches that
are substrings of one another and (b) user input with whitespace (e.g.,
sysfs input often has a trailing newline).

Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h

index 3ede0a2e686089dc94056e83e55bcf45f9d3b01e..379c5d87c80455d44d78db2ae41571bfaa712666 100644 (file)
@@ -4540,18 +4540,27 @@ static void bond_free_all(void)
 
 /*
  * Convert string input module parms.  Accept either the
- * number of the mode or its string name.
+ * number of the mode or its string name.  A bit complicated because
+ * some mode names are substrings of other names, and calls from sysfs
+ * may have whitespace in the name (trailing newlines, for example).
  */
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
+int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
 {
-       int i;
+       int mode = -1, i, rv;
+       char modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };
+
+       rv = sscanf(buf, "%d", &mode);
+       if (!rv) {
+               rv = sscanf(buf, "%20s", modestr);
+               if (!rv)
+                       return -1;
+       }
 
        for (i = 0; tbl[i].modename; i++) {
-               if ((isdigit(*mode_arg) &&
-                    tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
-                   (strcmp(mode_arg, tbl[i].modename) == 0)) {
+               if (mode == tbl[i].mode)
+                       return tbl[i].mode;
+               if (strcmp(modestr, tbl[i].modename) == 0)
                        return tbl[i].mode;
-               }
        }
 
        return -1;
index 28a2d803e7e5bc695f2a26ec011cd564bacf2200..bff4f2b84ce03a4b63acb550ac15f4d162b156f8 100644 (file)
@@ -423,7 +423,7 @@ static ssize_t bonding_store_mode(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, bond_mode_tbl);
+       new_value = bond_parse_parm(buf, bond_mode_tbl);
        if (new_value < 0)  {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid mode value %.*s.\n",
@@ -478,7 +478,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);
+       new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
        if (new_value < 0)  {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
@@ -518,7 +518,7 @@ static ssize_t bonding_store_arp_validate(struct device *d,
        int new_value;
        struct bonding *bond = to_bond(d);
 
-       new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
+       new_value = bond_parse_parm(buf, arp_validate_tbl);
        if (new_value < 0) {
                printk(KERN_ERR DRV_NAME
                       ": %s: Ignoring invalid arp_validate value %s\n",
@@ -941,7 +941,7 @@ static ssize_t bonding_store_lacp(struct device *d,
                goto out;
        }
 
-       new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);
+       new_value = bond_parse_parm(buf, bond_lacp_tbl);
 
        if ((new_value == 1) || (new_value == 0)) {
                bond->params.lacp_fast = new_value;
index e1e4734e23ce7191d0ddb23809c5a710bafa3190..6d83be49899a496fe5125ad3e95d081634a7c269 100644 (file)
@@ -141,6 +141,8 @@ struct bond_parm_tbl {
        int mode;
 };
 
+#define BOND_MAX_MODENAME_LEN 20
+
 struct vlan_entry {
        struct list_head vlan_list;
        __be32 vlan_ip;
@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *);
 void bond_loadbalance_arp_mon(struct work_struct *);
 void bond_activebackup_arp_mon(struct work_struct *);
 void bond_set_mode_ops(struct bonding *bond, int mode);
-int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
+int bond_parse_parm(const char *mode_arg, struct bond_parm_tbl *tbl);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);