diff options
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 4 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_netlink.c | 9 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_options.c | 30 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_options.h | 3 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 24 | ||||
| -rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
6 files changed, 36 insertions, 35 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 59edf18602d9..2ca949f6e995 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -3123,6 +3123,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
| 3123 | struct ifslave k_sinfo; | 3123 | struct ifslave k_sinfo; |
| 3124 | struct ifslave __user *u_sinfo = NULL; | 3124 | struct ifslave __user *u_sinfo = NULL; |
| 3125 | struct mii_ioctl_data *mii = NULL; | 3125 | struct mii_ioctl_data *mii = NULL; |
| 3126 | struct bond_opt_value newval; | ||
| 3126 | struct net *net; | 3127 | struct net *net; |
| 3127 | int res = 0; | 3128 | int res = 0; |
| 3128 | 3129 | ||
| @@ -3218,7 +3219,8 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
| 3218 | break; | 3219 | break; |
| 3219 | case BOND_CHANGE_ACTIVE_OLD: | 3220 | case BOND_CHANGE_ACTIVE_OLD: |
| 3220 | case SIOCBONDCHANGEACTIVE: | 3221 | case SIOCBONDCHANGEACTIVE: |
| 3221 | res = bond_option_active_slave_set(bond, slave_dev); | 3222 | bond_opt_initstr(&newval, slave_dev->name); |
| 3223 | res = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval); | ||
| 3222 | break; | 3224 | break; |
| 3223 | default: | 3225 | default: |
| 3224 | res = -EOPNOTSUPP; | 3226 | res = -EOPNOTSUPP; |
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index 2175e1926e5a..dba1f2e22371 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c | |||
| @@ -116,16 +116,17 @@ static int bond_changelink(struct net_device *bond_dev, | |||
| 116 | if (data[IFLA_BOND_ACTIVE_SLAVE]) { | 116 | if (data[IFLA_BOND_ACTIVE_SLAVE]) { |
| 117 | int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]); | 117 | int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]); |
| 118 | struct net_device *slave_dev; | 118 | struct net_device *slave_dev; |
| 119 | char *active_slave = ""; | ||
| 119 | 120 | ||
| 120 | if (ifindex == 0) { | 121 | if (ifindex != 0) { |
| 121 | slave_dev = NULL; | ||
| 122 | } else { | ||
| 123 | slave_dev = __dev_get_by_index(dev_net(bond_dev), | 122 | slave_dev = __dev_get_by_index(dev_net(bond_dev), |
| 124 | ifindex); | 123 | ifindex); |
| 125 | if (!slave_dev) | 124 | if (!slave_dev) |
| 126 | return -ENODEV; | 125 | return -ENODEV; |
| 126 | active_slave = slave_dev->name; | ||
| 127 | } | 127 | } |
| 128 | err = bond_option_active_slave_set(bond, slave_dev); | 128 | bond_opt_initstr(&newval, active_slave); |
| 129 | err = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval); | ||
| 129 | if (err) | 130 | if (err) |
| 130 | return err; | 131 | return err; |
| 131 | } | 132 | } |
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index 18b1cc0d8b80..2315104de8c0 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
| @@ -244,6 +244,16 @@ static struct bond_option bond_opts[] = { | |||
| 244 | .values = bond_use_carrier_tbl, | 244 | .values = bond_use_carrier_tbl, |
| 245 | .set = bond_option_use_carrier_set | 245 | .set = bond_option_use_carrier_set |
| 246 | }, | 246 | }, |
| 247 | [BOND_OPT_ACTIVE_SLAVE] = { | ||
| 248 | .id = BOND_OPT_ACTIVE_SLAVE, | ||
| 249 | .name = "active_slave", | ||
| 250 | .desc = "Currently active slave", | ||
| 251 | .flags = BOND_OPTFLAG_RAWVAL, | ||
| 252 | .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP) | | ||
| 253 | BIT(BOND_MODE_TLB) | | ||
| 254 | BIT(BOND_MODE_ALB)), | ||
| 255 | .set = bond_option_active_slave_set | ||
| 256 | }, | ||
| 247 | { } | 257 | { } |
| 248 | }; | 258 | }; |
| 249 | 259 | ||
| @@ -556,10 +566,21 @@ struct net_device *bond_option_active_slave_get(struct bonding *bond) | |||
| 556 | } | 566 | } |
| 557 | 567 | ||
| 558 | int bond_option_active_slave_set(struct bonding *bond, | 568 | int bond_option_active_slave_set(struct bonding *bond, |
| 559 | struct net_device *slave_dev) | 569 | struct bond_opt_value *newval) |
| 560 | { | 570 | { |
| 571 | char ifname[IFNAMSIZ] = { 0, }; | ||
| 572 | struct net_device *slave_dev; | ||
| 561 | int ret = 0; | 573 | int ret = 0; |
| 562 | 574 | ||
| 575 | sscanf(newval->string, "%15s", ifname); /* IFNAMSIZ */ | ||
| 576 | if (!strlen(ifname) || newval->string[0] == '\n') { | ||
| 577 | slave_dev = NULL; | ||
| 578 | } else { | ||
| 579 | slave_dev = __dev_get_by_name(dev_net(bond->dev), ifname); | ||
| 580 | if (!slave_dev) | ||
| 581 | return -ENODEV; | ||
| 582 | } | ||
| 583 | |||
| 563 | if (slave_dev) { | 584 | if (slave_dev) { |
| 564 | if (!netif_is_bond_slave(slave_dev)) { | 585 | if (!netif_is_bond_slave(slave_dev)) { |
| 565 | pr_err("Device %s is not bonding slave.\n", | 586 | pr_err("Device %s is not bonding slave.\n", |
| @@ -574,12 +595,6 @@ int bond_option_active_slave_set(struct bonding *bond, | |||
| 574 | } | 595 | } |
| 575 | } | 596 | } |
| 576 | 597 | ||
| 577 | if (!USES_PRIMARY(bond->params.mode)) { | ||
| 578 | pr_err("%s: Unable to change active slave; %s is in mode %d\n", | ||
| 579 | bond->dev->name, bond->dev->name, bond->params.mode); | ||
| 580 | return -EINVAL; | ||
| 581 | } | ||
| 582 | |||
| 583 | block_netpoll_tx(); | 598 | block_netpoll_tx(); |
| 584 | write_lock_bh(&bond->curr_slave_lock); | 599 | write_lock_bh(&bond->curr_slave_lock); |
| 585 | 600 | ||
| @@ -616,6 +631,7 @@ int bond_option_active_slave_set(struct bonding *bond, | |||
| 616 | 631 | ||
| 617 | write_unlock_bh(&bond->curr_slave_lock); | 632 | write_unlock_bh(&bond->curr_slave_lock); |
| 618 | unblock_netpoll_tx(); | 633 | unblock_netpoll_tx(); |
| 634 | |||
| 619 | return ret; | 635 | return ret; |
| 620 | } | 636 | } |
| 621 | 637 | ||
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h index 229f5c15a1a4..1f486a7d1e14 100644 --- a/drivers/net/bonding/bond_options.h +++ b/drivers/net/bonding/bond_options.h | |||
| @@ -56,6 +56,7 @@ enum { | |||
| 56 | BOND_OPT_PRIMARY, | 56 | BOND_OPT_PRIMARY, |
| 57 | BOND_OPT_PRIMARY_RESELECT, | 57 | BOND_OPT_PRIMARY_RESELECT, |
| 58 | BOND_OPT_USE_CARRIER, | 58 | BOND_OPT_USE_CARRIER, |
| 59 | BOND_OPT_ACTIVE_SLAVE, | ||
| 59 | BOND_OPT_LAST | 60 | BOND_OPT_LAST |
| 60 | }; | 61 | }; |
| 61 | 62 | ||
| @@ -150,4 +151,6 @@ int bond_option_primary_reselect_set(struct bonding *bond, | |||
| 150 | struct bond_opt_value *newval); | 151 | struct bond_opt_value *newval); |
| 151 | int bond_option_use_carrier_set(struct bonding *bond, | 152 | int bond_option_use_carrier_set(struct bonding *bond, |
| 152 | struct bond_opt_value *newval); | 153 | struct bond_opt_value *newval); |
| 154 | int bond_option_active_slave_set(struct bonding *bond, | ||
| 155 | struct bond_opt_value *newval); | ||
| 153 | #endif /* _BOND_OPTIONS_H */ | 156 | #endif /* _BOND_OPTIONS_H */ |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 004048240def..181a59d7241e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -809,34 +809,14 @@ static ssize_t bonding_store_active_slave(struct device *d, | |||
| 809 | struct device_attribute *attr, | 809 | struct device_attribute *attr, |
| 810 | const char *buf, size_t count) | 810 | const char *buf, size_t count) |
| 811 | { | 811 | { |
| 812 | int ret; | ||
| 813 | struct bonding *bond = to_bond(d); | 812 | struct bonding *bond = to_bond(d); |
| 814 | char ifname[IFNAMSIZ]; | 813 | int ret; |
| 815 | struct net_device *dev; | ||
| 816 | |||
| 817 | if (!rtnl_trylock()) | ||
| 818 | return restart_syscall(); | ||
| 819 | |||
| 820 | sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ | ||
| 821 | if (!strlen(ifname) || buf[0] == '\n') { | ||
| 822 | dev = NULL; | ||
| 823 | } else { | ||
| 824 | dev = __dev_get_by_name(dev_net(bond->dev), ifname); | ||
| 825 | if (!dev) { | ||
| 826 | ret = -ENODEV; | ||
| 827 | goto out; | ||
| 828 | } | ||
| 829 | } | ||
| 830 | 814 | ||
| 831 | ret = bond_option_active_slave_set(bond, dev); | 815 | ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ACTIVE_SLAVE, (char *)buf); |
| 832 | if (!ret) | 816 | if (!ret) |
| 833 | ret = count; | 817 | ret = count; |
| 834 | 818 | ||
| 835 | out: | ||
| 836 | rtnl_unlock(); | ||
| 837 | |||
| 838 | return ret; | 819 | return ret; |
| 839 | |||
| 840 | } | 820 | } |
| 841 | static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, | 821 | static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, |
| 842 | bonding_show_active_slave, bonding_store_active_slave); | 822 | bonding_show_active_slave, bonding_store_active_slave); |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 51f3b0ad11ab..4ac79e1dd78f 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -452,7 +452,6 @@ void bond_setup(struct net_device *bond_dev); | |||
| 452 | unsigned int bond_get_num_tx_queues(void); | 452 | unsigned int bond_get_num_tx_queues(void); |
| 453 | int bond_netlink_init(void); | 453 | int bond_netlink_init(void); |
| 454 | void bond_netlink_fini(void); | 454 | void bond_netlink_fini(void); |
| 455 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); | ||
| 456 | int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); | 455 | int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); |
| 457 | int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); | 456 | int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); |
| 458 | int bond_option_resend_igmp_set(struct bonding *bond, int resend_igmp); | 457 | int bond_option_resend_igmp_set(struct bonding *bond, int resend_igmp); |
