diff options
Diffstat (limited to 'drivers/net/bonding/bond_sysfs.c')
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 103 |
1 files changed, 61 insertions, 42 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 08f3d396bcd6..6caac0ffb2f2 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -50,9 +50,9 @@ extern struct bond_parm_tbl bond_mode_tbl[]; | |||
50 | extern struct bond_parm_tbl bond_lacp_tbl[]; | 50 | extern struct bond_parm_tbl bond_lacp_tbl[]; |
51 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; | 51 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; |
52 | extern struct bond_parm_tbl arp_validate_tbl[]; | 52 | extern struct bond_parm_tbl arp_validate_tbl[]; |
53 | extern struct bond_parm_tbl fail_over_mac_tbl[]; | ||
53 | 54 | ||
54 | static int expected_refcount = -1; | 55 | static int expected_refcount = -1; |
55 | static struct class *netdev_class; | ||
56 | /*--------------------------- Data Structures -----------------------------*/ | 56 | /*--------------------------- Data Structures -----------------------------*/ |
57 | 57 | ||
58 | /* Bonding sysfs lock. Why can't we just use the subsystem lock? | 58 | /* Bonding sysfs lock. Why can't we just use the subsystem lock? |
@@ -111,7 +111,6 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t | |||
111 | char *ifname; | 111 | char *ifname; |
112 | int rv, res = count; | 112 | int rv, res = count; |
113 | struct bonding *bond; | 113 | struct bonding *bond; |
114 | struct bonding *nxt; | ||
115 | 114 | ||
116 | sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ | 115 | sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ |
117 | ifname = command + 1; | 116 | ifname = command + 1; |
@@ -122,7 +121,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t | |||
122 | if (command[0] == '+') { | 121 | if (command[0] == '+') { |
123 | printk(KERN_INFO DRV_NAME | 122 | printk(KERN_INFO DRV_NAME |
124 | ": %s is being created...\n", ifname); | 123 | ": %s is being created...\n", ifname); |
125 | rv = bond_create(ifname, &bonding_defaults, &bond); | 124 | rv = bond_create(ifname, &bonding_defaults); |
126 | if (rv) { | 125 | if (rv) { |
127 | printk(KERN_INFO DRV_NAME ": Bond creation failed.\n"); | 126 | printk(KERN_INFO DRV_NAME ": Bond creation failed.\n"); |
128 | res = rv; | 127 | res = rv; |
@@ -134,7 +133,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t | |||
134 | rtnl_lock(); | 133 | rtnl_lock(); |
135 | down_write(&bonding_rwsem); | 134 | down_write(&bonding_rwsem); |
136 | 135 | ||
137 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) | 136 | list_for_each_entry(bond, &bond_dev_list, bond_list) |
138 | if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) { | 137 | if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) { |
139 | /* check the ref count on the bond's kobject. | 138 | /* check the ref count on the bond's kobject. |
140 | * If it's > expected, then there's a file open, | 139 | * If it's > expected, then there's a file open, |
@@ -548,42 +547,37 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib | |||
548 | { | 547 | { |
549 | struct bonding *bond = to_bond(d); | 548 | struct bonding *bond = to_bond(d); |
550 | 549 | ||
551 | return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1; | 550 | return sprintf(buf, "%s %d\n", |
551 | fail_over_mac_tbl[bond->params.fail_over_mac].modename, | ||
552 | bond->params.fail_over_mac); | ||
552 | } | 553 | } |
553 | 554 | ||
554 | static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) | 555 | static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) |
555 | { | 556 | { |
556 | int new_value; | 557 | int new_value; |
557 | int ret = count; | ||
558 | struct bonding *bond = to_bond(d); | 558 | struct bonding *bond = to_bond(d); |
559 | 559 | ||
560 | if (bond->slave_cnt != 0) { | 560 | if (bond->slave_cnt != 0) { |
561 | printk(KERN_ERR DRV_NAME | 561 | printk(KERN_ERR DRV_NAME |
562 | ": %s: Can't alter fail_over_mac with slaves in bond.\n", | 562 | ": %s: Can't alter fail_over_mac with slaves in bond.\n", |
563 | bond->dev->name); | 563 | bond->dev->name); |
564 | ret = -EPERM; | 564 | return -EPERM; |
565 | goto out; | ||
566 | } | 565 | } |
567 | 566 | ||
568 | if (sscanf(buf, "%d", &new_value) != 1) { | 567 | new_value = bond_parse_parm(buf, fail_over_mac_tbl); |
568 | if (new_value < 0) { | ||
569 | printk(KERN_ERR DRV_NAME | 569 | printk(KERN_ERR DRV_NAME |
570 | ": %s: no fail_over_mac value specified.\n", | 570 | ": %s: Ignoring invalid fail_over_mac value %s.\n", |
571 | bond->dev->name); | 571 | bond->dev->name, buf); |
572 | ret = -EINVAL; | 572 | return -EINVAL; |
573 | goto out; | ||
574 | } | 573 | } |
575 | 574 | ||
576 | if ((new_value == 0) || (new_value == 1)) { | 575 | bond->params.fail_over_mac = new_value; |
577 | bond->params.fail_over_mac = new_value; | 576 | printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n", |
578 | printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n", | 577 | bond->dev->name, fail_over_mac_tbl[new_value].modename, |
579 | bond->dev->name, new_value); | 578 | new_value); |
580 | } else { | 579 | |
581 | printk(KERN_INFO DRV_NAME | 580 | return count; |
582 | ": %s: Ignoring invalid fail_over_mac value %d.\n", | ||
583 | bond->dev->name, new_value); | ||
584 | } | ||
585 | out: | ||
586 | return ret; | ||
587 | } | 581 | } |
588 | 582 | ||
589 | static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); | 583 | static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); |
@@ -952,6 +946,45 @@ out: | |||
952 | static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp); | 946 | static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp); |
953 | 947 | ||
954 | /* | 948 | /* |
949 | * Show and set the number of grat ARP to send after a failover event. | ||
950 | */ | ||
951 | static ssize_t bonding_show_n_grat_arp(struct device *d, | ||
952 | struct device_attribute *attr, | ||
953 | char *buf) | ||
954 | { | ||
955 | struct bonding *bond = to_bond(d); | ||
956 | |||
957 | return sprintf(buf, "%d\n", bond->params.num_grat_arp); | ||
958 | } | ||
959 | |||
960 | static ssize_t bonding_store_n_grat_arp(struct device *d, | ||
961 | struct device_attribute *attr, | ||
962 | const char *buf, size_t count) | ||
963 | { | ||
964 | int new_value, ret = count; | ||
965 | struct bonding *bond = to_bond(d); | ||
966 | |||
967 | if (sscanf(buf, "%d", &new_value) != 1) { | ||
968 | printk(KERN_ERR DRV_NAME | ||
969 | ": %s: no num_grat_arp value specified.\n", | ||
970 | bond->dev->name); | ||
971 | ret = -EINVAL; | ||
972 | goto out; | ||
973 | } | ||
974 | if (new_value < 0 || new_value > 255) { | ||
975 | printk(KERN_ERR DRV_NAME | ||
976 | ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n", | ||
977 | bond->dev->name, new_value); | ||
978 | ret = -EINVAL; | ||
979 | goto out; | ||
980 | } else { | ||
981 | bond->params.num_grat_arp = new_value; | ||
982 | } | ||
983 | out: | ||
984 | return ret; | ||
985 | } | ||
986 | static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp); | ||
987 | /* | ||
955 | * Show and set the MII monitor interval. There are two tricky bits | 988 | * Show and set the MII monitor interval. There are two tricky bits |
956 | * here. First, if MII monitoring is activated, then we must disable | 989 | * here. First, if MII monitoring is activated, then we must disable |
957 | * ARP monitoring. Second, if the timer isn't running, we must | 990 | * ARP monitoring. Second, if the timer isn't running, we must |
@@ -1388,6 +1421,7 @@ static struct attribute *per_bond_attrs[] = { | |||
1388 | &dev_attr_updelay.attr, | 1421 | &dev_attr_updelay.attr, |
1389 | &dev_attr_lacp_rate.attr, | 1422 | &dev_attr_lacp_rate.attr, |
1390 | &dev_attr_xmit_hash_policy.attr, | 1423 | &dev_attr_xmit_hash_policy.attr, |
1424 | &dev_attr_num_grat_arp.attr, | ||
1391 | &dev_attr_miimon.attr, | 1425 | &dev_attr_miimon.attr, |
1392 | &dev_attr_primary.attr, | 1426 | &dev_attr_primary.attr, |
1393 | &dev_attr_use_carrier.attr, | 1427 | &dev_attr_use_carrier.attr, |
@@ -1412,19 +1446,9 @@ static struct attribute_group bonding_group = { | |||
1412 | */ | 1446 | */ |
1413 | int bond_create_sysfs(void) | 1447 | int bond_create_sysfs(void) |
1414 | { | 1448 | { |
1415 | int ret = 0; | 1449 | int ret; |
1416 | struct bonding *firstbond; | ||
1417 | |||
1418 | /* get the netdev class pointer */ | ||
1419 | firstbond = container_of(bond_dev_list.next, struct bonding, bond_list); | ||
1420 | if (!firstbond) | ||
1421 | return -ENODEV; | ||
1422 | 1450 | ||
1423 | netdev_class = firstbond->dev->dev.class; | 1451 | ret = netdev_class_create_file(&class_attr_bonding_masters); |
1424 | if (!netdev_class) | ||
1425 | return -ENODEV; | ||
1426 | |||
1427 | ret = class_create_file(netdev_class, &class_attr_bonding_masters); | ||
1428 | /* | 1452 | /* |
1429 | * Permit multiple loads of the module by ignoring failures to | 1453 | * Permit multiple loads of the module by ignoring failures to |
1430 | * create the bonding_masters sysfs file. Bonding devices | 1454 | * create the bonding_masters sysfs file. Bonding devices |
@@ -1443,10 +1467,6 @@ int bond_create_sysfs(void) | |||
1443 | printk(KERN_ERR | 1467 | printk(KERN_ERR |
1444 | "network device named %s already exists in sysfs", | 1468 | "network device named %s already exists in sysfs", |
1445 | class_attr_bonding_masters.attr.name); | 1469 | class_attr_bonding_masters.attr.name); |
1446 | else { | ||
1447 | netdev_class = NULL; | ||
1448 | return 0; | ||
1449 | } | ||
1450 | } | 1470 | } |
1451 | 1471 | ||
1452 | return ret; | 1472 | return ret; |
@@ -1458,8 +1478,7 @@ int bond_create_sysfs(void) | |||
1458 | */ | 1478 | */ |
1459 | void bond_destroy_sysfs(void) | 1479 | void bond_destroy_sysfs(void) |
1460 | { | 1480 | { |
1461 | if (netdev_class) | 1481 | netdev_class_remove_file(&class_attr_bonding_masters); |
1462 | class_remove_file(netdev_class, &class_attr_bonding_masters); | ||
1463 | } | 1482 | } |
1464 | 1483 | ||
1465 | /* | 1484 | /* |