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); |