Add IFLA_BOND_UPDELAY to allow get/set of bonding parameter updelay via netlink.
Unified · Split
| @@ -25,6 +25,7 @@ static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = { · 24 unmodified lines | |||
| 25 | [IFLA_BOND_MODE] = { .type = NLA_U8 }, | 25 | [IFLA_BOND_MODE] = { .type = NLA_U8 }, |
| 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 | }; | 29 | }; |
| 29 | 30 | ||
| 30 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) | 31 | static int bond_validate(struct nlattr *tb[], struct nlattr *data[]) |
| @@ -77,6 +78,13 @@ static int bond_changelink(struct net_device *bond_dev, · 46 unmodified lines | |||
| 77 | if (err) | 78 | if (err) |
| 78 | return err; | 79 | return err; |
| 79 | } | 80 | } |
| 81 | if (data[IFLA_BOND_UPDELAY]) { | ||
| 82 | int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]); | ||
| 83 | |||
| 84 | err = bond_option_updelay_set(bond, updelay); | ||
| 85 | if (err) | ||
| 86 | return err; | ||
| 87 | } | ||
| 80 | return 0; | 88 | return 0; |
| 81 | } | 89 | } |
| 82 | 90 | ||
| @@ -97,6 +105,7 @@ static size_t bond_get_size(const struct net_device *bond_dev) · 14 unmodified lines | |||
| 97 | return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */ | 105 | return nla_total_size(sizeof(u8)) + /* IFLA_BOND_MODE */ |
| 98 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ | 106 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_ACTIVE_SLAVE */ |
| 99 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ | 107 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_MIIMON */ |
| 108 | nla_total_size(sizeof(u32)) + /* IFLA_BOND_UPDELAY */ | ||
| 100 | 0; | 109 | 0; |
| 101 | } | 110 | } |
| 102 | 111 | ||
| @@ -116,6 +125,10 @@ static int bond_fill_info(struct sk_buff *skb, · 13 unmodified lines | |||
| 116 | if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon)) | 125 | if (nla_put_u32(skb, IFLA_BOND_MIIMON, bond->params.miimon)) |
| 117 | goto nla_put_failure; | 126 | goto nla_put_failure; |
| 118 | 127 | ||
| 128 | if (nla_put_u32(skb, IFLA_BOND_UPDELAY, | ||
| 129 | bond->params.updelay * bond->params.miimon)) | ||
| 130 | goto nla_put_failure; | ||
| 131 | |||
| 119 | return 0; | 132 | return 0; |
| 120 | 133 | ||
| 121 | nla_put_failure: | 134 | nla_put_failure: |
| @@ -187,3 +187,32 @@ int bond_option_miimon_set(struct bonding *bond, int miimon) · 186 unmodified lines | |||
| 187 | } | 187 | } |
| 188 | return 0; | 188 | return 0; |
| 189 | } | 189 | } |
| 190 | |||
| 191 | int bond_option_updelay_set(struct bonding *bond, int updelay) | ||
| 192 | { | ||
| 193 | if (!(bond->params.miimon)) { | ||
| 194 | pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", | ||
| 195 | bond->dev->name); | ||
| 196 | return -EPERM; | ||
| 197 | } | ||
| 198 | |||
| 199 | if (updelay < 0) { | ||
| 200 | pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", | ||
| 201 | bond->dev->name, updelay, 0, INT_MAX); | ||
| 202 | return -EINVAL; | ||
| 203 | } else { | ||
| 204 | if ((updelay % bond->params.miimon) != 0) { | ||
| 205 | pr_warn("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", | ||
| 206 | bond->dev->name, updelay, | ||
| 207 | bond->params.miimon, | ||
| 208 | (updelay / bond->params.miimon) * | ||
| 209 | bond->params.miimon); | ||
| 210 | } | ||
| 211 | bond->params.updelay = updelay / bond->params.miimon; | ||
| 212 | pr_info("%s: Setting up delay to %d.\n", | ||
| 213 | bond->dev->name, | ||
| 214 | bond->params.updelay * bond->params.miimon); | ||
| 215 | } | ||
| 216 | |||
| 217 | return 0; | ||
| 218 | } | ||
| @@ -747,44 +747,22 @@ static ssize_t bonding_store_updelay(struct device *d, · 746 unmodified lines | |||
| 747 | struct device_attribute *attr, | 747 | struct device_attribute *attr, |
| 748 | const char *buf, size_t count) | 748 | const char *buf, size_t count) |
| 749 | { | 749 | { |
| 750 | int new_value, ret = count; | 750 | int new_value, ret; |
| 751 | struct bonding *bond = to_bond(d); | 751 | struct bonding *bond = to_bond(d); |
| 752 | 752 | ||
| 753 | if (!rtnl_trylock()) | ||
| 754 | return restart_syscall(); | ||
| 755 | if (!(bond->params.miimon)) { | ||
| 756 | pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", | ||
| 757 | bond->dev->name); | ||
| 758 | ret = -EPERM; | ||
| 759 | goto out; | ||
| 760 | } | ||
| 761 | |||
| 762 | if (sscanf(buf, "%d", &new_value) != 1) { | 753 | if (sscanf(buf, "%d", &new_value) != 1) { |
| 763 | pr_err("%s: no up delay value specified.\n", | 754 | pr_err("%s: no up delay value specified.\n", |
| 764 | bond->dev->name); | 755 | bond->dev->name); |
| 765 | ret = -EINVAL; | 756 | return -EINVAL; |
| 766 | goto out; | ||
| 767 | } | ||
| 768 | if (new_value < 0) { | ||
| 769 | pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", | ||
| 770 | bond->dev->name, new_value, 0, INT_MAX); | ||
| 771 | ret = -EINVAL; | ||
| 772 | goto out; | ||
| 773 | } else { | ||
| 774 | if ((new_value % bond->params.miimon) != 0) { | ||
| 775 | pr_warning("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", | ||
| 776 | bond->dev->name, new_value, | ||
| 777 | bond->params.miimon, | ||
| 778 | (new_value / bond->params.miimon) * | ||
| 779 | bond->params.miimon); | ||
| 780 | } | ||
| 781 | bond->params.updelay = new_value / bond->params.miimon; | ||
| 782 | pr_info("%s: Setting up delay to %d.\n", | ||
| 783 | bond->dev->name, | ||
| 784 | bond->params.updelay * bond->params.miimon); | ||
| 785 | } | 757 | } |
| 786 | 758 | ||
| 787 | out: | 759 | if (!rtnl_trylock()) |
| 760 | return restart_syscall(); | ||
| 761 | |||
| 762 | ret = bond_option_updelay_set(bond, new_value); | ||
| 763 | if (!ret) | ||
| 764 | ret = count; | ||
| 765 | |||
| 788 | rtnl_unlock(); | 766 | rtnl_unlock(); |
| 789 | return ret; | 767 | return ret; |
| 790 | } | 768 | } |
| @@ -440,6 +440,7 @@ void bond_netlink_fini(void); · 439 unmodified lines | |||
| 440 | int bond_option_mode_set(struct bonding *bond, int mode); | 440 | 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 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); | 444 | struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); |
| 444 | struct net_device *bond_option_active_slave_get(struct bonding *bond); | 445 | struct net_device *bond_option_active_slave_get(struct bonding *bond); |
| 445 | 446 | ||
| @@ -332,6 +332,7 @@ enum { · 331 unmodified lines | |||
| 332 | IFLA_BOND_MODE, | 332 | IFLA_BOND_MODE, |
| 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_MAX, | 336 | __IFLA_BOND_MAX, |
| 336 | }; | 337 | }; |
| 337 | 338 | ||