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 + -
显示快捷键?