diff options
| author | sfeldma@cumulusnetworks.com <sfeldma@cumulusnetworks.com> | 2013-12-12 17:10:09 -0500 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-12-14 01:07:31 -0500 | 
| commit | c7461f9bf5a11bf88fdbd05b26c6d55b77dcd46d (patch) | |
| tree | 2c80c47d2ef00b0c4cdf64835865612c73682cfb | |
| parent | 25852e29dfc58d249ad0db235996b36c33db6d61 (diff) | |
bonding: add downdelay netlink support
Add IFLA_BOND_DOWNDELAY to allow get/set of bonding parameter
downdelay via netlink.
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/bonding/bond_netlink.c | 13 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_options.c | 29 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 39 | ||||
| -rw-r--r-- | drivers/net/bonding/bonding.h | 1 | ||||
| -rw-r--r-- | include/uapi/linux/if_link.h | 1 | 
5 files changed, 52 insertions, 31 deletions
| diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index 086cf4f5f0a6..a0a2e8c32fe5 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c | |||
| @@ -26,6 +26,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { | |||
| 26 | [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, | 26 | [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, | 
| 27 | [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, | 27 | [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, | 
| 28 | [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, | 28 | [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, | 
| 29 | [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 }, | ||
| 29 | }; | 30 | }; | 
| 30 | 31 | ||
| 31 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | 32 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | 
| @@ -85,6 +86,13 @@ static int bond_changelink(struct net_device *bond_dev, | |||
| 85 | if (err) | 86 | if (err) | 
| 86 | return err; | 87 | return err; | 
| 87 | } | 88 | } | 
| 89 | if (data[IFLA_BOND_DOWNDELAY]) { | ||
| 90 | int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]); | ||
| 91 | |||
| 92 | err = bond_option_downdelay_set(bond, downdelay); | ||
| 93 | if (err) | ||
| 94 | return err; | ||
| 95 | } | ||
| 88 | return 0; | 96 | return 0; | 
| 89 | } | 97 | } | 
| 90 | 98 | ||
| @@ -106,6 +114,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) | |||
| 106 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ | 114 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ | 
| 107 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ | 115 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ | 
| 108 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ | 116 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ | 
| 117 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_DOWNDELAY */ | ||
| 109 | 0; | 118 | 0; | 
| 110 | } | 119 | } | 
| 111 | 120 | ||
| @@ -129,6 +138,10 @@ static int bond_fill_info(struct sk_buff *skb, | |||
| 129 | bond->params.updelay * bond->params.miimon)) | 138 | bond->params.updelay * bond->params.miimon)) | 
| 130 | goto nla_put_failure; | 139 | goto nla_put_failure; | 
| 131 | 140 | ||
| 141 | if (nla_put_u32(skb, IFLA_BOND_DOWNDELAY, | ||
| 142 | bond->params.downdelay * bond->params.miimon)) | ||
| 143 | goto nla_put_failure; | ||
| 144 | |||
| 132 | return 0; | 145 | return 0; | 
| 133 | 146 | ||
| 134 | nla_put_failure: | 147 | nla_put_failure: | 
| diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index ae94b847ffcc..2914d649ee34 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c | |||
| @@ -216,3 +216,32 @@ int bond_option_updelay_set(struct bonding *bond, int updelay) | |||
| 216 | 216 | ||
| 217 | return 0; | 217 | return 0; | 
| 218 | } | 218 | } | 
| 219 | |||
| 220 | int bond_option_downdelay_set(struct bonding *bond, int downdelay) | ||
| 221 | { | ||
| 222 | if (!(bond->params.miimon)) { | ||
| 223 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", | ||
| 224 | bond->dev->name); | ||
| 225 | return -EPERM; | ||
| 226 | } | ||
| 227 | |||
| 228 | if (downdelay < 0) { | ||
| 229 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", | ||
| 230 | bond->dev->name, downdelay, 0, INT_MAX); | ||
| 231 | return -EINVAL; | ||
| 232 | } else { | ||
| 233 | if ((downdelay % bond->params.miimon) != 0) { | ||
| 234 | pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", | ||
| 235 | bond->dev->name, downdelay, | ||
| 236 | bond->params.miimon, | ||
| 237 | (downdelay / bond->params.miimon) * | ||
| 238 | bond->params.miimon); | ||
| 239 | } | ||
| 240 | bond->params.downdelay = downdelay / bond->params.miimon; | ||
| 241 | pr_info("%s: Setting down delay to %d.\n", | ||
| 242 | bond->dev->name, | ||
| 243 | bond->params.downdelay * bond->params.miimon); | ||
| 244 | } | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 4dcbec4e07c0..bec20bc08d31 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -689,44 +689,21 @@ static ssize_t bonding_store_downdelay(struct device *d, | |||
| 689 | struct device_attribute *attr, | 689 | struct device_attribute *attr, | 
| 690 | const char *buf, size_t count) | 690 | const char *buf, size_t count) | 
| 691 | { | 691 | { | 
| 692 | int new_value, ret = count; | 692 | int new_value, ret; | 
| 693 | struct bonding *bond = to_bond(d); | 693 | struct bonding *bond = to_bond(d); | 
| 694 | 694 | ||
| 695 | if (!rtnl_trylock()) | ||
| 696 | return restart_syscall(); | ||
| 697 | if (!(bond->params.miimon)) { | ||
| 698 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", | ||
| 699 | bond->dev->name); | ||
| 700 | ret = -EPERM; | ||
| 701 | goto out; | ||
| 702 | } | ||
| 703 | |||
| 704 | if (sscanf(buf, "%d", &new_value) != 1) { | 695 | if (sscanf(buf, "%d", &new_value) != 1) { | 
| 705 | pr_err("%s: no down delay value specified.\n", bond->dev->name); | 696 | pr_err("%s: no down delay value specified.\n", bond->dev->name); | 
| 706 | ret = -EINVAL; | 697 | return -EINVAL; | 
| 707 | goto out; | ||
| 708 | } | 698 | } | 
| 709 | if (new_value < 0) { | ||
| 710 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", | ||
| 711 | bond->dev->name, new_value, 0, INT_MAX); | ||
| 712 | ret = -EINVAL; | ||
| 713 | goto out; | ||
| 714 | } else { | ||
| 715 | if ((new_value % bond->params.miimon) != 0) { | ||
| 716 | pr_warning("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", | ||
| 717 | bond->dev->name, new_value, | ||
| 718 | bond->params.miimon, | ||
| 719 | (new_value / bond->params.miimon) * | ||
| 720 | bond->params.miimon); | ||
| 721 | } | ||
| 722 | bond->params.downdelay = new_value / bond->params.miimon; | ||
| 723 | pr_info("%s: Setting down delay to %d.\n", | ||
| 724 | bond->dev->name, | ||
| 725 | bond->params.downdelay * bond->params.miimon); | ||
| 726 | 699 | ||
| 727 | } | 700 | if (!rtnl_trylock()) | 
| 701 | return restart_syscall(); | ||
| 702 | |||
| 703 | ret = bond_option_downdelay_set(bond, new_value); | ||
| 704 | if (!ret) | ||
| 705 | ret = count; | ||
| 728 | 706 | ||
| 729 | out: | ||
| 730 | rtnl_unlock(); | 707 | rtnl_unlock(); | 
| 731 | return ret; | 708 | return ret; | 
| 732 | } | 709 | } | 
| diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 8a91f7187e51..f5749b18d168 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -441,6 +441,7 @@ int bond_option_mode_set(struct bonding *bond, int mode); | |||
| 441 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); | 441 | int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); | 
| 442 | int bond_option_miimon_set(struct bonding *bond, int miimon); | 442 | int bond_option_miimon_set(struct bonding *bond, int miimon); | 
| 443 | int bond_option_updelay_set(struct bonding *bond, int updelay); | 443 | int bond_option_updelay_set(struct bonding *bond, int updelay); | 
| 444 | int bond_option_downdelay_set(struct bonding *bond, int downdelay); | ||
| 444 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); | 445 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); | 
| 445 | struct net_device *bond_option_active_slave_get(struct bonding *bond); | 446 | struct net_device *bond_option_active_slave_get(struct bonding *bond); | 
| 446 | 447 | ||
| diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index 7588c8120e7f..f95506777710 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h | |||
| @@ -333,6 +333,7 @@ enum { | |||
| 333 | IFLA_BOND_ACTIVE_SLAVE, | 333 | IFLA_BOND_ACTIVE_SLAVE, | 
| 334 | IFLA_BOND_MIIMON, | 334 | IFLA_BOND_MIIMON, | 
| 335 | IFLA_BOND_UPDELAY, | 335 | IFLA_BOND_UPDELAY, | 
| 336 | IFLA_BOND_DOWNDELAY, | ||
| 336 | __IFLA_BOND_MAX, | 337 | __IFLA_BOND_MAX, | 
| 337 | }; | 338 | }; | 
| 338 | 339 | ||
