bond_sysfs.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 1,365 行 · 第 1/3 页

C
1,365
字号
	} else {		count = sprintf(buf, "%s %d\n",			xmit_hashtype_tbl[bond->params.xmit_policy].modename,			bond->params.xmit_policy) + 1;	}	return count;}static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count){	int new_value, ret = count;	struct bonding *bond = to_bond(cd);	if (bond->dev->flags & IFF_UP) {		printk(KERN_ERR DRV_NAME		       "%s: Interface is up. Unable to update xmit policy.\n",		       bond->dev->name);		ret = -EPERM;		goto out;	}	if ((bond->params.mode != BOND_MODE_XOR) &&	    (bond->params.mode != BOND_MODE_8023AD)) {		printk(KERN_ERR DRV_NAME		       "%s: Transmit hash policy is irrelevant in this mode.\n",		       bond->dev->name);		ret = -EPERM;		goto out;	}	new_value = bond_parse_parm((char *)buf, xmit_hashtype_tbl);	if (new_value < 0)  {		printk(KERN_ERR DRV_NAME		       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",		       bond->dev->name,		       (int)strlen(buf) - 1, buf);		ret = -EINVAL;		goto out;	} else {		bond->params.xmit_policy = new_value;		bond_set_mode_ops(bond, bond->params.mode);		printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",			bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);	}out:	return ret;}static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);/* * Show and set the arp timer interval.  There are two tricky bits * here.  First, if ARP monitoring is activated, then we must disable * MII monitoring.  Second, if the ARP timer isn't running, we must * start it. */static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf){	struct bonding *bond = to_bond(cd);	return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;}static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count){	int new_value, ret = count;	struct bonding *bond = to_bond(cd);	if (sscanf(buf, "%d", &new_value) != 1) {		printk(KERN_ERR DRV_NAME		       ": %s: no arp_interval value specified.\n",		       bond->dev->name);		ret = -EINVAL;		goto out;	}	if (new_value < 0) {		printk(KERN_ERR DRV_NAME		       ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",		       bond->dev->name, new_value, INT_MAX);		ret = -EINVAL;		goto out;	}	printk(KERN_INFO DRV_NAME	       ": %s: Setting ARP monitoring interval to %d.\n",	       bond->dev->name, new_value);	bond->params.arp_interval = new_value;	if (bond->params.miimon) {		printk(KERN_INFO DRV_NAME		       ": %s: ARP monitoring cannot be used with MII monitoring. "		       "%s Disabling MII monitoring.\n",		       bond->dev->name, bond->dev->name);		bond->params.miimon = 0;		/* Kill MII timer, else it brings bond's link down */		if (bond->arp_timer.function) {			printk(KERN_INFO DRV_NAME			": %s: Kill MII timer, else it brings bond's link down...\n",		       bond->dev->name);			del_timer_sync(&bond->mii_timer);		}	}	if (!bond->params.arp_targets[0]) {		printk(KERN_INFO DRV_NAME		       ": %s: ARP monitoring has been set up, "		       "but no ARP targets have been specified.\n",		       bond->dev->name);	}	if (bond->dev->flags & IFF_UP) {		/* If the interface is up, we may need to fire off		 * the ARP timer.  If the interface is down, the		 * timer will get fired off when the open function		 * is called.		 */		if (bond->arp_timer.function) {			/* The timer's already set up, so fire it off */			mod_timer(&bond->arp_timer, jiffies + 1);		} else {			/* Set up the timer. */			init_timer(&bond->arp_timer);			bond->arp_timer.expires = jiffies + 1;			bond->arp_timer.data =				(unsigned long) bond->dev;			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {				bond->arp_timer.function =					(void *)					&bond_activebackup_arp_mon;			} else {				bond->arp_timer.function =					(void *)					&bond_loadbalance_arp_mon;			}			add_timer(&bond->arp_timer);		}	}out:	return ret;}static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);/* * Show and set the arp targets. */static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf){	int i, res = 0;	struct bonding *bond = to_bond(cd);	for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {		if (bond->params.arp_targets[i])			res += sprintf(buf + res, "%u.%u.%u.%u ",			       NIPQUAD(bond->params.arp_targets[i]));	}	if (res)		res--;  /* eat the leftover space */	res += sprintf(buf + res, "\n");	res++;	return res;}static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count){	u32 newtarget;	int i = 0, done = 0, ret = count;	struct bonding *bond = to_bond(cd);	u32 *targets;	targets = bond->params.arp_targets;	newtarget = in_aton(buf + 1);	/* look for adds */	if (buf[0] == '+') {		if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {			printk(KERN_ERR DRV_NAME			       ": %s: invalid ARP target %u.%u.%u.%u specified for addition\n", 			       bond->dev->name, NIPQUAD(newtarget));			ret = -EINVAL;			goto out;		}		/* look for an empty slot to put the target in, and check for dupes */		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {			if (targets[i] == newtarget) { /* duplicate */				printk(KERN_ERR DRV_NAME				       ": %s: ARP target %u.%u.%u.%u is already present\n",				       bond->dev->name, NIPQUAD(newtarget));				if (done)					targets[i] = 0;				ret = -EINVAL;				goto out;			}			if (targets[i] == 0 && !done) {				printk(KERN_INFO DRV_NAME				       ": %s: adding ARP target %d.%d.%d.%d.\n",				       bond->dev->name, NIPQUAD(newtarget));				done = 1;				targets[i] = newtarget;			}		}		if (!done) {			printk(KERN_ERR DRV_NAME			       ": %s: ARP target table is full!\n",			       bond->dev->name);			ret = -EINVAL;			goto out;		}	}	else if (buf[0] == '-')	{		if ((newtarget == 0) || (newtarget == INADDR_BROADCAST)) {			printk(KERN_ERR DRV_NAME			       ": %s: invalid ARP target %d.%d.%d.%d specified for removal\n",			       bond->dev->name, NIPQUAD(newtarget));			ret = -EINVAL;			goto out;		}		for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {			if (targets[i] == newtarget) {				printk(KERN_INFO DRV_NAME				       ": %s: removing ARP target %d.%d.%d.%d.\n",				       bond->dev->name, NIPQUAD(newtarget));				targets[i] = 0;				done = 1;			}		}		if (!done) {			printk(KERN_INFO DRV_NAME			       ": %s: unable to remove nonexistent ARP target %d.%d.%d.%d.\n",			       bond->dev->name, NIPQUAD(newtarget));			ret = -EINVAL;			goto out;		}	}	else {		printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",			bond->dev->name);		ret = -EPERM;		goto out;	}out:	return ret;}static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);/* * Show and set the up and down delays.  These must be multiples of the * MII monitoring value, and are stored internally as the multiplier. * Thus, we must translate to MS for the real world. */static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf){	struct bonding *bond = to_bond(cd);	return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;}static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count){	int new_value, ret = count;	struct bonding *bond = to_bond(cd);	if (!(bond->params.miimon)) {		printk(KERN_ERR DRV_NAME		       ": %s: Unable to set down delay as MII monitoring is disabled\n",		       bond->dev->name);		ret = -EPERM;		goto out;	}	if (sscanf(buf, "%d", &new_value) != 1) {		printk(KERN_ERR DRV_NAME		       ": %s: no down delay value specified.\n",		       bond->dev->name);		ret = -EINVAL;		goto out;	}	if (new_value < 0) {		printk(KERN_ERR DRV_NAME		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",		       bond->dev->name, new_value, 1, INT_MAX);		ret = -EINVAL;		goto out;	} else {		if ((new_value % bond->params.miimon) != 0) {			printk(KERN_WARNING DRV_NAME			       ": %s: Warning: down delay (%d) is not a multiple "			       "of miimon (%d), delay rounded to %d ms\n",			       bond->dev->name, new_value, bond->params.miimon,			       (new_value / bond->params.miimon) *			       bond->params.miimon);		}		bond->params.downdelay = new_value / bond->params.miimon;		printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",		       bond->dev->name, bond->params.downdelay * bond->params.miimon);	}out:	return ret;}static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);static ssize_t bonding_show_updelay(struct class_device *cd, char *buf){	struct bonding *bond = to_bond(cd);	return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;}static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count){	int new_value, ret = count;	struct bonding *bond = to_bond(cd);	if (!(bond->params.miimon)) {		printk(KERN_ERR DRV_NAME		       ": %s: Unable to set up delay as MII monitoring is disabled\n",		       bond->dev->name);		ret = -EPERM;		goto out;	}	if (sscanf(buf, "%d", &new_value) != 1) {		printk(KERN_ERR DRV_NAME		       ": %s: no up delay value specified.\n",		       bond->dev->name);		ret = -EINVAL;		goto out;	}	if (new_value < 0) {		printk(KERN_ERR DRV_NAME		       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",		       bond->dev->name, new_value, 1, INT_MAX);		ret = -EINVAL;		goto out;	} else {		if ((new_value % bond->params.miimon) != 0) {			printk(KERN_WARNING DRV_NAME			       ": %s: Warning: up delay (%d) is not a multiple "			       "of miimon (%d), updelay rounded to %d ms\n",			       bond->dev->name, new_value, bond->params.miimon,			       (new_value / bond->params.miimon) *			       bond->params.miimon);		}		bond->params.updelay = new_value / bond->params.miimon;		printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",		       bond->dev->name, bond->params.updelay * bond->params.miimon);	}out:	return ret;}static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);/* * Show and set the LACP interval.  Interface must be down, and the mode * must be set to 802.3ad mode. */static ssize_t bonding_show_lacp(struct class_device *cd, char *buf){	struct bonding *bond = to_bond(cd);	return sprintf(buf, "%s %d\n",		bond_lacp_tbl[bond->params.lacp_fast].modename,		bond->params.lacp_fast) + 1;}static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count){	int new_value, ret = count;	struct bonding *bond = to_bond(cd);	if (bond->dev->flags & IFF_UP) {		printk(KERN_ERR DRV_NAME		       ": %s: Unable to update LACP rate because interface is up.\n",		       bond->dev->name);		ret = -EPERM;		goto out;	}	if (bond->params.mode != BOND_MODE_8023AD) {		printk(KERN_ERR DRV_NAME		       ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",		       bond->dev->name);		ret = -EPERM;		goto out;	}	new_value = bond_parse_parm((char *)buf, bond_lacp_tbl);	if ((new_value == 1) || (new_value == 0)) {		bond->params.lacp_fast = new_value;		printk(KERN_INFO DRV_NAME		       ": %s: Setting LACP rate to %s (%d).\n",		       bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);	} else {		printk(KERN_ERR DRV_NAME		       ": %s: Ignoring invalid LACP rate value %.*s.\n",		     	bond->dev->name, (int)strlen(buf) - 1, buf);		ret = -EINVAL;	}out:	return ret;}static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);/* * Show and set the MII monitor interval.  There are two tricky bits * here.  First, if MII monitoring is activated, then we must disable * ARP monitoring.  Second, if the timer isn't running, we must * start it. */static ssize_t bonding_show_miimon(struct class_device *cd, char *buf){	struct bonding *bond = to_bond(cd);	return sprintf(buf, "%d\n", bond->params.miimon) + 1;}static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count){	int new_value, ret = count;	struct bonding *bond = to_bond(cd);	if (sscanf(buf, "%d", &new_value) != 1) {		printk(KERN_ERR DRV_NAME		       ": %s: no miimon value specified.\n",		       bond->dev->name);		ret = -EINVAL;		goto out;	}	if (new_value < 0) {		printk(KERN_ERR DRV_NAME		       ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",		       bond->dev->name, new_value, 1, INT_MAX);		ret = -EINVAL;		goto out;	} else {		printk(KERN_INFO DRV_NAME		       ": %s: Setting MII monitoring interval to %d.\n",		       bond->dev->name, new_value);		bond->params.miimon = new_value;		if(bond->params.updelay)			printk(KERN_INFO DRV_NAME			      ": %s: Note: Updating updelay (to %d) "			      "since it is a multiple of the miimon value.\n",			      bond->dev->name,			      bond->params.updelay * bond->params.miimon);		if(bond->params.downdelay)			printk(KERN_INFO DRV_NAME			      ": %s: Note: Updating downdelay (to %d) "			      "since it is a multiple of the miimon value.\n",			      bond->dev->name,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?