diff options
Diffstat (limited to 'drivers/net/bonding/bond_sysfs.c')
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 167 | 
1 files changed, 105 insertions, 62 deletions
| diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 88fcb25e554a..2dfb4bf90087 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -804,6 +804,7 @@ static ssize_t bonding_store_lacp(struct device *d,  	if ((new_value == 1) || (new_value == 0)) {  		bond->params.lacp_fast = new_value; +		bond_3ad_update_lacp_rate(bond);  		pr_info("%s: Setting LACP rate to %s (%d).\n",  			bond->dev->name, bond_lacp_tbl[new_value].modename,  			new_value); @@ -818,6 +819,38 @@ out:  static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,  		   bonding_show_lacp, bonding_store_lacp); +static ssize_t bonding_show_min_links(struct device *d, +				      struct device_attribute *attr, +				      char *buf) +{ +	struct bonding *bond = to_bond(d); + +	return sprintf(buf, "%d\n", bond->params.min_links); +} + +static ssize_t bonding_store_min_links(struct device *d, +				       struct device_attribute *attr, +				       const char *buf, size_t count) +{ +	struct bonding *bond = to_bond(d); +	int ret; +	unsigned int new_value; + +	ret = kstrtouint(buf, 0, &new_value); +	if (ret < 0) { +		pr_err("%s: Ignoring invalid min links value %s.\n", +		       bond->dev->name, buf); +		return ret; +	} + +	pr_info("%s: Setting min links value to %u\n", +		bond->dev->name, new_value); +	bond->params.min_links = new_value; +	return count; +} +static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, +		   bonding_show_min_links, bonding_store_min_links); +  static ssize_t bonding_show_ad_select(struct device *d,  				      struct device_attribute *attr,  				      char *buf) @@ -992,6 +1025,7 @@ static ssize_t bonding_store_primary(struct device *d,  	int i;  	struct slave *slave;  	struct bonding *bond = to_bond(d); +	char ifname[IFNAMSIZ];  	if (!rtnl_trylock())  		return restart_syscall(); @@ -1002,32 +1036,33 @@ static ssize_t bonding_store_primary(struct device *d,  	if (!USES_PRIMARY(bond->params.mode)) {  		pr_info("%s: Unable to set primary slave; %s is in mode %d\n",  			bond->dev->name, bond->dev->name, bond->params.mode); -	} else { -		bond_for_each_slave(bond, slave, i) { -			if (strnicmp -			    (slave->dev->name, buf, -			     strlen(slave->dev->name)) == 0) { -				pr_info("%s: Setting %s as primary slave.\n", -					bond->dev->name, slave->dev->name); -				bond->primary_slave = slave; -				strcpy(bond->params.primary, slave->dev->name); -				bond_select_active_slave(bond); -				goto out; -			} -		} +		goto out; +	} -		/* if we got here, then we didn't match the name of any slave */ +	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ -		if (strlen(buf) == 0 || buf[0] == '\n') { -			pr_info("%s: Setting primary slave to None.\n", -				bond->dev->name); -			bond->primary_slave = NULL; -				bond_select_active_slave(bond); -		} else { -			pr_info("%s: Unable to set %.*s as primary slave as it is not a slave.\n", -				bond->dev->name, (int)strlen(buf) - 1, buf); +	/* check to see if we are clearing primary */ +	if (!strlen(ifname) || buf[0] == '\n') { +		pr_info("%s: Setting primary slave to None.\n", +			bond->dev->name); +		bond->primary_slave = NULL; +		bond_select_active_slave(bond); +		goto out; +	} + +	bond_for_each_slave(bond, slave, i) { +		if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { +			pr_info("%s: Setting %s as primary slave.\n", +				bond->dev->name, slave->dev->name); +			bond->primary_slave = slave; +			strcpy(bond->params.primary, slave->dev->name); +			bond_select_active_slave(bond); +			goto out;  		}  	} + +	pr_info("%s: Unable to set %.*s as primary slave.\n", +		bond->dev->name, (int)strlen(buf) - 1, buf);  out:  	write_unlock_bh(&bond->curr_slave_lock);  	read_unlock(&bond->lock); @@ -1162,6 +1197,7 @@ static ssize_t bonding_store_active_slave(struct device *d,  	struct slave *old_active = NULL;  	struct slave *new_active = NULL;  	struct bonding *bond = to_bond(d); +	char ifname[IFNAMSIZ];  	if (!rtnl_trylock())  		return restart_syscall(); @@ -1170,56 +1206,62 @@ static ssize_t bonding_store_active_slave(struct device *d,  	read_lock(&bond->lock);  	write_lock_bh(&bond->curr_slave_lock); -	if (!USES_PRIMARY(bond->params.mode)) +	if (!USES_PRIMARY(bond->params.mode)) {  		pr_info("%s: Unable to change active slave; %s is in mode %d\n",  			bond->dev->name, bond->dev->name, bond->params.mode); -	else { -		bond_for_each_slave(bond, slave, i) { -			if (strnicmp -			    (slave->dev->name, buf, -			     strlen(slave->dev->name)) == 0) { -        			old_active = bond->curr_active_slave; -        			new_active = slave; -        			if (new_active == old_active) { -					/* do nothing */ -					pr_info("%s: %s is already the current active slave.\n", +		goto out; +	} + +	sscanf(buf, "%16s", ifname); /* IFNAMSIZ */ + +	/* check to see if we are clearing active */ +	if (!strlen(ifname) || buf[0] == '\n') { +		pr_info("%s: Clearing current active slave.\n", +			bond->dev->name); +		bond->curr_active_slave = NULL; +		bond_select_active_slave(bond); +		goto out; +	} + +	bond_for_each_slave(bond, slave, i) { +		if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { +			old_active = bond->curr_active_slave; +			new_active = slave; +			if (new_active == old_active) { +				/* do nothing */ +				pr_info("%s: %s is already the current" +					" active slave.\n", +					bond->dev->name, +					slave->dev->name); +				goto out; +			} +			else { +				if ((new_active) && +				    (old_active) && +				    (new_active->link == BOND_LINK_UP) && +				    IS_UP(new_active->dev)) { +					pr_info("%s: Setting %s as active" +						" slave.\n",  						bond->dev->name,  						slave->dev->name); -					goto out; +					bond_change_active_slave(bond, +								 new_active);  				}  				else { -        				if ((new_active) && -            				    (old_active) && -				            (new_active->link == BOND_LINK_UP) && -				            IS_UP(new_active->dev)) { -						pr_info("%s: Setting %s as active slave.\n", -							bond->dev->name, -							slave->dev->name); -							bond_change_active_slave(bond, new_active); -        				} -					else { -						pr_info("%s: Could not set %s as active slave; either %s is down or the link is down.\n", -							bond->dev->name, -							slave->dev->name, -							slave->dev->name); -					} -					goto out; +					pr_info("%s: Could not set %s as" +						" active slave; either %s is" +						" down or the link is down.\n", +						bond->dev->name, +						slave->dev->name, +						slave->dev->name);  				} +				goto out;  			}  		} - -		/* if we got here, then we didn't match the name of any slave */ - -		if (strlen(buf) == 0 || buf[0] == '\n') { -			pr_info("%s: Setting active slave to None.\n", -				bond->dev->name); -			bond->primary_slave = NULL; -			bond_select_active_slave(bond); -		} else { -			pr_info("%s: Unable to set %.*s as active slave as it is not a slave.\n", -				bond->dev->name, (int)strlen(buf) - 1, buf); -		}  	} + +	pr_info("%s: Unable to set %.*s as active slave.\n", +		bond->dev->name, (int)strlen(buf) - 1, buf);   out:  	write_unlock_bh(&bond->curr_slave_lock);  	read_unlock(&bond->lock); @@ -1600,6 +1642,7 @@ static struct attribute *per_bond_attrs[] = {  	&dev_attr_queue_id.attr,  	&dev_attr_all_slaves_active.attr,  	&dev_attr_resend_igmp.attr, +	&dev_attr_min_links.attr,  	NULL,  }; | 
