Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -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;
+4 −4
Original line number Diff line number Diff line
@@ -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;
+3 −1
Original line number Diff line number Diff line
@@ -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 *);