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: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
committed by
Jeff Garzik
parent
3b96c858fc
commit
ece95f7fef
@@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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 *);
|
|||||||
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 *);
|
||||||
|
Reference in New Issue
Block a user