Commit ece95f7f authored by Jay Vosburgh's avatar Jay Vosburgh Committed by Jeff Garzik

bonding: Fix up parameter parsing

	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: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 3b96c858
...@@ -4540,18 +4540,27 @@ static void bond_free_all(void) ...@@ -4540,18 +4540,27 @@ static void bond_free_all(void)
/* /*
* Convert string input module parms. Accept either the * 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++) { for (i = 0; tbl[i].modename; i++) {
if ((isdigit(*mode_arg) && if (mode == tbl[i].mode)
tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || return tbl[i].mode;
(strcmp(mode_arg, tbl[i].modename) == 0)) { if (strcmp(modestr, tbl[i].modename) == 0)
return tbl[i].mode; return tbl[i].mode;
}
} }
return -1; return -1;
......
...@@ -423,7 +423,7 @@ static ssize_t bonding_store_mode(struct device *d, ...@@ -423,7 +423,7 @@ static ssize_t bonding_store_mode(struct device *d,
goto out; 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) { if (new_value < 0) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": %s: Ignoring invalid mode value %.*s.\n", ": %s: Ignoring invalid mode value %.*s.\n",
...@@ -478,7 +478,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d, ...@@ -478,7 +478,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
goto out; 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) { if (new_value < 0) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": %s: Ignoring invalid xmit hash policy value %.*s.\n", ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
...@@ -518,7 +518,7 @@ static ssize_t bonding_store_arp_validate(struct device *d, ...@@ -518,7 +518,7 @@ static ssize_t bonding_store_arp_validate(struct device *d,
int new_value; int new_value;
struct bonding *bond = to_bond(d); 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) { if (new_value < 0) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
": %s: Ignoring invalid arp_validate value %s\n", ": %s: Ignoring invalid arp_validate value %s\n",
...@@ -941,7 +941,7 @@ static ssize_t bonding_store_lacp(struct device *d, ...@@ -941,7 +941,7 @@ static ssize_t bonding_store_lacp(struct device *d,
goto out; 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)) { if ((new_value == 1) || (new_value == 0)) {
bond->params.lacp_fast = new_value; bond->params.lacp_fast = new_value;
......
...@@ -141,6 +141,8 @@ struct bond_parm_tbl { ...@@ -141,6 +141,8 @@ struct bond_parm_tbl {
int mode; int mode;
}; };
#define BOND_MAX_MODENAME_LEN 20
struct vlan_entry { struct vlan_entry {
struct list_head vlan_list; struct list_head vlan_list;
__be32 vlan_ip; __be32 vlan_ip;
...@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *); ...@@ -314,7 +316,7 @@ void bond_mii_monitor(struct work_struct *);
void bond_loadbalance_arp_mon(struct work_struct *); void bond_loadbalance_arp_mon(struct work_struct *);
void bond_activebackup_arp_mon(struct work_struct *); void bond_activebackup_arp_mon(struct work_struct *);
void bond_set_mode_ops(struct bonding *bond, int mode); 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_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active); void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
void bond_register_arp(struct bonding *); void bond_register_arp(struct bonding *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment