Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'bonding_option_api'

Nikolay Aleksandrov says:

====================
bonding: introduce new option API

This patchset's goal is to introduce a new option API which should be used
to properly describe the bonding options with their mode dependcies and
requirements. With this patchset applied we get centralized option
manipulation, automatic RTNL acquire per option setting, automatic option
range checking, mode dependcy checking and other various flags which are
described in detail in patch 01's commit message and comments.
Also the parameter passing is changed to use a specialized structure which
is initialized to a value depending on the needs.
The main exported functions are:
__bond_opt_set() - set an option (RTNL should be acquired prior)
bond_opt_init(val|str) - init a bond_opt_value struct for value or string
parameter passing
bond_opt_tryset_rtnl() - function which tries to acquire rtnl, mainly used
for sysfs
bond_opt_parse - used to parse or check for valid values
bond_opt_get - retrieve a pointer to bond_option struct for some option
bond_opt_get_val - retrieve a pointer to a bond_opt_value struct for
some value

The same functions are used to set an option via sysfs and netlink, just
the parameter that's passed is usually initialized in a different way.
The converted options have multiple style fixes, there're some longer
lines but they looked either ugly or were strings/pr_warnings, if you
think some line would be better broken just let me know :-) there're
also a few sscanf false-positive warnings.
I decided to keep the "unsuppmodes" way of mode dep checking since it's
straight forward, if we make a more general way for checking dependencies
it'll be easy to change it.

Future plans for this work include:
- Automatic sysfs generation from the bond_opts[].
- Use of the API in bond_check_params() and thus cleaning it up (this has
actually started, I'll take care of the rest in a separate patch)
- Clean up all option-unrelated files of option definitions and functions

I've tried to leave as much documentation as possible, if there's anything
unclear please let me know. One more thing, I haven't moved all
option-related functions from bonding.h to the new bond_options.h, this
will be done in a separate patch, it's in my todo list.

This patchset has been tested by setting each converted option via sysfs
and netlink to a couple of wrong values, a couple of correct values and
some random values, also for the opts that have flags they have been
tested as well.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+1222 -888
+66 -113
drivers/net/bonding/bond_main.c
··· 86 86 /*---------------------------- Module parameters ----------------------------*/ 87 87 88 88 /* monitor all links that often (in milliseconds). <=0 disables monitoring */ 89 - #define BOND_LINK_MON_INTERV 0 90 - #define BOND_LINK_ARP_INTERV 0 91 89 92 90 static int max_bonds = BOND_DEFAULT_MAX_BONDS; 93 91 static int tx_queues = BOND_DEFAULT_TX_QUEUES; 94 92 static int num_peer_notif = 1; 95 - static int miimon = BOND_LINK_MON_INTERV; 93 + static int miimon; 96 94 static int updelay; 97 95 static int downdelay; 98 96 static int use_carrier = 1; ··· 101 103 static int min_links; 102 104 static char *ad_select; 103 105 static char *xmit_hash_policy; 104 - static int arp_interval = BOND_LINK_ARP_INTERV; 106 + static int arp_interval; 105 107 static char *arp_ip_target[BOND_MAX_ARP_TARGETS]; 106 108 static char *arp_validate; 107 109 static char *arp_all_targets; ··· 205 207 static int bond_mode = BOND_MODE_ROUNDROBIN; 206 208 static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2; 207 209 static int lacp_fast; 208 - 209 - const struct bond_parm_tbl bond_lacp_tbl[] = { 210 - { "slow", AD_LACP_SLOW}, 211 - { "fast", AD_LACP_FAST}, 212 - { NULL, -1}, 213 - }; 214 - 215 - const struct bond_parm_tbl bond_mode_tbl[] = { 216 - { "balance-rr", BOND_MODE_ROUNDROBIN}, 217 - { "active-backup", BOND_MODE_ACTIVEBACKUP}, 218 - { "balance-xor", BOND_MODE_XOR}, 219 - { "broadcast", BOND_MODE_BROADCAST}, 220 - { "802.3ad", BOND_MODE_8023AD}, 221 - { "balance-tlb", BOND_MODE_TLB}, 222 - { "balance-alb", BOND_MODE_ALB}, 223 - { NULL, -1}, 224 - }; 225 - 226 - const struct bond_parm_tbl xmit_hashtype_tbl[] = { 227 - { "layer2", BOND_XMIT_POLICY_LAYER2}, 228 - { "layer3+4", BOND_XMIT_POLICY_LAYER34}, 229 - { "layer2+3", BOND_XMIT_POLICY_LAYER23}, 230 - { "encap2+3", BOND_XMIT_POLICY_ENCAP23}, 231 - { "encap3+4", BOND_XMIT_POLICY_ENCAP34}, 232 - { NULL, -1}, 233 - }; 234 - 235 - const struct bond_parm_tbl arp_all_targets_tbl[] = { 236 - { "any", BOND_ARP_TARGETS_ANY}, 237 - { "all", BOND_ARP_TARGETS_ALL}, 238 - { NULL, -1}, 239 - }; 240 - 241 - const struct bond_parm_tbl arp_validate_tbl[] = { 242 - { "none", BOND_ARP_VALIDATE_NONE}, 243 - { "active", BOND_ARP_VALIDATE_ACTIVE}, 244 - { "backup", BOND_ARP_VALIDATE_BACKUP}, 245 - { "all", BOND_ARP_VALIDATE_ALL}, 246 - { NULL, -1}, 247 - }; 248 - 249 - const struct bond_parm_tbl fail_over_mac_tbl[] = { 250 - { "none", BOND_FOM_NONE}, 251 - { "active", BOND_FOM_ACTIVE}, 252 - { "follow", BOND_FOM_FOLLOW}, 253 - { NULL, -1}, 254 - }; 255 - 256 - const struct bond_parm_tbl pri_reselect_tbl[] = { 257 - { "always", BOND_PRI_RESELECT_ALWAYS}, 258 - { "better", BOND_PRI_RESELECT_BETTER}, 259 - { "failure", BOND_PRI_RESELECT_FAILURE}, 260 - { NULL, -1}, 261 - }; 262 - 263 - struct bond_parm_tbl ad_select_tbl[] = { 264 - { "stable", BOND_AD_STABLE}, 265 - { "bandwidth", BOND_AD_BANDWIDTH}, 266 - { "count", BOND_AD_COUNT}, 267 - { NULL, -1}, 268 - }; 269 210 270 211 /*-------------------------- Forward declarations ---------------------------*/ 271 212 ··· 3123 3186 struct ifslave k_sinfo; 3124 3187 struct ifslave __user *u_sinfo = NULL; 3125 3188 struct mii_ioctl_data *mii = NULL; 3189 + struct bond_opt_value newval; 3126 3190 struct net *net; 3127 3191 int res = 0; 3128 3192 ··· 3219 3281 break; 3220 3282 case BOND_CHANGE_ACTIVE_OLD: 3221 3283 case SIOCBONDCHANGEACTIVE: 3222 - res = bond_option_active_slave_set(bond, slave_dev); 3284 + bond_opt_initstr(&newval, slave_dev->name); 3285 + res = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval); 3223 3286 break; 3224 3287 default: 3225 3288 res = -EOPNOTSUPP; ··· 3967 4028 static int bond_check_params(struct bond_params *params) 3968 4029 { 3969 4030 int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; 4031 + struct bond_opt_value newval, *valptr; 3970 4032 int arp_all_targets_value; 3971 4033 3972 4034 /* 3973 4035 * Convert string parameters. 3974 4036 */ 3975 4037 if (mode) { 3976 - bond_mode = bond_parse_parm(mode, bond_mode_tbl); 3977 - if (bond_mode == -1) { 3978 - pr_err("Error: Invalid bonding mode \"%s\"\n", 3979 - mode == NULL ? "NULL" : mode); 4038 + bond_opt_initstr(&newval, mode); 4039 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_MODE), &newval); 4040 + if (!valptr) { 4041 + pr_err("Error: Invalid bonding mode \"%s\"\n", mode); 3980 4042 return -EINVAL; 3981 4043 } 4044 + bond_mode = valptr->value; 3982 4045 } 3983 4046 3984 4047 if (xmit_hash_policy) { ··· 3989 4048 pr_info("xmit_hash_policy param is irrelevant in mode %s\n", 3990 4049 bond_mode_name(bond_mode)); 3991 4050 } else { 3992 - xmit_hashtype = bond_parse_parm(xmit_hash_policy, 3993 - xmit_hashtype_tbl); 3994 - if (xmit_hashtype == -1) { 4051 + bond_opt_initstr(&newval, xmit_hash_policy); 4052 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_XMIT_HASH), 4053 + &newval); 4054 + if (!valptr) { 3995 4055 pr_err("Error: Invalid xmit_hash_policy \"%s\"\n", 3996 - xmit_hash_policy == NULL ? "NULL" : 3997 4056 xmit_hash_policy); 3998 4057 return -EINVAL; 3999 4058 } 4059 + xmit_hashtype = valptr->value; 4000 4060 } 4001 4061 } 4002 4062 ··· 4006 4064 pr_info("lacp_rate param is irrelevant in mode %s\n", 4007 4065 bond_mode_name(bond_mode)); 4008 4066 } else { 4009 - lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl); 4010 - if (lacp_fast == -1) { 4067 + bond_opt_initstr(&newval, lacp_rate); 4068 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_LACP_RATE), 4069 + &newval); 4070 + if (!valptr) { 4011 4071 pr_err("Error: Invalid lacp rate \"%s\"\n", 4012 - lacp_rate == NULL ? "NULL" : lacp_rate); 4072 + lacp_rate); 4013 4073 return -EINVAL; 4014 4074 } 4075 + lacp_fast = valptr->value; 4015 4076 } 4016 4077 } 4017 4078 4018 4079 if (ad_select) { 4019 - params->ad_select = bond_parse_parm(ad_select, ad_select_tbl); 4020 - if (params->ad_select == -1) { 4021 - pr_err("Error: Invalid ad_select \"%s\"\n", 4022 - ad_select == NULL ? "NULL" : ad_select); 4080 + bond_opt_initstr(&newval, lacp_rate); 4081 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_AD_SELECT), 4082 + &newval); 4083 + if (!valptr) { 4084 + pr_err("Error: Invalid ad_select \"%s\"\n", ad_select); 4023 4085 return -EINVAL; 4024 4086 } 4025 - 4026 - if (bond_mode != BOND_MODE_8023AD) { 4087 + params->ad_select = valptr->value; 4088 + if (bond_mode != BOND_MODE_8023AD) 4027 4089 pr_warning("ad_select param only affects 802.3ad mode\n"); 4028 - } 4029 4090 } else { 4030 4091 params->ad_select = BOND_AD_STABLE; 4031 4092 } ··· 4040 4095 } 4041 4096 4042 4097 if (miimon < 0) { 4043 - pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to %d\n", 4044 - miimon, INT_MAX, BOND_LINK_MON_INTERV); 4045 - miimon = BOND_LINK_MON_INTERV; 4098 + pr_warning("Warning: miimon module parameter (%d), not in range 0-%d, so it was reset to 0\n", 4099 + miimon, INT_MAX); 4100 + miimon = 0; 4046 4101 } 4047 4102 4048 4103 if (updelay < 0) { ··· 4099 4154 resend_igmp = BOND_DEFAULT_RESEND_IGMP; 4100 4155 } 4101 4156 4102 - if (packets_per_slave < 0 || packets_per_slave > USHRT_MAX) { 4157 + bond_opt_initval(&newval, packets_per_slave); 4158 + if (!bond_opt_parse(bond_opt_get(BOND_OPT_PACKETS_PER_SLAVE), &newval)) { 4103 4159 pr_warn("Warning: packets_per_slave (%d) should be between 0 and %u resetting to 1\n", 4104 4160 packets_per_slave, USHRT_MAX); 4105 4161 packets_per_slave = 1; ··· 4145 4199 } 4146 4200 4147 4201 if (arp_interval < 0) { 4148 - pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to %d\n", 4149 - arp_interval, INT_MAX, BOND_LINK_ARP_INTERV); 4150 - arp_interval = BOND_LINK_ARP_INTERV; 4202 + pr_warning("Warning: arp_interval module parameter (%d) , not in range 0-%d, so it was reset to 0\n", 4203 + arp_interval, INT_MAX); 4204 + arp_interval = 0; 4151 4205 } 4152 4206 4153 4207 for (arp_ip_count = 0, i = 0; ··· 4186 4240 return -EINVAL; 4187 4241 } 4188 4242 4189 - arp_validate_value = bond_parse_parm(arp_validate, 4190 - arp_validate_tbl); 4191 - if (arp_validate_value == -1) { 4243 + bond_opt_initstr(&newval, arp_validate); 4244 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_VALIDATE), 4245 + &newval); 4246 + if (!valptr) { 4192 4247 pr_err("Error: invalid arp_validate \"%s\"\n", 4193 - arp_validate == NULL ? "NULL" : arp_validate); 4248 + arp_validate); 4194 4249 return -EINVAL; 4195 4250 } 4196 - } else 4251 + arp_validate_value = valptr->value; 4252 + } else { 4197 4253 arp_validate_value = 0; 4254 + } 4198 4255 4199 4256 arp_all_targets_value = 0; 4200 4257 if (arp_all_targets) { 4201 - arp_all_targets_value = bond_parse_parm(arp_all_targets, 4202 - arp_all_targets_tbl); 4203 - 4204 - if (arp_all_targets_value == -1) { 4258 + bond_opt_initstr(&newval, arp_all_targets); 4259 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_ARP_ALL_TARGETS), 4260 + &newval); 4261 + if (!valptr) { 4205 4262 pr_err("Error: invalid arp_all_targets_value \"%s\"\n", 4206 4263 arp_all_targets); 4207 4264 arp_all_targets_value = 0; 4265 + } else { 4266 + arp_all_targets_value = valptr->value; 4208 4267 } 4209 4268 } 4210 4269 4211 4270 if (miimon) { 4212 4271 pr_info("MII link monitoring set to %d ms\n", miimon); 4213 4272 } else if (arp_interval) { 4273 + valptr = bond_opt_get_val(BOND_OPT_ARP_VALIDATE, 4274 + arp_validate_value); 4214 4275 pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", 4215 - arp_interval, 4216 - arp_validate_tbl[arp_validate_value].modename, 4217 - arp_ip_count); 4276 + arp_interval, valptr->string, arp_ip_count); 4218 4277 4219 4278 for (i = 0; i < arp_ip_count; i++) 4220 4279 pr_info(" %s", arp_ip_target[i]); ··· 4243 4292 } 4244 4293 4245 4294 if (primary && primary_reselect) { 4246 - primary_reselect_value = bond_parse_parm(primary_reselect, 4247 - pri_reselect_tbl); 4248 - if (primary_reselect_value == -1) { 4295 + bond_opt_initstr(&newval, primary_reselect); 4296 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_PRIMARY_RESELECT), 4297 + &newval); 4298 + if (!valptr) { 4249 4299 pr_err("Error: Invalid primary_reselect \"%s\"\n", 4250 - primary_reselect == 4251 - NULL ? "NULL" : primary_reselect); 4300 + primary_reselect); 4252 4301 return -EINVAL; 4253 4302 } 4303 + primary_reselect_value = valptr->value; 4254 4304 } else { 4255 4305 primary_reselect_value = BOND_PRI_RESELECT_ALWAYS; 4256 4306 } 4257 4307 4258 4308 if (fail_over_mac) { 4259 - fail_over_mac_value = bond_parse_parm(fail_over_mac, 4260 - fail_over_mac_tbl); 4261 - if (fail_over_mac_value == -1) { 4309 + bond_opt_initstr(&newval, fail_over_mac); 4310 + valptr = bond_opt_parse(bond_opt_get(BOND_OPT_FAIL_OVER_MAC), 4311 + &newval); 4312 + if (!valptr) { 4262 4313 pr_err("Error: invalid fail_over_mac \"%s\"\n", 4263 - arp_validate == NULL ? "NULL" : arp_validate); 4314 + fail_over_mac); 4264 4315 return -EINVAL; 4265 4316 } 4266 - 4317 + fail_over_mac_value = valptr->value; 4267 4318 if (bond_mode != BOND_MODE_ACTIVEBACKUP) 4268 4319 pr_warning("Warning: fail_over_mac only affects active-backup mode.\n"); 4269 4320 } else {
+57 -30
drivers/net/bonding/bond_netlink.c
··· 98 98 struct nlattr *tb[], struct nlattr *data[]) 99 99 { 100 100 struct bonding *bond = netdev_priv(bond_dev); 101 + struct bond_opt_value newval; 101 102 int miimon = 0; 102 103 int err; 103 104 ··· 108 107 if (data[IFLA_BOND_MODE]) { 109 108 int mode = nla_get_u8(data[IFLA_BOND_MODE]); 110 109 111 - err = bond_option_mode_set(bond, mode); 110 + bond_opt_initval(&newval, mode); 111 + err = __bond_opt_set(bond, BOND_OPT_MODE, &newval); 112 112 if (err) 113 113 return err; 114 114 } 115 115 if (data[IFLA_BOND_ACTIVE_SLAVE]) { 116 116 int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]); 117 117 struct net_device *slave_dev; 118 + char *active_slave = ""; 118 119 119 - if (ifindex == 0) { 120 - slave_dev = NULL; 121 - } else { 120 + if (ifindex != 0) { 122 121 slave_dev = __dev_get_by_index(dev_net(bond_dev), 123 122 ifindex); 124 123 if (!slave_dev) 125 124 return -ENODEV; 125 + active_slave = slave_dev->name; 126 126 } 127 - err = bond_option_active_slave_set(bond, slave_dev); 127 + bond_opt_initstr(&newval, active_slave); 128 + err = __bond_opt_set(bond, BOND_OPT_ACTIVE_SLAVE, &newval); 128 129 if (err) 129 130 return err; 130 131 } 131 132 if (data[IFLA_BOND_MIIMON]) { 132 133 miimon = nla_get_u32(data[IFLA_BOND_MIIMON]); 133 134 134 - err = bond_option_miimon_set(bond, miimon); 135 + bond_opt_initval(&newval, miimon); 136 + err = __bond_opt_set(bond, BOND_OPT_MIIMON, &newval); 135 137 if (err) 136 138 return err; 137 139 } 138 140 if (data[IFLA_BOND_UPDELAY]) { 139 141 int updelay = nla_get_u32(data[IFLA_BOND_UPDELAY]); 140 142 141 - err = bond_option_updelay_set(bond, updelay); 143 + bond_opt_initval(&newval, updelay); 144 + err = __bond_opt_set(bond, BOND_OPT_UPDELAY, &newval); 142 145 if (err) 143 146 return err; 144 147 } 145 148 if (data[IFLA_BOND_DOWNDELAY]) { 146 149 int downdelay = nla_get_u32(data[IFLA_BOND_DOWNDELAY]); 147 150 148 - err = bond_option_downdelay_set(bond, downdelay); 151 + bond_opt_initval(&newval, downdelay); 152 + err = __bond_opt_set(bond, BOND_OPT_DOWNDELAY, &newval); 149 153 if (err) 150 154 return err; 151 155 } 152 156 if (data[IFLA_BOND_USE_CARRIER]) { 153 157 int use_carrier = nla_get_u8(data[IFLA_BOND_USE_CARRIER]); 154 158 155 - err = bond_option_use_carrier_set(bond, use_carrier); 159 + bond_opt_initval(&newval, use_carrier); 160 + err = __bond_opt_set(bond, BOND_OPT_USE_CARRIER, &newval); 156 161 if (err) 157 162 return err; 158 163 } ··· 171 164 return -EINVAL; 172 165 } 173 166 174 - err = bond_option_arp_interval_set(bond, arp_interval); 167 + bond_opt_initval(&newval, arp_interval); 168 + err = __bond_opt_set(bond, BOND_OPT_ARP_INTERVAL, &newval); 175 169 if (err) 176 170 return err; 177 171 } 178 172 if (data[IFLA_BOND_ARP_IP_TARGET]) { 179 - __be32 targets[BOND_MAX_ARP_TARGETS] = { 0, }; 180 173 struct nlattr *attr; 181 174 int i = 0, rem; 182 175 176 + bond_option_arp_ip_targets_clear(bond); 183 177 nla_for_each_nested(attr, data[IFLA_BOND_ARP_IP_TARGET], rem) { 184 178 __be32 target = nla_get_be32(attr); 185 - targets[i++] = target; 186 - } 187 179 188 - err = bond_option_arp_ip_targets_set(bond, targets, i); 180 + bond_opt_initval(&newval, target); 181 + err = __bond_opt_set(bond, BOND_OPT_ARP_TARGETS, 182 + &newval); 183 + if (err) 184 + break; 185 + i++; 186 + } 187 + if (i == 0 && bond->params.arp_interval) 188 + pr_warn("%s: removing last arp target with arp_interval on\n", 189 + bond->dev->name); 189 190 if (err) 190 191 return err; 191 192 } ··· 206 191 return -EINVAL; 207 192 } 208 193 209 - err = bond_option_arp_validate_set(bond, arp_validate); 194 + bond_opt_initval(&newval, arp_validate); 195 + err = __bond_opt_set(bond, BOND_OPT_ARP_VALIDATE, &newval); 210 196 if (err) 211 197 return err; 212 198 } ··· 215 199 int arp_all_targets = 216 200 nla_get_u32(data[IFLA_BOND_ARP_ALL_TARGETS]); 217 201 218 - err = bond_option_arp_all_targets_set(bond, arp_all_targets); 202 + bond_opt_initval(&newval, arp_all_targets); 203 + err = __bond_opt_set(bond, BOND_OPT_ARP_ALL_TARGETS, &newval); 219 204 if (err) 220 205 return err; 221 206 } ··· 229 212 if (dev) 230 213 primary = dev->name; 231 214 232 - err = bond_option_primary_set(bond, primary); 215 + bond_opt_initstr(&newval, primary); 216 + err = __bond_opt_set(bond, BOND_OPT_PRIMARY, &newval); 233 217 if (err) 234 218 return err; 235 219 } ··· 238 220 int primary_reselect = 239 221 nla_get_u8(data[IFLA_BOND_PRIMARY_RESELECT]); 240 222 241 - err = bond_option_primary_reselect_set(bond, primary_reselect); 223 + bond_opt_initval(&newval, primary_reselect); 224 + err = __bond_opt_set(bond, BOND_OPT_PRIMARY_RESELECT, &newval); 242 225 if (err) 243 226 return err; 244 227 } ··· 247 228 int fail_over_mac = 248 229 nla_get_u8(data[IFLA_BOND_FAIL_OVER_MAC]); 249 230 250 - err = bond_option_fail_over_mac_set(bond, fail_over_mac); 231 + bond_opt_initval(&newval, fail_over_mac); 232 + err = __bond_opt_set(bond, BOND_OPT_FAIL_OVER_MAC, &newval); 251 233 if (err) 252 234 return err; 253 235 } ··· 256 236 int xmit_hash_policy = 257 237 nla_get_u8(data[IFLA_BOND_XMIT_HASH_POLICY]); 258 238 259 - err = bond_option_xmit_hash_policy_set(bond, xmit_hash_policy); 239 + bond_opt_initval(&newval, xmit_hash_policy); 240 + err = __bond_opt_set(bond, BOND_OPT_XMIT_HASH, &newval); 260 241 if (err) 261 242 return err; 262 243 } ··· 265 244 int resend_igmp = 266 245 nla_get_u32(data[IFLA_BOND_RESEND_IGMP]); 267 246 268 - err = bond_option_resend_igmp_set(bond, resend_igmp); 247 + bond_opt_initval(&newval, resend_igmp); 248 + err = __bond_opt_set(bond, BOND_OPT_RESEND_IGMP, &newval); 269 249 if (err) 270 250 return err; 271 251 } ··· 274 252 int num_peer_notif = 275 253 nla_get_u8(data[IFLA_BOND_NUM_PEER_NOTIF]); 276 254 277 - err = bond_option_num_peer_notif_set(bond, num_peer_notif); 255 + bond_opt_initval(&newval, num_peer_notif); 256 + err = __bond_opt_set(bond, BOND_OPT_NUM_PEER_NOTIF, &newval); 278 257 if (err) 279 258 return err; 280 259 } ··· 283 260 int all_slaves_active = 284 261 nla_get_u8(data[IFLA_BOND_ALL_SLAVES_ACTIVE]); 285 262 286 - err = bond_option_all_slaves_active_set(bond, 287 - all_slaves_active); 263 + bond_opt_initval(&newval, all_slaves_active); 264 + err = __bond_opt_set(bond, BOND_OPT_ALL_SLAVES_ACTIVE, &newval); 288 265 if (err) 289 266 return err; 290 267 } ··· 292 269 int min_links = 293 270 nla_get_u32(data[IFLA_BOND_MIN_LINKS]); 294 271 295 - err = bond_option_min_links_set(bond, min_links); 272 + bond_opt_initval(&newval, min_links); 273 + err = __bond_opt_set(bond, BOND_OPT_MINLINKS, &newval); 296 274 if (err) 297 275 return err; 298 276 } ··· 301 277 int lp_interval = 302 278 nla_get_u32(data[IFLA_BOND_LP_INTERVAL]); 303 279 304 - err = bond_option_lp_interval_set(bond, lp_interval); 280 + bond_opt_initval(&newval, lp_interval); 281 + err = __bond_opt_set(bond, BOND_OPT_LP_INTERVAL, &newval); 305 282 if (err) 306 283 return err; 307 284 } ··· 310 285 int packets_per_slave = 311 286 nla_get_u32(data[IFLA_BOND_PACKETS_PER_SLAVE]); 312 287 313 - err = bond_option_packets_per_slave_set(bond, 314 - packets_per_slave); 288 + bond_opt_initval(&newval, packets_per_slave); 289 + err = __bond_opt_set(bond, BOND_OPT_PACKETS_PER_SLAVE, &newval); 315 290 if (err) 316 291 return err; 317 292 } ··· 319 294 int lacp_rate = 320 295 nla_get_u8(data[IFLA_BOND_AD_LACP_RATE]); 321 296 322 - err = bond_option_lacp_rate_set(bond, lacp_rate); 297 + bond_opt_initval(&newval, lacp_rate); 298 + err = __bond_opt_set(bond, BOND_OPT_LACP_RATE, &newval); 323 299 if (err) 324 300 return err; 325 301 } ··· 328 302 int ad_select = 329 303 nla_get_u8(data[IFLA_BOND_AD_SELECT]); 330 304 331 - err = bond_option_ad_select_set(bond, ad_select); 305 + bond_opt_initval(&newval, ad_select); 306 + err = __bond_opt_set(bond, BOND_OPT_AD_SELECT, &newval); 332 307 if (err) 333 308 return err; 334 309 }
+820 -281
drivers/net/bonding/bond_options.c
··· 16 16 #include <linux/netdevice.h> 17 17 #include <linux/rwlock.h> 18 18 #include <linux/rcupdate.h> 19 + #include <linux/ctype.h> 20 + #include <linux/inet.h> 19 21 #include "bonding.h" 20 22 21 - int bond_option_mode_set(struct bonding *bond, int mode) 23 + static struct bond_opt_value bond_mode_tbl[] = { 24 + { "balance-rr", BOND_MODE_ROUNDROBIN, BOND_VALFLAG_DEFAULT}, 25 + { "active-backup", BOND_MODE_ACTIVEBACKUP, 0}, 26 + { "balance-xor", BOND_MODE_XOR, 0}, 27 + { "broadcast", BOND_MODE_BROADCAST, 0}, 28 + { "802.3ad", BOND_MODE_8023AD, 0}, 29 + { "balance-tlb", BOND_MODE_TLB, 0}, 30 + { "balance-alb", BOND_MODE_ALB, 0}, 31 + { NULL, -1, 0}, 32 + }; 33 + 34 + static struct bond_opt_value bond_pps_tbl[] = { 35 + { "default", 1, BOND_VALFLAG_DEFAULT}, 36 + { "maxval", USHRT_MAX, BOND_VALFLAG_MAX}, 37 + { NULL, -1, 0}, 38 + }; 39 + 40 + static struct bond_opt_value bond_xmit_hashtype_tbl[] = { 41 + { "layer2", BOND_XMIT_POLICY_LAYER2, BOND_VALFLAG_DEFAULT}, 42 + { "layer3+4", BOND_XMIT_POLICY_LAYER34, 0}, 43 + { "layer2+3", BOND_XMIT_POLICY_LAYER23, 0}, 44 + { "encap2+3", BOND_XMIT_POLICY_ENCAP23, 0}, 45 + { "encap3+4", BOND_XMIT_POLICY_ENCAP34, 0}, 46 + { NULL, -1, 0}, 47 + }; 48 + 49 + static struct bond_opt_value bond_arp_validate_tbl[] = { 50 + { "none", BOND_ARP_VALIDATE_NONE, BOND_VALFLAG_DEFAULT}, 51 + { "active", BOND_ARP_VALIDATE_ACTIVE, 0}, 52 + { "backup", BOND_ARP_VALIDATE_BACKUP, 0}, 53 + { "all", BOND_ARP_VALIDATE_ALL, 0}, 54 + { NULL, -1, 0}, 55 + }; 56 + 57 + static struct bond_opt_value bond_arp_all_targets_tbl[] = { 58 + { "any", BOND_ARP_TARGETS_ANY, BOND_VALFLAG_DEFAULT}, 59 + { "all", BOND_ARP_TARGETS_ALL, 0}, 60 + { NULL, -1, 0}, 61 + }; 62 + 63 + static struct bond_opt_value bond_fail_over_mac_tbl[] = { 64 + { "none", BOND_FOM_NONE, BOND_VALFLAG_DEFAULT}, 65 + { "active", BOND_FOM_ACTIVE, 0}, 66 + { "follow", BOND_FOM_FOLLOW, 0}, 67 + { NULL, -1, 0}, 68 + }; 69 + 70 + static struct bond_opt_value bond_intmax_tbl[] = { 71 + { "off", 0, BOND_VALFLAG_DEFAULT}, 72 + { "maxval", INT_MAX, BOND_VALFLAG_MAX}, 73 + }; 74 + 75 + static struct bond_opt_value bond_lacp_rate_tbl[] = { 76 + { "slow", AD_LACP_SLOW, 0}, 77 + { "fast", AD_LACP_FAST, 0}, 78 + { NULL, -1, 0}, 79 + }; 80 + 81 + static struct bond_opt_value bond_ad_select_tbl[] = { 82 + { "stable", BOND_AD_STABLE, BOND_VALFLAG_DEFAULT}, 83 + { "bandwidth", BOND_AD_BANDWIDTH, 0}, 84 + { "count", BOND_AD_COUNT, 0}, 85 + { NULL, -1, 0}, 86 + }; 87 + 88 + static struct bond_opt_value bond_num_peer_notif_tbl[] = { 89 + { "off", 0, 0}, 90 + { "maxval", 255, BOND_VALFLAG_MAX}, 91 + { "default", 1, BOND_VALFLAG_DEFAULT}, 92 + { NULL, -1, 0} 93 + }; 94 + 95 + static struct bond_opt_value bond_primary_reselect_tbl[] = { 96 + { "always", BOND_PRI_RESELECT_ALWAYS, BOND_VALFLAG_DEFAULT}, 97 + { "better", BOND_PRI_RESELECT_BETTER, 0}, 98 + { "failure", BOND_PRI_RESELECT_FAILURE, 0}, 99 + { NULL, -1}, 100 + }; 101 + 102 + static struct bond_opt_value bond_use_carrier_tbl[] = { 103 + { "off", 0, 0}, 104 + { "on", 1, BOND_VALFLAG_DEFAULT}, 105 + { NULL, -1, 0} 106 + }; 107 + 108 + static struct bond_opt_value bond_all_slaves_active_tbl[] = { 109 + { "off", 0, BOND_VALFLAG_DEFAULT}, 110 + { "on", 1, 0}, 111 + { NULL, -1, 0} 112 + }; 113 + 114 + static struct bond_opt_value bond_resend_igmp_tbl[] = { 115 + { "off", 0, 0}, 116 + { "maxval", 255, BOND_VALFLAG_MAX}, 117 + { "default", 1, BOND_VALFLAG_DEFAULT}, 118 + { NULL, -1, 0} 119 + }; 120 + 121 + static struct bond_opt_value bond_lp_interval_tbl[] = { 122 + { "minval", 1, BOND_VALFLAG_MIN | BOND_VALFLAG_DEFAULT}, 123 + { "maxval", INT_MAX, BOND_VALFLAG_MAX}, 124 + }; 125 + 126 + static struct bond_option bond_opts[] = { 127 + [BOND_OPT_MODE] = { 128 + .id = BOND_OPT_MODE, 129 + .name = "mode", 130 + .desc = "bond device mode", 131 + .flags = BOND_OPTFLAG_NOSLAVES | BOND_OPTFLAG_IFDOWN, 132 + .values = bond_mode_tbl, 133 + .set = bond_option_mode_set 134 + }, 135 + [BOND_OPT_PACKETS_PER_SLAVE] = { 136 + .id = BOND_OPT_PACKETS_PER_SLAVE, 137 + .name = "packets_per_slave", 138 + .desc = "Packets to send per slave in RR mode", 139 + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ROUNDROBIN)), 140 + .values = bond_pps_tbl, 141 + .set = bond_option_pps_set 142 + }, 143 + [BOND_OPT_XMIT_HASH] = { 144 + .id = BOND_OPT_XMIT_HASH, 145 + .name = "xmit_hash_policy", 146 + .desc = "balance-xor and 802.3ad hashing method", 147 + .values = bond_xmit_hashtype_tbl, 148 + .set = bond_option_xmit_hash_policy_set 149 + }, 150 + [BOND_OPT_ARP_VALIDATE] = { 151 + .id = BOND_OPT_ARP_VALIDATE, 152 + .name = "arp_validate", 153 + .desc = "validate src/dst of ARP probes", 154 + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP)), 155 + .values = bond_arp_validate_tbl, 156 + .set = bond_option_arp_validate_set 157 + }, 158 + [BOND_OPT_ARP_ALL_TARGETS] = { 159 + .id = BOND_OPT_ARP_ALL_TARGETS, 160 + .name = "arp_all_targets", 161 + .desc = "fail on any/all arp targets timeout", 162 + .values = bond_arp_all_targets_tbl, 163 + .set = bond_option_arp_all_targets_set 164 + }, 165 + [BOND_OPT_FAIL_OVER_MAC] = { 166 + .id = BOND_OPT_FAIL_OVER_MAC, 167 + .name = "fail_over_mac", 168 + .desc = "For active-backup, do not set all slaves to the same MAC", 169 + .flags = BOND_OPTFLAG_NOSLAVES, 170 + .values = bond_fail_over_mac_tbl, 171 + .set = bond_option_fail_over_mac_set 172 + }, 173 + [BOND_OPT_ARP_INTERVAL] = { 174 + .id = BOND_OPT_ARP_INTERVAL, 175 + .name = "arp_interval", 176 + .desc = "arp interval in milliseconds", 177 + .unsuppmodes = BIT(BOND_MODE_8023AD) | BIT(BOND_MODE_TLB) | 178 + BIT(BOND_MODE_ALB), 179 + .values = bond_intmax_tbl, 180 + .set = bond_option_arp_interval_set 181 + }, 182 + [BOND_OPT_ARP_TARGETS] = { 183 + .id = BOND_OPT_ARP_TARGETS, 184 + .name = "arp_ip_target", 185 + .desc = "arp targets in n.n.n.n form", 186 + .flags = BOND_OPTFLAG_RAWVAL, 187 + .set = bond_option_arp_ip_targets_set 188 + }, 189 + [BOND_OPT_DOWNDELAY] = { 190 + .id = BOND_OPT_DOWNDELAY, 191 + .name = "downdelay", 192 + .desc = "Delay before considering link down, in milliseconds", 193 + .values = bond_intmax_tbl, 194 + .set = bond_option_downdelay_set 195 + }, 196 + [BOND_OPT_UPDELAY] = { 197 + .id = BOND_OPT_UPDELAY, 198 + .name = "updelay", 199 + .desc = "Delay before considering link up, in milliseconds", 200 + .values = bond_intmax_tbl, 201 + .set = bond_option_updelay_set 202 + }, 203 + [BOND_OPT_LACP_RATE] = { 204 + .id = BOND_OPT_LACP_RATE, 205 + .name = "lacp_rate", 206 + .desc = "LACPDU tx rate to request from 802.3ad partner", 207 + .flags = BOND_OPTFLAG_IFDOWN, 208 + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_8023AD)), 209 + .values = bond_lacp_rate_tbl, 210 + .set = bond_option_lacp_rate_set 211 + }, 212 + [BOND_OPT_MINLINKS] = { 213 + .id = BOND_OPT_MINLINKS, 214 + .name = "min_links", 215 + .desc = "Minimum number of available links before turning on carrier", 216 + .values = bond_intmax_tbl, 217 + .set = bond_option_min_links_set 218 + }, 219 + [BOND_OPT_AD_SELECT] = { 220 + .id = BOND_OPT_AD_SELECT, 221 + .name = "ad_select", 222 + .desc = "803.ad aggregation selection logic", 223 + .flags = BOND_OPTFLAG_IFDOWN, 224 + .values = bond_ad_select_tbl, 225 + .set = bond_option_ad_select_set 226 + }, 227 + [BOND_OPT_NUM_PEER_NOTIF] = { 228 + .id = BOND_OPT_NUM_PEER_NOTIF, 229 + .name = "num_unsol_na", 230 + .desc = "Number of peer notifications to send on failover event", 231 + .values = bond_num_peer_notif_tbl, 232 + .set = bond_option_num_peer_notif_set 233 + }, 234 + [BOND_OPT_MIIMON] = { 235 + .id = BOND_OPT_MIIMON, 236 + .name = "miimon", 237 + .desc = "Link check interval in milliseconds", 238 + .values = bond_intmax_tbl, 239 + .set = bond_option_miimon_set 240 + }, 241 + [BOND_OPT_PRIMARY] = { 242 + .id = BOND_OPT_PRIMARY, 243 + .name = "primary", 244 + .desc = "Primary network device to use", 245 + .flags = BOND_OPTFLAG_RAWVAL, 246 + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP) | 247 + BIT(BOND_MODE_TLB) | 248 + BIT(BOND_MODE_ALB)), 249 + .set = bond_option_primary_set 250 + }, 251 + [BOND_OPT_PRIMARY_RESELECT] = { 252 + .id = BOND_OPT_PRIMARY_RESELECT, 253 + .name = "primary_reselect", 254 + .desc = "Reselect primary slave once it comes up", 255 + .values = bond_primary_reselect_tbl, 256 + .set = bond_option_primary_reselect_set 257 + }, 258 + [BOND_OPT_USE_CARRIER] = { 259 + .id = BOND_OPT_USE_CARRIER, 260 + .name = "use_carrier", 261 + .desc = "Use netif_carrier_ok (vs MII ioctls) in miimon", 262 + .values = bond_use_carrier_tbl, 263 + .set = bond_option_use_carrier_set 264 + }, 265 + [BOND_OPT_ACTIVE_SLAVE] = { 266 + .id = BOND_OPT_ACTIVE_SLAVE, 267 + .name = "active_slave", 268 + .desc = "Currently active slave", 269 + .flags = BOND_OPTFLAG_RAWVAL, 270 + .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_ACTIVEBACKUP) | 271 + BIT(BOND_MODE_TLB) | 272 + BIT(BOND_MODE_ALB)), 273 + .set = bond_option_active_slave_set 274 + }, 275 + [BOND_OPT_QUEUE_ID] = { 276 + .id = BOND_OPT_QUEUE_ID, 277 + .name = "queue_id", 278 + .desc = "Set queue id of a slave", 279 + .flags = BOND_OPTFLAG_RAWVAL, 280 + .set = bond_option_queue_id_set 281 + }, 282 + [BOND_OPT_ALL_SLAVES_ACTIVE] = { 283 + .id = BOND_OPT_ALL_SLAVES_ACTIVE, 284 + .name = "all_slaves_active", 285 + .desc = "Keep all frames received on an interface by setting active flag for all slaves", 286 + .values = bond_all_slaves_active_tbl, 287 + .set = bond_option_all_slaves_active_set 288 + }, 289 + [BOND_OPT_RESEND_IGMP] = { 290 + .id = BOND_OPT_RESEND_IGMP, 291 + .name = "resend_igmp", 292 + .desc = "Number of IGMP membership reports to send on link failure", 293 + .values = bond_resend_igmp_tbl, 294 + .set = bond_option_resend_igmp_set 295 + }, 296 + [BOND_OPT_LP_INTERVAL] = { 297 + .id = BOND_OPT_LP_INTERVAL, 298 + .name = "lp_interval", 299 + .desc = "The number of seconds between instances where the bonding driver sends learning packets to each slave's peer switch", 300 + .values = bond_lp_interval_tbl, 301 + .set = bond_option_lp_interval_set 302 + }, 303 + [BOND_OPT_SLAVES] = { 304 + .id = BOND_OPT_SLAVES, 305 + .name = "slaves", 306 + .desc = "Slave membership management", 307 + .flags = BOND_OPTFLAG_RAWVAL, 308 + .set = bond_option_slaves_set 309 + }, 310 + { } 311 + }; 312 + 313 + /* Searches for a value in opt's values[] table */ 314 + struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val) 22 315 { 23 - if (bond_parm_tbl_lookup(mode, bond_mode_tbl) < 0) { 24 - pr_err("%s: Ignoring invalid mode value %d.\n", 25 - bond->dev->name, mode); 26 - return -EINVAL; 316 + struct bond_option *opt; 317 + int i; 318 + 319 + opt = bond_opt_get(option); 320 + if (WARN_ON(!opt)) 321 + return NULL; 322 + for (i = 0; opt->values && opt->values[i].string; i++) 323 + if (opt->values[i].value == val) 324 + return &opt->values[i]; 325 + 326 + return NULL; 327 + } 328 + 329 + /* Searches for a value in opt's values[] table which matches the flagmask */ 330 + static struct bond_opt_value *bond_opt_get_flags(const struct bond_option *opt, 331 + u32 flagmask) 332 + { 333 + int i; 334 + 335 + for (i = 0; opt->values && opt->values[i].string; i++) 336 + if (opt->values[i].flags & flagmask) 337 + return &opt->values[i]; 338 + 339 + return NULL; 340 + } 341 + 342 + /* If maxval is missing then there's no range to check. In case minval is 343 + * missing then it's considered to be 0. 344 + */ 345 + static bool bond_opt_check_range(const struct bond_option *opt, u64 val) 346 + { 347 + struct bond_opt_value *minval, *maxval; 348 + 349 + minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN); 350 + maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX); 351 + if (!maxval || (minval && val < minval->value) || val > maxval->value) 352 + return false; 353 + 354 + return true; 355 + } 356 + 357 + /** 358 + * bond_opt_parse - parse option value 359 + * @opt: the option to parse against 360 + * @val: value to parse 361 + * 362 + * This function tries to extract the value from @val and check if it's 363 + * a possible match for the option and returns NULL if a match isn't found, 364 + * or the struct_opt_value that matched. It also strips the new line from 365 + * @val->string if it's present. 366 + */ 367 + struct bond_opt_value *bond_opt_parse(const struct bond_option *opt, 368 + struct bond_opt_value *val) 369 + { 370 + char *p, valstr[BOND_OPT_MAX_NAMELEN + 1] = { 0, }; 371 + struct bond_opt_value *tbl, *ret = NULL; 372 + bool checkval; 373 + int i, rv; 374 + 375 + /* No parsing if the option wants a raw val */ 376 + if (opt->flags & BOND_OPTFLAG_RAWVAL) 377 + return val; 378 + 379 + tbl = opt->values; 380 + if (!tbl) 381 + goto out; 382 + 383 + /* ULLONG_MAX is used to bypass string processing */ 384 + checkval = val->value != ULLONG_MAX; 385 + if (!checkval) { 386 + if (!val->string) 387 + goto out; 388 + p = strchr(val->string, '\n'); 389 + if (p) 390 + *p = '\0'; 391 + for (p = val->string; *p; p++) 392 + if (!(isdigit(*p) || isspace(*p))) 393 + break; 394 + /* The following code extracts the string to match or the value 395 + * and sets checkval appropriately 396 + */ 397 + if (*p) { 398 + rv = sscanf(val->string, "%32s", valstr); 399 + } else { 400 + rv = sscanf(val->string, "%llu", &val->value); 401 + checkval = true; 402 + } 403 + if (!rv) 404 + goto out; 27 405 } 28 406 29 - if (bond->dev->flags & IFF_UP) { 30 - pr_err("%s: unable to update mode because interface is up.\n", 31 - bond->dev->name); 32 - return -EPERM; 33 - } 407 + for (i = 0; tbl[i].string; i++) { 408 + /* Check for exact match */ 409 + if (checkval) { 410 + if (val->value == tbl[i].value) 411 + ret = &tbl[i]; 412 + } else { 413 + if (!strcmp(valstr, "default") && 414 + (tbl[i].flags & BOND_VALFLAG_DEFAULT)) 415 + ret = &tbl[i]; 34 416 35 - if (bond_has_slaves(bond)) { 36 - pr_err("%s: unable to update mode because bond has slaves.\n", 37 - bond->dev->name); 38 - return -EPERM; 417 + if (!strcmp(valstr, tbl[i].string)) 418 + ret = &tbl[i]; 419 + } 420 + /* Found an exact match */ 421 + if (ret) 422 + goto out; 39 423 } 424 + /* Possible range match */ 425 + if (checkval && bond_opt_check_range(opt, val->value)) 426 + ret = val; 427 + out: 428 + return ret; 429 + } 40 430 41 - if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) { 431 + /* Check opt's dependencies against bond mode and currently set options */ 432 + static int bond_opt_check_deps(struct bonding *bond, 433 + const struct bond_option *opt) 434 + { 435 + struct bond_params *params = &bond->params; 436 + 437 + if (test_bit(params->mode, &opt->unsuppmodes)) 438 + return -EACCES; 439 + if ((opt->flags & BOND_OPTFLAG_NOSLAVES) && bond_has_slaves(bond)) 440 + return -ENOTEMPTY; 441 + if ((opt->flags & BOND_OPTFLAG_IFDOWN) && (bond->dev->flags & IFF_UP)) 442 + return -EBUSY; 443 + 444 + return 0; 445 + } 446 + 447 + static void bond_opt_dep_print(struct bonding *bond, 448 + const struct bond_option *opt) 449 + { 450 + struct bond_opt_value *modeval; 451 + struct bond_params *params; 452 + 453 + params = &bond->params; 454 + modeval = bond_opt_get_val(BOND_OPT_MODE, params->mode); 455 + if (test_bit(params->mode, &opt->unsuppmodes)) 456 + pr_err("%s: option %s: mode dependency failed, not supported in mode %s(%llu)\n", 457 + bond->dev->name, opt->name, 458 + modeval->string, modeval->value); 459 + } 460 + 461 + static void bond_opt_error_interpret(struct bonding *bond, 462 + const struct bond_option *opt, 463 + int error, struct bond_opt_value *val) 464 + { 465 + struct bond_opt_value *minval, *maxval; 466 + char *p; 467 + 468 + switch (error) { 469 + case -EINVAL: 470 + if (val) { 471 + if (val->string) { 472 + /* sometimes RAWVAL opts may have new lines */ 473 + p = strchr(val->string, '\n'); 474 + if (p) 475 + *p = '\0'; 476 + pr_err("%s: option %s: invalid value (%s).\n", 477 + bond->dev->name, opt->name, val->string); 478 + } else { 479 + pr_err("%s: option %s: invalid value (%llu).\n", 480 + bond->dev->name, opt->name, val->value); 481 + } 482 + } 483 + minval = bond_opt_get_flags(opt, BOND_VALFLAG_MIN); 484 + maxval = bond_opt_get_flags(opt, BOND_VALFLAG_MAX); 485 + if (!maxval) 486 + break; 487 + pr_err("%s: option %s: allowed values %llu - %llu.\n", 488 + bond->dev->name, opt->name, minval ? minval->value : 0, 489 + maxval->value); 490 + break; 491 + case -EACCES: 492 + bond_opt_dep_print(bond, opt); 493 + break; 494 + case -ENOTEMPTY: 495 + pr_err("%s: option %s: unable to set because the bond device has slaves.\n", 496 + bond->dev->name, opt->name); 497 + break; 498 + case -EBUSY: 499 + pr_err("%s: option %s: unable to set because the bond device is up.\n", 500 + bond->dev->name, opt->name); 501 + break; 502 + default: 503 + break; 504 + } 505 + } 506 + 507 + /** 508 + * __bond_opt_set - set a bonding option 509 + * @bond: target bond device 510 + * @option: option to set 511 + * @val: value to set it to 512 + * 513 + * This function is used to change the bond's option value, it can be 514 + * used for both enabling/changing an option and for disabling it. RTNL lock 515 + * must be obtained before calling this function. 516 + */ 517 + int __bond_opt_set(struct bonding *bond, 518 + unsigned int option, struct bond_opt_value *val) 519 + { 520 + struct bond_opt_value *retval = NULL; 521 + const struct bond_option *opt; 522 + int ret = -ENOENT; 523 + 524 + ASSERT_RTNL(); 525 + 526 + opt = bond_opt_get(option); 527 + if (WARN_ON(!val) || WARN_ON(!opt)) 528 + goto out; 529 + ret = bond_opt_check_deps(bond, opt); 530 + if (ret) 531 + goto out; 532 + retval = bond_opt_parse(opt, val); 533 + if (!retval) { 534 + ret = -EINVAL; 535 + goto out; 536 + } 537 + ret = opt->set(bond, retval); 538 + out: 539 + if (ret) 540 + bond_opt_error_interpret(bond, opt, ret, val); 541 + 542 + return ret; 543 + } 544 + 545 + /** 546 + * bond_opt_tryset_rtnl - try to acquire rtnl and call __bond_opt_set 547 + * @bond: target bond device 548 + * @option: option to set 549 + * @buf: value to set it to 550 + * 551 + * This function tries to acquire RTNL without blocking and if successful 552 + * calls __bond_opt_set. It is mainly used for sysfs option manipulation. 553 + */ 554 + int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf) 555 + { 556 + struct bond_opt_value optval; 557 + int ret; 558 + 559 + if (!rtnl_trylock()) 560 + return restart_syscall(); 561 + bond_opt_initstr(&optval, buf); 562 + ret = __bond_opt_set(bond, option, &optval); 563 + rtnl_unlock(); 564 + 565 + return ret; 566 + } 567 + 568 + /** 569 + * bond_opt_get - get a pointer to an option 570 + * @option: option for which to return a pointer 571 + * 572 + * This function checks if option is valid and if so returns a pointer 573 + * to its entry in the bond_opts[] option array. 574 + */ 575 + struct bond_option *bond_opt_get(unsigned int option) 576 + { 577 + if (!BOND_OPT_VALID(option)) 578 + return NULL; 579 + 580 + return &bond_opts[option]; 581 + } 582 + 583 + int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval) 584 + { 585 + if (BOND_NO_USES_ARP(newval->value) && bond->params.arp_interval) { 42 586 pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n", 43 - bond->dev->name, bond_mode_tbl[mode].modename); 587 + bond->dev->name, newval->string); 44 588 /* disable arp monitoring */ 45 589 bond->params.arp_interval = 0; 46 590 /* set miimon to default value */ ··· 595 51 596 52 /* don't cache arp_validate between modes */ 597 53 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; 598 - bond->params.mode = mode; 54 + bond->params.mode = newval->value; 55 + 599 56 return 0; 600 57 } 601 58 ··· 619 74 } 620 75 621 76 int bond_option_active_slave_set(struct bonding *bond, 622 - struct net_device *slave_dev) 77 + struct bond_opt_value *newval) 623 78 { 79 + char ifname[IFNAMSIZ] = { 0, }; 80 + struct net_device *slave_dev; 624 81 int ret = 0; 82 + 83 + sscanf(newval->string, "%15s", ifname); /* IFNAMSIZ */ 84 + if (!strlen(ifname) || newval->string[0] == '\n') { 85 + slave_dev = NULL; 86 + } else { 87 + slave_dev = __dev_get_by_name(dev_net(bond->dev), ifname); 88 + if (!slave_dev) 89 + return -ENODEV; 90 + } 625 91 626 92 if (slave_dev) { 627 93 if (!netif_is_bond_slave(slave_dev)) { ··· 646 90 bond->dev->name, slave_dev->name); 647 91 return -EINVAL; 648 92 } 649 - } 650 - 651 - if (!USES_PRIMARY(bond->params.mode)) { 652 - pr_err("%s: Unable to change active slave; %s is in mode %d\n", 653 - bond->dev->name, bond->dev->name, bond->params.mode); 654 - return -EINVAL; 655 93 } 656 94 657 95 block_netpoll_tx(); ··· 684 134 685 135 write_unlock_bh(&bond->curr_slave_lock); 686 136 unblock_netpoll_tx(); 137 + 687 138 return ret; 688 139 } 689 140 690 - int bond_option_miimon_set(struct bonding *bond, int miimon) 141 + int bond_option_miimon_set(struct bonding *bond, struct bond_opt_value *newval) 691 142 { 692 - if (miimon < 0) { 693 - pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", 694 - bond->dev->name, miimon, 0, INT_MAX); 695 - return -EINVAL; 696 - } 697 - pr_info("%s: Setting MII monitoring interval to %d.\n", 698 - bond->dev->name, miimon); 699 - bond->params.miimon = miimon; 143 + pr_info("%s: Setting MII monitoring interval to %llu.\n", 144 + bond->dev->name, newval->value); 145 + bond->params.miimon = newval->value; 700 146 if (bond->params.updelay) 701 147 pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", 702 148 bond->dev->name, ··· 701 155 pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", 702 156 bond->dev->name, 703 157 bond->params.downdelay * bond->params.miimon); 704 - if (miimon && bond->params.arp_interval) { 158 + if (newval->value && bond->params.arp_interval) { 705 159 pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", 706 160 bond->dev->name); 707 161 bond->params.arp_interval = 0; ··· 714 168 * timer will get fired off when the open function 715 169 * is called. 716 170 */ 717 - if (!miimon) { 171 + if (!newval->value) { 718 172 cancel_delayed_work_sync(&bond->mii_work); 719 173 } else { 720 174 cancel_delayed_work_sync(&bond->arp_work); 721 175 queue_delayed_work(bond->wq, &bond->mii_work, 0); 722 176 } 723 177 } 178 + 724 179 return 0; 725 180 } 726 181 727 - int bond_option_updelay_set(struct bonding *bond, int updelay) 182 + int bond_option_updelay_set(struct bonding *bond, struct bond_opt_value *newval) 728 183 { 729 - if (!(bond->params.miimon)) { 184 + if (!bond->params.miimon) { 730 185 pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", 731 186 bond->dev->name); 732 187 return -EPERM; 733 188 } 734 - 735 - if (updelay < 0) { 736 - pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", 737 - bond->dev->name, updelay, 0, INT_MAX); 738 - return -EINVAL; 739 - } else { 740 - if ((updelay % bond->params.miimon) != 0) { 741 - pr_warn("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n", 742 - bond->dev->name, updelay, 743 - bond->params.miimon, 744 - (updelay / bond->params.miimon) * 745 - bond->params.miimon); 746 - } 747 - bond->params.updelay = updelay / bond->params.miimon; 748 - pr_info("%s: Setting up delay to %d.\n", 749 - bond->dev->name, 750 - bond->params.updelay * bond->params.miimon); 189 + if ((newval->value % bond->params.miimon) != 0) { 190 + pr_warn("%s: Warning: up delay (%llu) is not a multiple of miimon (%d), updelay rounded to %llu ms\n", 191 + bond->dev->name, newval->value, 192 + bond->params.miimon, 193 + (newval->value / bond->params.miimon) * 194 + bond->params.miimon); 751 195 } 196 + bond->params.updelay = newval->value / bond->params.miimon; 197 + pr_info("%s: Setting up delay to %d.\n", 198 + bond->dev->name, 199 + bond->params.updelay * bond->params.miimon); 752 200 753 201 return 0; 754 202 } 755 203 756 - int bond_option_downdelay_set(struct bonding *bond, int downdelay) 204 + int bond_option_downdelay_set(struct bonding *bond, 205 + struct bond_opt_value *newval) 757 206 { 758 - if (!(bond->params.miimon)) { 207 + if (!bond->params.miimon) { 759 208 pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", 760 209 bond->dev->name); 761 210 return -EPERM; 762 211 } 763 - 764 - if (downdelay < 0) { 765 - pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", 766 - bond->dev->name, downdelay, 0, INT_MAX); 767 - return -EINVAL; 768 - } else { 769 - if ((downdelay % bond->params.miimon) != 0) { 770 - pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n", 771 - bond->dev->name, downdelay, 772 - bond->params.miimon, 773 - (downdelay / bond->params.miimon) * 774 - bond->params.miimon); 775 - } 776 - bond->params.downdelay = downdelay / bond->params.miimon; 777 - pr_info("%s: Setting down delay to %d.\n", 778 - bond->dev->name, 779 - bond->params.downdelay * bond->params.miimon); 212 + if ((newval->value % bond->params.miimon) != 0) { 213 + pr_warn("%s: Warning: down delay (%llu) is not a multiple of miimon (%d), delay rounded to %llu ms\n", 214 + bond->dev->name, newval->value, 215 + bond->params.miimon, 216 + (newval->value / bond->params.miimon) * 217 + bond->params.miimon); 780 218 } 219 + bond->params.downdelay = newval->value / bond->params.miimon; 220 + pr_info("%s: Setting down delay to %d.\n", 221 + bond->dev->name, 222 + bond->params.downdelay * bond->params.miimon); 781 223 782 224 return 0; 783 225 } 784 226 785 - int bond_option_use_carrier_set(struct bonding *bond, int use_carrier) 227 + int bond_option_use_carrier_set(struct bonding *bond, 228 + struct bond_opt_value *newval) 786 229 { 787 - if ((use_carrier == 0) || (use_carrier == 1)) { 788 - bond->params.use_carrier = use_carrier; 789 - pr_info("%s: Setting use_carrier to %d.\n", 790 - bond->dev->name, use_carrier); 791 - } else { 792 - pr_info("%s: Ignoring invalid use_carrier value %d.\n", 793 - bond->dev->name, use_carrier); 794 - } 230 + pr_info("%s: Setting use_carrier to %llu.\n", 231 + bond->dev->name, newval->value); 232 + bond->params.use_carrier = newval->value; 795 233 796 234 return 0; 797 235 } 798 236 799 - int bond_option_arp_interval_set(struct bonding *bond, int arp_interval) 237 + int bond_option_arp_interval_set(struct bonding *bond, 238 + struct bond_opt_value *newval) 800 239 { 801 - if (arp_interval < 0) { 802 - pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n", 803 - bond->dev->name, arp_interval, INT_MAX); 804 - return -EINVAL; 805 - } 806 - if (BOND_NO_USES_ARP(bond->params.mode)) { 807 - pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n", 808 - bond->dev->name, bond->dev->name); 809 - return -EINVAL; 810 - } 811 - pr_info("%s: Setting ARP monitoring interval to %d.\n", 812 - bond->dev->name, arp_interval); 813 - bond->params.arp_interval = arp_interval; 814 - if (arp_interval) { 240 + pr_info("%s: Setting ARP monitoring interval to %llu.\n", 241 + bond->dev->name, newval->value); 242 + bond->params.arp_interval = newval->value; 243 + if (newval->value) { 815 244 if (bond->params.miimon) { 816 245 pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", 817 246 bond->dev->name, bond->dev->name); ··· 802 281 * timer will get fired off when the open function 803 282 * is called. 804 283 */ 805 - if (!arp_interval) { 284 + if (!newval->value) { 806 285 if (bond->params.arp_validate) 807 286 bond->recv_probe = NULL; 808 287 cancel_delayed_work_sync(&bond->arp_work); ··· 922 401 return 0; 923 402 } 924 403 925 - int bond_option_arp_ip_targets_set(struct bonding *bond, __be32 *targets, 926 - int count) 404 + void bond_option_arp_ip_targets_clear(struct bonding *bond) 927 405 { 928 - int i, ret = 0; 406 + int i; 929 407 930 408 /* not to race with bond_arp_rcv */ 931 409 write_lock_bh(&bond->lock); 932 - 933 - /* clear table */ 934 410 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) 935 411 _bond_options_arp_ip_target_set(bond, i, 0, 0); 412 + write_unlock_bh(&bond->lock); 413 + } 936 414 937 - if (count == 0 && bond->params.arp_interval) 938 - pr_warn("%s: removing last arp target with arp_interval on\n", 939 - bond->dev->name); 415 + int bond_option_arp_ip_targets_set(struct bonding *bond, 416 + struct bond_opt_value *newval) 417 + { 418 + int ret = -EPERM; 419 + __be32 target; 940 420 941 - for (i = 0; i < count; i++) { 942 - ret = _bond_option_arp_ip_target_add(bond, targets[i]); 943 - if (ret) 944 - break; 421 + if (newval->string) { 422 + if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) { 423 + pr_err("%s: invalid ARP target %pI4 specified\n", 424 + bond->dev->name, &target); 425 + return ret; 426 + } 427 + if (newval->string[0] == '+') 428 + ret = bond_option_arp_ip_target_add(bond, target); 429 + else if (newval->string[0] == '-') 430 + ret = bond_option_arp_ip_target_rem(bond, target); 431 + else 432 + pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n", 433 + bond->dev->name); 434 + } else { 435 + target = newval->value; 436 + ret = bond_option_arp_ip_target_add(bond, target); 945 437 } 946 438 947 - write_unlock_bh(&bond->lock); 948 439 return ret; 949 440 } 950 441 951 - int bond_option_arp_validate_set(struct bonding *bond, int arp_validate) 442 + int bond_option_arp_validate_set(struct bonding *bond, 443 + struct bond_opt_value *newval) 952 444 { 953 - if (bond_parm_tbl_lookup(arp_validate, arp_validate_tbl) < 0) { 954 - pr_err("%s: Ignoring invalid arp_validate value %d.\n", 955 - bond->dev->name, arp_validate); 956 - return -EINVAL; 957 - } 958 - 959 - if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) { 960 - pr_err("%s: arp_validate only supported in active-backup mode.\n", 961 - bond->dev->name); 962 - return -EINVAL; 963 - } 964 - 965 - pr_info("%s: setting arp_validate to %s (%d).\n", 966 - bond->dev->name, arp_validate_tbl[arp_validate].modename, 967 - arp_validate); 445 + pr_info("%s: setting arp_validate to %s (%llu).\n", 446 + bond->dev->name, newval->string, newval->value); 968 447 969 448 if (bond->dev->flags & IFF_UP) { 970 - if (!arp_validate) 449 + if (!newval->value) 971 450 bond->recv_probe = NULL; 972 451 else if (bond->params.arp_interval) 973 452 bond->recv_probe = bond_arp_rcv; 974 453 } 975 - bond->params.arp_validate = arp_validate; 454 + bond->params.arp_validate = newval->value; 976 455 977 456 return 0; 978 457 } 979 458 980 - int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets) 459 + int bond_option_arp_all_targets_set(struct bonding *bond, 460 + struct bond_opt_value *newval) 981 461 { 982 - if (bond_parm_tbl_lookup(arp_all_targets, arp_all_targets_tbl) < 0) { 983 - pr_err("%s: Ignoring invalid arp_all_targets value %d.\n", 984 - bond->dev->name, arp_all_targets); 985 - return -EINVAL; 986 - } 987 - 988 - pr_info("%s: setting arp_all_targets to %s (%d).\n", 989 - bond->dev->name, arp_all_targets_tbl[arp_all_targets].modename, 990 - arp_all_targets); 991 - 992 - bond->params.arp_all_targets = arp_all_targets; 462 + pr_info("%s: setting arp_all_targets to %s (%llu).\n", 463 + bond->dev->name, newval->string, newval->value); 464 + bond->params.arp_all_targets = newval->value; 993 465 994 466 return 0; 995 467 } 996 468 997 - int bond_option_primary_set(struct bonding *bond, const char *primary) 469 + int bond_option_primary_set(struct bonding *bond, struct bond_opt_value *newval) 998 470 { 471 + char *p, *primary = newval->string; 999 472 struct list_head *iter; 1000 473 struct slave *slave; 1001 - int err = 0; 1002 474 1003 475 block_netpoll_tx(); 1004 476 read_lock(&bond->lock); 1005 477 write_lock_bh(&bond->curr_slave_lock); 1006 478 1007 - if (!USES_PRIMARY(bond->params.mode)) { 1008 - pr_err("%s: Unable to set primary slave; %s is in mode %d\n", 1009 - bond->dev->name, bond->dev->name, bond->params.mode); 1010 - err = -EINVAL; 1011 - goto out; 1012 - } 1013 - 479 + p = strchr(primary, '\n'); 480 + if (p) 481 + *p = '\0'; 1014 482 /* check to see if we are clearing primary */ 1015 483 if (!strlen(primary)) { 1016 484 pr_info("%s: Setting primary slave to None.\n", ··· 1032 522 read_unlock(&bond->lock); 1033 523 unblock_netpoll_tx(); 1034 524 1035 - return err; 525 + return 0; 1036 526 } 1037 527 1038 - int bond_option_primary_reselect_set(struct bonding *bond, int primary_reselect) 528 + int bond_option_primary_reselect_set(struct bonding *bond, 529 + struct bond_opt_value *newval) 1039 530 { 1040 - if (bond_parm_tbl_lookup(primary_reselect, pri_reselect_tbl) < 0) { 1041 - pr_err("%s: Ignoring invalid primary_reselect value %d.\n", 1042 - bond->dev->name, primary_reselect); 1043 - return -EINVAL; 1044 - } 1045 - 1046 - bond->params.primary_reselect = primary_reselect; 1047 - pr_info("%s: setting primary_reselect to %s (%d).\n", 1048 - bond->dev->name, pri_reselect_tbl[primary_reselect].modename, 1049 - primary_reselect); 531 + pr_info("%s: setting primary_reselect to %s (%llu).\n", 532 + bond->dev->name, newval->string, newval->value); 533 + bond->params.primary_reselect = newval->value; 1050 534 1051 535 block_netpoll_tx(); 1052 536 write_lock_bh(&bond->curr_slave_lock); ··· 1051 547 return 0; 1052 548 } 1053 549 1054 - int bond_option_fail_over_mac_set(struct bonding *bond, int fail_over_mac) 550 + int bond_option_fail_over_mac_set(struct bonding *bond, 551 + struct bond_opt_value *newval) 1055 552 { 1056 - if (bond_parm_tbl_lookup(fail_over_mac, fail_over_mac_tbl) < 0) { 1057 - pr_err("%s: Ignoring invalid fail_over_mac value %d.\n", 1058 - bond->dev->name, fail_over_mac); 1059 - return -EINVAL; 1060 - } 1061 - 1062 - if (bond_has_slaves(bond)) { 1063 - pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n", 1064 - bond->dev->name); 1065 - return -EPERM; 1066 - } 1067 - 1068 - bond->params.fail_over_mac = fail_over_mac; 1069 - pr_info("%s: Setting fail_over_mac to %s (%d).\n", 1070 - bond->dev->name, fail_over_mac_tbl[fail_over_mac].modename, 1071 - fail_over_mac); 553 + pr_info("%s: Setting fail_over_mac to %s (%llu).\n", 554 + bond->dev->name, newval->string, newval->value); 555 + bond->params.fail_over_mac = newval->value; 1072 556 1073 557 return 0; 1074 558 } 1075 559 1076 - int bond_option_xmit_hash_policy_set(struct bonding *bond, int xmit_hash_policy) 560 + int bond_option_xmit_hash_policy_set(struct bonding *bond, 561 + struct bond_opt_value *newval) 1077 562 { 1078 - if (bond_parm_tbl_lookup(xmit_hash_policy, xmit_hashtype_tbl) < 0) { 1079 - pr_err("%s: Ignoring invalid xmit_hash_policy value %d.\n", 1080 - bond->dev->name, xmit_hash_policy); 1081 - return -EINVAL; 1082 - } 1083 - 1084 - bond->params.xmit_policy = xmit_hash_policy; 1085 - pr_info("%s: setting xmit hash policy to %s (%d).\n", 1086 - bond->dev->name, 1087 - xmit_hashtype_tbl[xmit_hash_policy].modename, xmit_hash_policy); 563 + pr_info("%s: setting xmit hash policy to %s (%llu).\n", 564 + bond->dev->name, newval->string, newval->value); 565 + bond->params.xmit_policy = newval->value; 1088 566 1089 567 return 0; 1090 568 } 1091 569 1092 - int bond_option_resend_igmp_set(struct bonding *bond, int resend_igmp) 570 + int bond_option_resend_igmp_set(struct bonding *bond, 571 + struct bond_opt_value *newval) 1093 572 { 1094 - if (resend_igmp < 0 || resend_igmp > 255) { 1095 - pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n", 1096 - bond->dev->name, resend_igmp); 1097 - return -EINVAL; 1098 - } 1099 - 1100 - bond->params.resend_igmp = resend_igmp; 1101 - pr_info("%s: Setting resend_igmp to %d.\n", 1102 - bond->dev->name, resend_igmp); 573 + pr_info("%s: Setting resend_igmp to %llu.\n", 574 + bond->dev->name, newval->value); 575 + bond->params.resend_igmp = newval->value; 1103 576 1104 577 return 0; 1105 578 } 1106 579 1107 - int bond_option_num_peer_notif_set(struct bonding *bond, int num_peer_notif) 580 + int bond_option_num_peer_notif_set(struct bonding *bond, 581 + struct bond_opt_value *newval) 1108 582 { 1109 - bond->params.num_peer_notif = num_peer_notif; 583 + bond->params.num_peer_notif = newval->value; 584 + 1110 585 return 0; 1111 586 } 1112 587 1113 588 int bond_option_all_slaves_active_set(struct bonding *bond, 1114 - int all_slaves_active) 589 + struct bond_opt_value *newval) 1115 590 { 1116 591 struct list_head *iter; 1117 592 struct slave *slave; 1118 593 1119 - if (all_slaves_active == bond->params.all_slaves_active) 594 + if (newval->value == bond->params.all_slaves_active) 1120 595 return 0; 1121 - 1122 - if ((all_slaves_active == 0) || (all_slaves_active == 1)) { 1123 - bond->params.all_slaves_active = all_slaves_active; 1124 - } else { 1125 - pr_info("%s: Ignoring invalid all_slaves_active value %d.\n", 1126 - bond->dev->name, all_slaves_active); 1127 - return -EINVAL; 1128 - } 1129 - 596 + bond->params.all_slaves_active = newval->value; 1130 597 bond_for_each_slave(bond, slave, iter) { 1131 598 if (!bond_is_active_slave(slave)) { 1132 - if (all_slaves_active) 599 + if (newval->value) 1133 600 slave->inactive = 0; 1134 601 else 1135 602 slave->inactive = 1; ··· 1110 635 return 0; 1111 636 } 1112 637 1113 - int bond_option_min_links_set(struct bonding *bond, int min_links) 638 + int bond_option_min_links_set(struct bonding *bond, 639 + struct bond_opt_value *newval) 1114 640 { 1115 - pr_info("%s: Setting min links value to %u\n", 1116 - bond->dev->name, min_links); 1117 - bond->params.min_links = min_links; 641 + pr_info("%s: Setting min links value to %llu\n", 642 + bond->dev->name, newval->value); 643 + bond->params.min_links = newval->value; 1118 644 1119 645 return 0; 1120 646 } 1121 647 1122 - int bond_option_lp_interval_set(struct bonding *bond, int lp_interval) 648 + int bond_option_lp_interval_set(struct bonding *bond, 649 + struct bond_opt_value *newval) 1123 650 { 1124 - if (lp_interval <= 0) { 1125 - pr_err("%s: lp_interval must be between 1 and %d\n", 1126 - bond->dev->name, INT_MAX); 1127 - return -EINVAL; 1128 - } 1129 - 1130 - bond->params.lp_interval = lp_interval; 651 + bond->params.lp_interval = newval->value; 1131 652 1132 653 return 0; 1133 654 } 1134 655 1135 - int bond_option_packets_per_slave_set(struct bonding *bond, 1136 - int packets_per_slave) 656 + int bond_option_pps_set(struct bonding *bond, struct bond_opt_value *newval) 1137 657 { 1138 - if (packets_per_slave < 0 || packets_per_slave > USHRT_MAX) { 1139 - pr_err("%s: packets_per_slave must be between 0 and %u\n", 1140 - bond->dev->name, USHRT_MAX); 1141 - return -EINVAL; 1142 - } 1143 - 1144 - if (bond->params.mode != BOND_MODE_ROUNDROBIN) 1145 - pr_warn("%s: Warning: packets_per_slave has effect only in balance-rr mode\n", 1146 - bond->dev->name); 1147 - 1148 - bond->params.packets_per_slave = packets_per_slave; 1149 - if (packets_per_slave > 0) { 658 + bond->params.packets_per_slave = newval->value; 659 + if (newval->value > 0) { 1150 660 bond->params.reciprocal_packets_per_slave = 1151 - reciprocal_value(packets_per_slave); 661 + reciprocal_value(newval->value); 1152 662 } else { 1153 663 /* reciprocal_packets_per_slave is unused if 1154 664 * packets_per_slave is 0 or 1, just initialize it ··· 1145 685 return 0; 1146 686 } 1147 687 1148 - int bond_option_lacp_rate_set(struct bonding *bond, int lacp_rate) 688 + int bond_option_lacp_rate_set(struct bonding *bond, 689 + struct bond_opt_value *newval) 1149 690 { 1150 - if (bond_parm_tbl_lookup(lacp_rate, bond_lacp_tbl) < 0) { 1151 - pr_err("%s: Ignoring invalid LACP rate value %d.\n", 1152 - bond->dev->name, lacp_rate); 1153 - return -EINVAL; 1154 - } 1155 - 1156 - if (bond->dev->flags & IFF_UP) { 1157 - pr_err("%s: Unable to update LACP rate because interface is up.\n", 1158 - bond->dev->name); 1159 - return -EPERM; 1160 - } 1161 - 1162 - if (bond->params.mode != BOND_MODE_8023AD) { 1163 - pr_err("%s: Unable to update LACP rate because bond is not in 802.3ad mode.\n", 1164 - bond->dev->name); 1165 - return -EPERM; 1166 - } 1167 - 1168 - bond->params.lacp_fast = lacp_rate; 691 + pr_info("%s: Setting LACP rate to %s (%llu).\n", 692 + bond->dev->name, newval->string, newval->value); 693 + bond->params.lacp_fast = newval->value; 1169 694 bond_3ad_update_lacp_rate(bond); 1170 - pr_info("%s: Setting LACP rate to %s (%d).\n", 1171 - bond->dev->name, bond_lacp_tbl[lacp_rate].modename, 1172 - lacp_rate); 1173 695 1174 696 return 0; 1175 697 } 1176 698 1177 - int bond_option_ad_select_set(struct bonding *bond, int ad_select) 699 + int bond_option_ad_select_set(struct bonding *bond, 700 + struct bond_opt_value *newval) 1178 701 { 1179 - if (bond_parm_tbl_lookup(ad_select, ad_select_tbl) < 0) { 1180 - pr_err("%s: Ignoring invalid ad_select value %d.\n", 1181 - bond->dev->name, ad_select); 1182 - return -EINVAL; 1183 - } 1184 - 1185 - if (bond->dev->flags & IFF_UP) { 1186 - pr_err("%s: Unable to update ad_select because interface is up.\n", 1187 - bond->dev->name); 1188 - return -EPERM; 1189 - } 1190 - 1191 - bond->params.ad_select = ad_select; 1192 - pr_info("%s: Setting ad_select to %s (%d).\n", 1193 - bond->dev->name, ad_select_tbl[ad_select].modename, 1194 - ad_select); 702 + pr_info("%s: Setting ad_select to %s (%llu).\n", 703 + bond->dev->name, newval->string, newval->value); 704 + bond->params.ad_select = newval->value; 1195 705 1196 706 return 0; 707 + } 708 + 709 + int bond_option_queue_id_set(struct bonding *bond, 710 + struct bond_opt_value *newval) 711 + { 712 + struct slave *slave, *update_slave; 713 + struct net_device *sdev; 714 + struct list_head *iter; 715 + char *delim; 716 + int ret = 0; 717 + u16 qid; 718 + 719 + /* delim will point to queue id if successful */ 720 + delim = strchr(newval->string, ':'); 721 + if (!delim) 722 + goto err_no_cmd; 723 + 724 + /* Terminate string that points to device name and bump it 725 + * up one, so we can read the queue id there. 726 + */ 727 + *delim = '\0'; 728 + if (sscanf(++delim, "%hd\n", &qid) != 1) 729 + goto err_no_cmd; 730 + 731 + /* Check buffer length, valid ifname and queue id */ 732 + if (strlen(newval->string) > IFNAMSIZ || 733 + !dev_valid_name(newval->string) || 734 + qid > bond->dev->real_num_tx_queues) 735 + goto err_no_cmd; 736 + 737 + /* Get the pointer to that interface if it exists */ 738 + sdev = __dev_get_by_name(dev_net(bond->dev), newval->string); 739 + if (!sdev) 740 + goto err_no_cmd; 741 + 742 + /* Search for thes slave and check for duplicate qids */ 743 + update_slave = NULL; 744 + bond_for_each_slave(bond, slave, iter) { 745 + if (sdev == slave->dev) 746 + /* We don't need to check the matching 747 + * slave for dups, since we're overwriting it 748 + */ 749 + update_slave = slave; 750 + else if (qid && qid == slave->queue_id) { 751 + goto err_no_cmd; 752 + } 753 + } 754 + 755 + if (!update_slave) 756 + goto err_no_cmd; 757 + 758 + /* Actually set the qids for the slave */ 759 + update_slave->queue_id = qid; 760 + 761 + out: 762 + return ret; 763 + 764 + err_no_cmd: 765 + pr_info("invalid input for queue_id set for %s.\n", 766 + bond->dev->name); 767 + ret = -EPERM; 768 + goto out; 769 + 770 + } 771 + 772 + int bond_option_slaves_set(struct bonding *bond, struct bond_opt_value *newval) 773 + { 774 + char command[IFNAMSIZ + 1] = { 0, }; 775 + struct net_device *dev; 776 + char *ifname; 777 + int ret; 778 + 779 + sscanf(newval->string, "%16s", command); /* IFNAMSIZ*/ 780 + ifname = command + 1; 781 + if ((strlen(command) <= 1) || 782 + !dev_valid_name(ifname)) 783 + goto err_no_cmd; 784 + 785 + dev = __dev_get_by_name(dev_net(bond->dev), ifname); 786 + if (!dev) { 787 + pr_info("%s: Interface %s does not exist!\n", 788 + bond->dev->name, ifname); 789 + ret = -ENODEV; 790 + goto out; 791 + } 792 + 793 + switch (command[0]) { 794 + case '+': 795 + pr_info("%s: Adding slave %s.\n", bond->dev->name, dev->name); 796 + ret = bond_enslave(bond->dev, dev); 797 + break; 798 + 799 + case '-': 800 + pr_info("%s: Removing slave %s.\n", bond->dev->name, dev->name); 801 + ret = bond_release(bond->dev, dev); 802 + break; 803 + 804 + default: 805 + goto err_no_cmd; 806 + } 807 + 808 + out: 809 + return ret; 810 + 811 + err_no_cmd: 812 + pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n", 813 + bond->dev->name); 814 + ret = -EPERM; 815 + goto out; 1197 816 }
+170
drivers/net/bonding/bond_options.h
··· 1 + /* 2 + * drivers/net/bond/bond_options.h - bonding options 3 + * Copyright (c) 2013 Nikolay Aleksandrov <nikolay@redhat.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify 6 + * it under the terms of the GNU General Public License as published by 7 + * the Free Software Foundation; either version 2 of the License, or 8 + * (at your option) any later version. 9 + */ 10 + 11 + #ifndef _BOND_OPTIONS_H 12 + #define _BOND_OPTIONS_H 13 + 14 + #define BOND_OPT_MAX_NAMELEN 32 15 + #define BOND_OPT_VALID(opt) ((opt) < BOND_OPT_LAST) 16 + #define BOND_MODE_ALL_EX(x) (~(x)) 17 + 18 + /* Option flags: 19 + * BOND_OPTFLAG_NOSLAVES - check if the bond device is empty before setting 20 + * BOND_OPTFLAG_IFDOWN - check if the bond device is down before setting 21 + * BOND_OPTFLAG_RAWVAL - the option parses the value itself 22 + */ 23 + enum { 24 + BOND_OPTFLAG_NOSLAVES = BIT(0), 25 + BOND_OPTFLAG_IFDOWN = BIT(1), 26 + BOND_OPTFLAG_RAWVAL = BIT(2) 27 + }; 28 + 29 + /* Value type flags: 30 + * BOND_VALFLAG_DEFAULT - mark the value as default 31 + * BOND_VALFLAG_(MIN|MAX) - mark the value as min/max 32 + */ 33 + enum { 34 + BOND_VALFLAG_DEFAULT = BIT(0), 35 + BOND_VALFLAG_MIN = BIT(1), 36 + BOND_VALFLAG_MAX = BIT(2) 37 + }; 38 + 39 + /* Option IDs, their bit positions correspond to their IDs */ 40 + enum { 41 + BOND_OPT_MODE, 42 + BOND_OPT_PACKETS_PER_SLAVE, 43 + BOND_OPT_XMIT_HASH, 44 + BOND_OPT_ARP_VALIDATE, 45 + BOND_OPT_ARP_ALL_TARGETS, 46 + BOND_OPT_FAIL_OVER_MAC, 47 + BOND_OPT_ARP_INTERVAL, 48 + BOND_OPT_ARP_TARGETS, 49 + BOND_OPT_DOWNDELAY, 50 + BOND_OPT_UPDELAY, 51 + BOND_OPT_LACP_RATE, 52 + BOND_OPT_MINLINKS, 53 + BOND_OPT_AD_SELECT, 54 + BOND_OPT_NUM_PEER_NOTIF, 55 + BOND_OPT_MIIMON, 56 + BOND_OPT_PRIMARY, 57 + BOND_OPT_PRIMARY_RESELECT, 58 + BOND_OPT_USE_CARRIER, 59 + BOND_OPT_ACTIVE_SLAVE, 60 + BOND_OPT_QUEUE_ID, 61 + BOND_OPT_ALL_SLAVES_ACTIVE, 62 + BOND_OPT_RESEND_IGMP, 63 + BOND_OPT_LP_INTERVAL, 64 + BOND_OPT_SLAVES, 65 + BOND_OPT_LAST 66 + }; 67 + 68 + /* This structure is used for storing option values and for passing option 69 + * values when changing an option. The logic when used as an arg is as follows: 70 + * - if string != NULL -> parse it, if the opt is RAW type then return it, else 71 + * return the parse result 72 + * - if string == NULL -> parse value 73 + */ 74 + struct bond_opt_value { 75 + char *string; 76 + u64 value; 77 + u32 flags; 78 + }; 79 + 80 + struct bonding; 81 + 82 + struct bond_option { 83 + int id; 84 + char *name; 85 + char *desc; 86 + u32 flags; 87 + 88 + /* unsuppmodes is used to denote modes in which the option isn't 89 + * supported. 90 + */ 91 + unsigned long unsuppmodes; 92 + /* supported values which this option can have, can be a subset of 93 + * BOND_OPTVAL_RANGE's value range 94 + */ 95 + struct bond_opt_value *values; 96 + 97 + int (*set)(struct bonding *bond, struct bond_opt_value *val); 98 + }; 99 + 100 + int __bond_opt_set(struct bonding *bond, unsigned int option, 101 + struct bond_opt_value *val); 102 + int bond_opt_tryset_rtnl(struct bonding *bond, unsigned int option, char *buf); 103 + struct bond_opt_value *bond_opt_parse(const struct bond_option *opt, 104 + struct bond_opt_value *val); 105 + struct bond_option *bond_opt_get(unsigned int option); 106 + struct bond_opt_value *bond_opt_get_val(unsigned int option, u64 val); 107 + 108 + /* This helper is used to initialize a bond_opt_value structure for parameter 109 + * passing. There should be either a valid string or value, but not both. 110 + * When value is ULLONG_MAX then string will be used. 111 + */ 112 + static inline void __bond_opt_init(struct bond_opt_value *optval, 113 + char *string, u64 value) 114 + { 115 + memset(optval, 0, sizeof(*optval)); 116 + optval->value = ULLONG_MAX; 117 + if (value == ULLONG_MAX) 118 + optval->string = string; 119 + else 120 + optval->value = value; 121 + } 122 + #define bond_opt_initval(optval, value) __bond_opt_init(optval, NULL, value) 123 + #define bond_opt_initstr(optval, str) __bond_opt_init(optval, str, ULLONG_MAX) 124 + 125 + int bond_option_mode_set(struct bonding *bond, struct bond_opt_value *newval); 126 + int bond_option_pps_set(struct bonding *bond, struct bond_opt_value *newval); 127 + int bond_option_xmit_hash_policy_set(struct bonding *bond, 128 + struct bond_opt_value *newval); 129 + int bond_option_arp_validate_set(struct bonding *bond, 130 + struct bond_opt_value *newval); 131 + int bond_option_arp_all_targets_set(struct bonding *bond, 132 + struct bond_opt_value *newval); 133 + int bond_option_fail_over_mac_set(struct bonding *bond, 134 + struct bond_opt_value *newval); 135 + int bond_option_arp_interval_set(struct bonding *bond, 136 + struct bond_opt_value *newval); 137 + int bond_option_arp_ip_targets_set(struct bonding *bond, 138 + struct bond_opt_value *newval); 139 + void bond_option_arp_ip_targets_clear(struct bonding *bond); 140 + int bond_option_downdelay_set(struct bonding *bond, 141 + struct bond_opt_value *newval); 142 + int bond_option_updelay_set(struct bonding *bond, 143 + struct bond_opt_value *newval); 144 + int bond_option_lacp_rate_set(struct bonding *bond, 145 + struct bond_opt_value *newval); 146 + int bond_option_min_links_set(struct bonding *bond, 147 + struct bond_opt_value *newval); 148 + int bond_option_ad_select_set(struct bonding *bond, 149 + struct bond_opt_value *newval); 150 + int bond_option_num_peer_notif_set(struct bonding *bond, 151 + struct bond_opt_value *newval); 152 + int bond_option_miimon_set(struct bonding *bond, struct bond_opt_value *newval); 153 + int bond_option_primary_set(struct bonding *bond, 154 + struct bond_opt_value *newval); 155 + int bond_option_primary_reselect_set(struct bonding *bond, 156 + struct bond_opt_value *newval); 157 + int bond_option_use_carrier_set(struct bonding *bond, 158 + struct bond_opt_value *newval); 159 + int bond_option_active_slave_set(struct bonding *bond, 160 + struct bond_opt_value *newval); 161 + int bond_option_queue_id_set(struct bonding *bond, 162 + struct bond_opt_value *newval); 163 + int bond_option_all_slaves_active_set(struct bonding *bond, 164 + struct bond_opt_value *newval); 165 + int bond_option_resend_igmp_set(struct bonding *bond, 166 + struct bond_opt_value *newval); 167 + int bond_option_lp_interval_set(struct bonding *bond, 168 + struct bond_opt_value *newval); 169 + int bond_option_slaves_set(struct bonding *bond, struct bond_opt_value *newval); 170 + #endif /* _BOND_OPTIONS_H */
+17 -8
drivers/net/bonding/bond_procfs.c
··· 65 65 static void bond_info_show_master(struct seq_file *seq) 66 66 { 67 67 struct bonding *bond = seq->private; 68 + struct bond_opt_value *optval; 68 69 struct slave *curr; 69 70 int i; 70 71 ··· 77 76 bond_mode_name(bond->params.mode)); 78 77 79 78 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && 80 - bond->params.fail_over_mac) 81 - seq_printf(seq, " (fail_over_mac %s)", 82 - fail_over_mac_tbl[bond->params.fail_over_mac].modename); 79 + bond->params.fail_over_mac) { 80 + optval = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC, 81 + bond->params.fail_over_mac); 82 + seq_printf(seq, " (fail_over_mac %s)", optval->string); 83 + } 83 84 84 85 seq_printf(seq, "\n"); 85 86 86 87 if (bond->params.mode == BOND_MODE_XOR || 87 88 bond->params.mode == BOND_MODE_8023AD) { 89 + optval = bond_opt_get_val(BOND_OPT_XMIT_HASH, 90 + bond->params.xmit_policy); 88 91 seq_printf(seq, "Transmit Hash Policy: %s (%d)\n", 89 - xmit_hashtype_tbl[bond->params.xmit_policy].modename, 90 - bond->params.xmit_policy); 92 + optval->string, bond->params.xmit_policy); 91 93 } 92 94 93 95 if (USES_PRIMARY(bond->params.mode)) { 94 96 seq_printf(seq, "Primary Slave: %s", 95 97 (bond->primary_slave) ? 96 98 bond->primary_slave->dev->name : "None"); 97 - if (bond->primary_slave) 99 + if (bond->primary_slave) { 100 + optval = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT, 101 + bond->params.primary_reselect); 98 102 seq_printf(seq, " (primary_reselect %s)", 99 - pri_reselect_tbl[bond->params.primary_reselect].modename); 103 + optval->string); 104 + } 100 105 101 106 seq_printf(seq, "\nCurrently Active Slave: %s\n", 102 107 (curr) ? curr->dev->name : "None"); ··· 143 136 seq_printf(seq, "LACP rate: %s\n", 144 137 (bond->params.lacp_fast) ? "fast" : "slow"); 145 138 seq_printf(seq, "Min links: %d\n", bond->params.min_links); 139 + optval = bond_opt_get_val(BOND_OPT_AD_SELECT, 140 + bond->params.ad_select); 146 141 seq_printf(seq, "Aggregator selection policy (ad_select): %s\n", 147 - ad_select_tbl[bond->params.ad_select].modename); 142 + optval->string); 148 143 149 144 if (__bond_3ad_get_active_agg_info(bond, &ad_info)) { 150 145 seq_printf(seq, "bond %s has no active aggregator\n",
+91 -428
drivers/net/bonding/bond_sysfs.c
··· 200 200 struct device_attribute *attr, 201 201 const char *buffer, size_t count) 202 202 { 203 - char command[IFNAMSIZ + 1] = { 0, }; 204 - char *ifname; 205 - int res, ret = count; 206 - struct net_device *dev; 207 203 struct bonding *bond = to_bond(d); 204 + int ret; 208 205 209 - if (!rtnl_trylock()) 210 - return restart_syscall(); 206 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_SLAVES, (char *)buffer); 207 + if (!ret) 208 + ret = count; 211 209 212 - sscanf(buffer, "%16s", command); /* IFNAMSIZ*/ 213 - ifname = command + 1; 214 - if ((strlen(command) <= 1) || 215 - !dev_valid_name(ifname)) 216 - goto err_no_cmd; 217 - 218 - dev = __dev_get_by_name(dev_net(bond->dev), ifname); 219 - if (!dev) { 220 - pr_info("%s: Interface %s does not exist!\n", 221 - bond->dev->name, ifname); 222 - ret = -ENODEV; 223 - goto out; 224 - } 225 - 226 - switch (command[0]) { 227 - case '+': 228 - pr_info("%s: Adding slave %s.\n", bond->dev->name, dev->name); 229 - res = bond_enslave(bond->dev, dev); 230 - break; 231 - 232 - case '-': 233 - pr_info("%s: Removing slave %s.\n", bond->dev->name, dev->name); 234 - res = bond_release(bond->dev, dev); 235 - break; 236 - 237 - default: 238 - goto err_no_cmd; 239 - } 240 - 241 - if (res) 242 - ret = res; 243 - goto out; 244 - 245 - err_no_cmd: 246 - pr_err("no command found in slaves file for bond %s. Use +ifname or -ifname.\n", 247 - bond->dev->name); 248 - ret = -EPERM; 249 - 250 - out: 251 - rtnl_unlock(); 252 210 return ret; 253 211 } 254 - 255 212 static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, 256 213 bonding_store_slaves); 257 214 ··· 220 263 struct device_attribute *attr, char *buf) 221 264 { 222 265 struct bonding *bond = to_bond(d); 266 + struct bond_opt_value *val; 223 267 224 - return sprintf(buf, "%s %d\n", 225 - bond_mode_tbl[bond->params.mode].modename, 226 - bond->params.mode); 268 + val = bond_opt_get_val(BOND_OPT_MODE, bond->params.mode); 269 + 270 + return sprintf(buf, "%s %d\n", val->string, bond->params.mode); 227 271 } 228 272 229 273 static ssize_t bonding_store_mode(struct device *d, 230 274 struct device_attribute *attr, 231 275 const char *buf, size_t count) 232 276 { 233 - int new_value, ret; 234 277 struct bonding *bond = to_bond(d); 278 + int ret; 235 279 236 - new_value = bond_parse_parm(buf, bond_mode_tbl); 237 - if (new_value < 0) { 238 - pr_err("%s: Ignoring invalid mode value %.*s.\n", 239 - bond->dev->name, (int)strlen(buf) - 1, buf); 240 - return -EINVAL; 241 - } 242 - if (!rtnl_trylock()) 243 - return restart_syscall(); 244 - 245 - ret = bond_option_mode_set(bond, new_value); 246 - if (!ret) { 247 - pr_info("%s: setting mode to %s (%d).\n", 248 - bond->dev->name, bond_mode_tbl[new_value].modename, 249 - new_value); 280 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MODE, (char *)buf); 281 + if (!ret) 250 282 ret = count; 251 - } 252 283 253 - rtnl_unlock(); 254 284 return ret; 255 285 } 256 286 static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, ··· 251 307 char *buf) 252 308 { 253 309 struct bonding *bond = to_bond(d); 310 + struct bond_opt_value *val; 254 311 255 - return sprintf(buf, "%s %d\n", 256 - xmit_hashtype_tbl[bond->params.xmit_policy].modename, 257 - bond->params.xmit_policy); 312 + val = bond_opt_get_val(BOND_OPT_XMIT_HASH, bond->params.xmit_policy); 313 + 314 + return sprintf(buf, "%s %d\n", val->string, bond->params.xmit_policy); 258 315 } 259 316 260 317 static ssize_t bonding_store_xmit_hash(struct device *d, 261 318 struct device_attribute *attr, 262 319 const char *buf, size_t count) 263 320 { 264 - int new_value, ret; 265 321 struct bonding *bond = to_bond(d); 322 + int ret; 266 323 267 - new_value = bond_parse_parm(buf, xmit_hashtype_tbl); 268 - if (new_value < 0) { 269 - pr_err("%s: Ignoring invalid xmit hash policy value %.*s.\n", 270 - bond->dev->name, 271 - (int)strlen(buf) - 1, buf); 272 - return -EINVAL; 273 - } 274 - 275 - if (!rtnl_trylock()) 276 - return restart_syscall(); 277 - 278 - ret = bond_option_xmit_hash_policy_set(bond, new_value); 324 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_XMIT_HASH, (char *)buf); 279 325 if (!ret) 280 326 ret = count; 281 327 282 - rtnl_unlock(); 283 328 return ret; 284 329 } 285 330 static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, ··· 282 349 char *buf) 283 350 { 284 351 struct bonding *bond = to_bond(d); 352 + struct bond_opt_value *val; 285 353 286 - return sprintf(buf, "%s %d\n", 287 - arp_validate_tbl[bond->params.arp_validate].modename, 288 - bond->params.arp_validate); 354 + val = bond_opt_get_val(BOND_OPT_ARP_VALIDATE, 355 + bond->params.arp_validate); 356 + 357 + return sprintf(buf, "%s %d\n", val->string, bond->params.arp_validate); 289 358 } 290 359 291 360 static ssize_t bonding_store_arp_validate(struct device *d, ··· 295 360 const char *buf, size_t count) 296 361 { 297 362 struct bonding *bond = to_bond(d); 298 - int new_value, ret; 363 + int ret; 299 364 300 - new_value = bond_parse_parm(buf, arp_validate_tbl); 301 - if (new_value < 0) { 302 - pr_err("%s: Ignoring invalid arp_validate value %s\n", 303 - bond->dev->name, buf); 304 - return -EINVAL; 305 - } 306 - if (!rtnl_trylock()) 307 - return restart_syscall(); 308 - 309 - ret = bond_option_arp_validate_set(bond, new_value); 365 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_VALIDATE, (char *)buf); 310 366 if (!ret) 311 367 ret = count; 312 - 313 - rtnl_unlock(); 314 368 315 369 return ret; 316 370 } ··· 314 390 char *buf) 315 391 { 316 392 struct bonding *bond = to_bond(d); 317 - int value = bond->params.arp_all_targets; 393 + struct bond_opt_value *val; 318 394 319 - return sprintf(buf, "%s %d\n", arp_all_targets_tbl[value].modename, 320 - value); 395 + val = bond_opt_get_val(BOND_OPT_ARP_ALL_TARGETS, 396 + bond->params.arp_all_targets); 397 + return sprintf(buf, "%s %d\n", 398 + val->string, bond->params.arp_all_targets); 321 399 } 322 400 323 401 static ssize_t bonding_store_arp_all_targets(struct device *d, ··· 327 401 const char *buf, size_t count) 328 402 { 329 403 struct bonding *bond = to_bond(d); 330 - int new_value, ret; 404 + int ret; 331 405 332 - new_value = bond_parse_parm(buf, arp_all_targets_tbl); 333 - if (new_value < 0) { 334 - pr_err("%s: Ignoring invalid arp_all_targets value %s\n", 335 - bond->dev->name, buf); 336 - return -EINVAL; 337 - } 338 - 339 - if (!rtnl_trylock()) 340 - return restart_syscall(); 341 - 342 - ret = bond_option_arp_all_targets_set(bond, new_value); 406 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_ALL_TARGETS, (char *)buf); 343 407 if (!ret) 344 408 ret = count; 345 - 346 - rtnl_unlock(); 347 409 348 410 return ret; 349 411 } ··· 348 434 char *buf) 349 435 { 350 436 struct bonding *bond = to_bond(d); 437 + struct bond_opt_value *val; 351 438 352 - return sprintf(buf, "%s %d\n", 353 - fail_over_mac_tbl[bond->params.fail_over_mac].modename, 354 - bond->params.fail_over_mac); 439 + val = bond_opt_get_val(BOND_OPT_FAIL_OVER_MAC, 440 + bond->params.fail_over_mac); 441 + 442 + return sprintf(buf, "%s %d\n", val->string, bond->params.fail_over_mac); 355 443 } 356 444 357 445 static ssize_t bonding_store_fail_over_mac(struct device *d, 358 446 struct device_attribute *attr, 359 447 const char *buf, size_t count) 360 448 { 361 - int new_value, ret; 362 449 struct bonding *bond = to_bond(d); 450 + int ret; 363 451 364 - new_value = bond_parse_parm(buf, fail_over_mac_tbl); 365 - if (new_value < 0) { 366 - pr_err("%s: Ignoring invalid fail_over_mac value %s.\n", 367 - bond->dev->name, buf); 368 - return -EINVAL; 369 - } 370 - 371 - if (!rtnl_trylock()) 372 - return restart_syscall(); 373 - 374 - ret = bond_option_fail_over_mac_set(bond, new_value); 452 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_FAIL_OVER_MAC, (char *)buf); 375 453 if (!ret) 376 454 ret = count; 377 455 378 - rtnl_unlock(); 379 456 return ret; 380 457 } 381 458 ··· 393 488 const char *buf, size_t count) 394 489 { 395 490 struct bonding *bond = to_bond(d); 396 - int new_value, ret; 491 + int ret; 397 492 398 - if (sscanf(buf, "%d", &new_value) != 1) { 399 - pr_err("%s: no arp_interval value specified.\n", 400 - bond->dev->name); 401 - return -EINVAL; 402 - } 403 - 404 - if (!rtnl_trylock()) 405 - return restart_syscall(); 406 - 407 - ret = bond_option_arp_interval_set(bond, new_value); 493 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_INTERVAL, (char *)buf); 408 494 if (!ret) 409 495 ret = count; 410 496 411 - rtnl_unlock(); 412 497 return ret; 413 498 } 414 499 static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR, ··· 411 516 struct device_attribute *attr, 412 517 char *buf) 413 518 { 414 - int i, res = 0; 415 519 struct bonding *bond = to_bond(d); 520 + int i, res = 0; 416 521 417 522 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) { 418 523 if (bond->params.arp_targets[i]) ··· 421 526 } 422 527 if (res) 423 528 buf[res-1] = '\n'; /* eat the leftover space */ 529 + 424 530 return res; 425 531 } 426 532 ··· 430 534 const char *buf, size_t count) 431 535 { 432 536 struct bonding *bond = to_bond(d); 433 - __be32 target; 434 - int ret = -EPERM; 537 + int ret; 435 538 436 - if (!in4_pton(buf + 1, -1, (u8 *)&target, -1, NULL)) { 437 - pr_err("%s: invalid ARP target %pI4 specified\n", 438 - bond->dev->name, &target); 439 - return -EPERM; 440 - } 441 - 442 - if (!rtnl_trylock()) 443 - return restart_syscall(); 444 - 445 - if (buf[0] == '+') 446 - ret = bond_option_arp_ip_target_add(bond, target); 447 - else if (buf[0] == '-') 448 - ret = bond_option_arp_ip_target_rem(bond, target); 449 - else 450 - pr_err("no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n", 451 - bond->dev->name); 452 - 539 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ARP_TARGETS, (char *)buf); 453 540 if (!ret) 454 541 ret = count; 455 542 456 - rtnl_unlock(); 457 543 return ret; 458 544 } 459 545 static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets); ··· 458 580 struct device_attribute *attr, 459 581 const char *buf, size_t count) 460 582 { 461 - int new_value, ret; 462 583 struct bonding *bond = to_bond(d); 584 + int ret; 463 585 464 - if (sscanf(buf, "%d", &new_value) != 1) { 465 - pr_err("%s: no down delay value specified.\n", bond->dev->name); 466 - return -EINVAL; 467 - } 468 - 469 - if (!rtnl_trylock()) 470 - return restart_syscall(); 471 - 472 - ret = bond_option_downdelay_set(bond, new_value); 586 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_DOWNDELAY, (char *)buf); 473 587 if (!ret) 474 588 ret = count; 475 589 476 - rtnl_unlock(); 477 590 return ret; 478 591 } 479 592 static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR, ··· 484 615 struct device_attribute *attr, 485 616 const char *buf, size_t count) 486 617 { 487 - int new_value, ret; 488 618 struct bonding *bond = to_bond(d); 619 + int ret; 489 620 490 - if (sscanf(buf, "%d", &new_value) != 1) { 491 - pr_err("%s: no up delay value specified.\n", 492 - bond->dev->name); 493 - return -EINVAL; 494 - } 495 - 496 - if (!rtnl_trylock()) 497 - return restart_syscall(); 498 - 499 - ret = bond_option_updelay_set(bond, new_value); 621 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_UPDELAY, (char *)buf); 500 622 if (!ret) 501 623 ret = count; 502 624 503 - rtnl_unlock(); 504 625 return ret; 505 626 } 506 627 static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR, ··· 505 646 char *buf) 506 647 { 507 648 struct bonding *bond = to_bond(d); 649 + struct bond_opt_value *val; 508 650 509 - return sprintf(buf, "%s %d\n", 510 - bond_lacp_tbl[bond->params.lacp_fast].modename, 511 - bond->params.lacp_fast); 651 + val = bond_opt_get_val(BOND_OPT_LACP_RATE, bond->params.lacp_fast); 652 + 653 + return sprintf(buf, "%s %d\n", val->string, bond->params.lacp_fast); 512 654 } 513 655 514 656 static ssize_t bonding_store_lacp(struct device *d, ··· 517 657 const char *buf, size_t count) 518 658 { 519 659 struct bonding *bond = to_bond(d); 520 - int new_value, ret; 660 + int ret; 521 661 522 - new_value = bond_parse_parm(buf, bond_lacp_tbl); 523 - if (new_value < 0) { 524 - pr_err("%s: Ignoring invalid LACP rate value %.*s.\n", 525 - bond->dev->name, (int)strlen(buf) - 1, buf); 526 - return -EINVAL; 527 - } 528 - 529 - if (!rtnl_trylock()) 530 - return restart_syscall(); 531 - 532 - ret = bond_option_lacp_rate_set(bond, new_value); 662 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_LACP_RATE, (char *)buf); 533 663 if (!ret) 534 664 ret = count; 535 665 536 - rtnl_unlock(); 537 666 return ret; 538 667 } 539 668 static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, ··· 543 694 { 544 695 struct bonding *bond = to_bond(d); 545 696 int ret; 546 - unsigned int new_value; 547 697 548 - ret = kstrtouint(buf, 0, &new_value); 549 - if (ret < 0) { 550 - pr_err("%s: Ignoring invalid min links value %s.\n", 551 - bond->dev->name, buf); 552 - return ret; 553 - } 554 - 555 - if (!rtnl_trylock()) 556 - return restart_syscall(); 557 - 558 - ret = bond_option_min_links_set(bond, new_value); 698 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MINLINKS, (char *)buf); 559 699 if (!ret) 560 700 ret = count; 561 701 562 - rtnl_unlock(); 563 702 return ret; 564 703 } 565 704 static DEVICE_ATTR(min_links, S_IRUGO | S_IWUSR, ··· 558 721 char *buf) 559 722 { 560 723 struct bonding *bond = to_bond(d); 724 + struct bond_opt_value *val; 561 725 562 - return sprintf(buf, "%s %d\n", 563 - ad_select_tbl[bond->params.ad_select].modename, 564 - bond->params.ad_select); 726 + val = bond_opt_get_val(BOND_OPT_AD_SELECT, bond->params.ad_select); 727 + 728 + return sprintf(buf, "%s %d\n", val->string, bond->params.ad_select); 565 729 } 566 730 567 731 ··· 570 732 struct device_attribute *attr, 571 733 const char *buf, size_t count) 572 734 { 573 - int new_value, ret; 574 735 struct bonding *bond = to_bond(d); 736 + int ret; 575 737 576 - new_value = bond_parse_parm(buf, ad_select_tbl); 577 - if (new_value < 0) { 578 - pr_err("%s: Ignoring invalid ad_select value %.*s.\n", 579 - bond->dev->name, (int)strlen(buf) - 1, buf); 580 - return -EINVAL; 581 - } 582 - 583 - if (!rtnl_trylock()) 584 - return restart_syscall(); 585 - 586 - ret = bond_option_ad_select_set(bond, new_value); 738 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_AD_SELECT, (char *)buf); 587 739 if (!ret) 588 740 ret = count; 589 741 590 - rtnl_unlock(); 591 742 return ret; 592 743 } 593 744 static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR, ··· 598 771 const char *buf, size_t count) 599 772 { 600 773 struct bonding *bond = to_bond(d); 601 - u8 new_value; 602 774 int ret; 603 775 604 - ret = kstrtou8(buf, 10, &new_value); 605 - if (ret) { 606 - pr_err("%s: invalid value %s specified.\n", 607 - bond->dev->name, buf); 608 - return ret; 609 - } 610 - 611 - if (!rtnl_trylock()) 612 - return restart_syscall(); 613 - 614 - ret = bond_option_num_peer_notif_set(bond, new_value); 776 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_NUM_PEER_NOTIF, (char *)buf); 615 777 if (!ret) 616 778 ret = count; 617 779 618 - rtnl_unlock(); 619 780 return ret; 620 781 } 621 782 static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, ··· 630 815 struct device_attribute *attr, 631 816 const char *buf, size_t count) 632 817 { 633 - int new_value, ret; 634 818 struct bonding *bond = to_bond(d); 819 + int ret; 635 820 636 - if (sscanf(buf, "%d", &new_value) != 1) { 637 - pr_err("%s: no miimon value specified.\n", 638 - bond->dev->name); 639 - return -EINVAL; 640 - } 641 - 642 - if (!rtnl_trylock()) 643 - return restart_syscall(); 644 - 645 - ret = bond_option_miimon_set(bond, new_value); 821 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_MIIMON, (char *)buf); 646 822 if (!ret) 647 823 ret = count; 648 824 649 - rtnl_unlock(); 650 825 return ret; 651 826 } 652 827 static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, ··· 667 862 const char *buf, size_t count) 668 863 { 669 864 struct bonding *bond = to_bond(d); 670 - char ifname[IFNAMSIZ]; 671 865 int ret; 672 866 673 - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ 674 - if (ifname[0] == '\n') 675 - ifname[0] = '\0'; 676 - 677 - if (!rtnl_trylock()) 678 - return restart_syscall(); 679 - 680 - ret = bond_option_primary_set(bond, ifname); 867 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PRIMARY, (char *)buf); 681 868 if (!ret) 682 869 ret = count; 683 870 684 - rtnl_unlock(); 685 871 return ret; 686 872 } 687 873 static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, ··· 686 890 char *buf) 687 891 { 688 892 struct bonding *bond = to_bond(d); 893 + struct bond_opt_value *val; 894 + 895 + val = bond_opt_get_val(BOND_OPT_PRIMARY_RESELECT, 896 + bond->params.primary_reselect); 689 897 690 898 return sprintf(buf, "%s %d\n", 691 - pri_reselect_tbl[bond->params.primary_reselect].modename, 692 - bond->params.primary_reselect); 899 + val->string, bond->params.primary_reselect); 693 900 } 694 901 695 902 static ssize_t bonding_store_primary_reselect(struct device *d, 696 903 struct device_attribute *attr, 697 904 const char *buf, size_t count) 698 905 { 699 - int new_value, ret; 700 906 struct bonding *bond = to_bond(d); 907 + int ret; 701 908 702 - new_value = bond_parse_parm(buf, pri_reselect_tbl); 703 - if (new_value < 0) { 704 - pr_err("%s: Ignoring invalid primary_reselect value %.*s.\n", 705 - bond->dev->name, 706 - (int) strlen(buf) - 1, buf); 707 - return -EINVAL; 708 - } 709 - 710 - if (!rtnl_trylock()) 711 - return restart_syscall(); 712 - 713 - ret = bond_option_primary_reselect_set(bond, new_value); 909 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PRIMARY_RESELECT, 910 + (char *)buf); 714 911 if (!ret) 715 912 ret = count; 716 913 717 - rtnl_unlock(); 718 914 return ret; 719 915 } 720 916 static DEVICE_ATTR(primary_reselect, S_IRUGO | S_IWUSR, ··· 729 941 struct device_attribute *attr, 730 942 const char *buf, size_t count) 731 943 { 732 - int new_value, ret; 733 944 struct bonding *bond = to_bond(d); 945 + int ret; 734 946 735 - if (sscanf(buf, "%d", &new_value) != 1) { 736 - pr_err("%s: no use_carrier value specified.\n", 737 - bond->dev->name); 738 - return -EINVAL; 739 - } 740 - 741 - if (!rtnl_trylock()) 742 - return restart_syscall(); 743 - 744 - ret = bond_option_use_carrier_set(bond, new_value); 947 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_USE_CARRIER, (char *)buf); 745 948 if (!ret) 746 949 ret = count; 747 950 748 - rtnl_unlock(); 749 951 return ret; 750 952 } 751 953 static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, ··· 766 988 struct device_attribute *attr, 767 989 const char *buf, size_t count) 768 990 { 769 - int ret; 770 991 struct bonding *bond = to_bond(d); 771 - char ifname[IFNAMSIZ]; 772 - struct net_device *dev; 992 + int ret; 773 993 774 - if (!rtnl_trylock()) 775 - return restart_syscall(); 776 - 777 - sscanf(buf, "%15s", ifname); /* IFNAMSIZ */ 778 - if (!strlen(ifname) || buf[0] == '\n') { 779 - dev = NULL; 780 - } else { 781 - dev = __dev_get_by_name(dev_net(bond->dev), ifname); 782 - if (!dev) { 783 - ret = -ENODEV; 784 - goto out; 785 - } 786 - } 787 - 788 - ret = bond_option_active_slave_set(bond, dev); 994 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ACTIVE_SLAVE, (char *)buf); 789 995 if (!ret) 790 996 ret = count; 791 997 792 - out: 793 - rtnl_unlock(); 794 - 795 998 return ret; 796 - 797 999 } 798 1000 static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, 799 1001 bonding_show_active_slave, bonding_store_active_slave); ··· 942 1184 struct device_attribute *attr, 943 1185 const char *buffer, size_t count) 944 1186 { 945 - struct slave *slave, *update_slave; 946 1187 struct bonding *bond = to_bond(d); 947 - struct list_head *iter; 948 - u16 qid; 949 - int ret = count; 950 - char *delim; 951 - struct net_device *sdev = NULL; 1188 + int ret; 952 1189 953 - if (!rtnl_trylock()) 954 - return restart_syscall(); 1190 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_QUEUE_ID, (char *)buffer); 1191 + if (!ret) 1192 + ret = count; 955 1193 956 - /* delim will point to queue id if successful */ 957 - delim = strchr(buffer, ':'); 958 - if (!delim) 959 - goto err_no_cmd; 960 - 961 - /* 962 - * Terminate string that points to device name and bump it 963 - * up one, so we can read the queue id there. 964 - */ 965 - *delim = '\0'; 966 - if (sscanf(++delim, "%hd\n", &qid) != 1) 967 - goto err_no_cmd; 968 - 969 - /* Check buffer length, valid ifname and queue id */ 970 - if (strlen(buffer) > IFNAMSIZ || 971 - !dev_valid_name(buffer) || 972 - qid > bond->dev->real_num_tx_queues) 973 - goto err_no_cmd; 974 - 975 - /* Get the pointer to that interface if it exists */ 976 - sdev = __dev_get_by_name(dev_net(bond->dev), buffer); 977 - if (!sdev) 978 - goto err_no_cmd; 979 - 980 - /* Search for thes slave and check for duplicate qids */ 981 - update_slave = NULL; 982 - bond_for_each_slave(bond, slave, iter) { 983 - if (sdev == slave->dev) 984 - /* 985 - * We don't need to check the matching 986 - * slave for dups, since we're overwriting it 987 - */ 988 - update_slave = slave; 989 - else if (qid && qid == slave->queue_id) { 990 - goto err_no_cmd; 991 - } 992 - } 993 - 994 - if (!update_slave) 995 - goto err_no_cmd; 996 - 997 - /* Actually set the qids for the slave */ 998 - update_slave->queue_id = qid; 999 - 1000 - out: 1001 - rtnl_unlock(); 1002 1194 return ret; 1003 - 1004 - err_no_cmd: 1005 - pr_info("invalid input for queue_id set for %s.\n", 1006 - bond->dev->name); 1007 - ret = -EPERM; 1008 - goto out; 1009 1195 } 1010 - 1011 1196 static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id, 1012 1197 bonding_store_queue_id); 1013 1198 ··· 972 1271 const char *buf, size_t count) 973 1272 { 974 1273 struct bonding *bond = to_bond(d); 975 - int new_value, ret; 1274 + int ret; 976 1275 977 - if (sscanf(buf, "%d", &new_value) != 1) { 978 - pr_err("%s: no all_slaves_active value specified.\n", 979 - bond->dev->name); 980 - return -EINVAL; 981 - } 982 - 983 - if (!rtnl_trylock()) 984 - return restart_syscall(); 985 - 986 - ret = bond_option_all_slaves_active_set(bond, new_value); 1276 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_ALL_SLAVES_ACTIVE, 1277 + (char *)buf); 987 1278 if (!ret) 988 1279 ret = count; 989 1280 990 - rtnl_unlock(); 991 1281 return ret; 992 1282 } 993 1283 static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, ··· 1000 1308 struct device_attribute *attr, 1001 1309 const char *buf, size_t count) 1002 1310 { 1003 - int new_value, ret = count; 1004 1311 struct bonding *bond = to_bond(d); 1312 + int ret; 1005 1313 1006 - if (sscanf(buf, "%d", &new_value) != 1) { 1007 - pr_err("%s: no resend_igmp value specified.\n", 1008 - bond->dev->name); 1009 - return -EINVAL; 1010 - } 1011 - 1012 - if (!rtnl_trylock()) 1013 - return restart_syscall(); 1014 - 1015 - ret = bond_option_resend_igmp_set(bond, new_value); 1314 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_RESEND_IGMP, (char *)buf); 1016 1315 if (!ret) 1017 1316 ret = count; 1018 1317 1019 - rtnl_unlock(); 1020 1318 return ret; 1021 1319 } 1022 1320 ··· 1027 1345 const char *buf, size_t count) 1028 1346 { 1029 1347 struct bonding *bond = to_bond(d); 1030 - int new_value, ret; 1348 + int ret; 1031 1349 1032 - if (sscanf(buf, "%d", &new_value) != 1) { 1033 - pr_err("%s: no lp interval value specified.\n", 1034 - bond->dev->name); 1035 - return -EINVAL; 1036 - } 1037 - 1038 - if (!rtnl_trylock()) 1039 - return restart_syscall(); 1040 - 1041 - ret = bond_option_lp_interval_set(bond, new_value); 1350 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_LP_INTERVAL, (char *)buf); 1042 1351 if (!ret) 1043 1352 ret = count; 1044 1353 1045 - rtnl_unlock(); 1046 1354 return ret; 1047 1355 } 1048 1356 ··· 1053 1381 const char *buf, size_t count) 1054 1382 { 1055 1383 struct bonding *bond = to_bond(d); 1056 - int new_value, ret; 1384 + int ret; 1057 1385 1058 - if (sscanf(buf, "%d", &new_value) != 1) { 1059 - pr_err("%s: no packets_per_slave value specified.\n", 1060 - bond->dev->name); 1061 - return -EINVAL; 1062 - } 1063 - 1064 - if (!rtnl_trylock()) 1065 - return restart_syscall(); 1066 - 1067 - ret = bond_option_packets_per_slave_set(bond, new_value); 1386 + ret = bond_opt_tryset_rtnl(bond, BOND_OPT_PACKETS_PER_SLAVE, 1387 + (char *)buf); 1068 1388 if (!ret) 1069 1389 ret = count; 1070 1390 1071 - rtnl_unlock(); 1072 1391 return ret; 1073 1392 } 1074 1393
+1 -28
drivers/net/bonding/bonding.h
··· 27 27 28 28 #include "bond_3ad.h" 29 29 #include "bond_alb.h" 30 + #include "bond_options.h" 30 31 31 32 #define DRV_VERSION "3.7.1" 32 33 #define DRV_RELDATE "April 27, 2011" ··· 452 451 unsigned int bond_get_num_tx_queues(void); 453 452 int bond_netlink_init(void); 454 453 void bond_netlink_fini(void); 455 - int bond_option_mode_set(struct bonding *bond, int mode); 456 - int bond_option_active_slave_set(struct bonding *bond, struct net_device *slave_dev); 457 - int bond_option_miimon_set(struct bonding *bond, int miimon); 458 - int bond_option_updelay_set(struct bonding *bond, int updelay); 459 - int bond_option_downdelay_set(struct bonding *bond, int downdelay); 460 - int bond_option_use_carrier_set(struct bonding *bond, int use_carrier); 461 - int bond_option_arp_interval_set(struct bonding *bond, int arp_interval); 462 - int bond_option_arp_ip_targets_set(struct bonding *bond, __be32 *targets, 463 - int count); 464 454 int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target); 465 455 int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target); 466 - int bond_option_arp_validate_set(struct bonding *bond, int arp_validate); 467 - int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets); 468 - int bond_option_primary_set(struct bonding *bond, const char *primary); 469 - int bond_option_primary_reselect_set(struct bonding *bond, 470 - int primary_reselect); 471 - int bond_option_fail_over_mac_set(struct bonding *bond, int fail_over_mac); 472 - int bond_option_xmit_hash_policy_set(struct bonding *bond, 473 - int xmit_hash_policy); 474 - int bond_option_resend_igmp_set(struct bonding *bond, int resend_igmp); 475 - int bond_option_num_peer_notif_set(struct bonding *bond, int num_peer_notif); 476 - int bond_option_all_slaves_active_set(struct bonding *bond, 477 - int all_slaves_active); 478 - int bond_option_min_links_set(struct bonding *bond, int min_links); 479 - int bond_option_lp_interval_set(struct bonding *bond, int min_links); 480 - int bond_option_packets_per_slave_set(struct bonding *bond, 481 - int packets_per_slave); 482 - int bond_option_lacp_rate_set(struct bonding *bond, int lacp_rate); 483 - int bond_option_ad_select_set(struct bonding *bond, int ad_select); 484 456 struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); 485 457 struct net_device *bond_option_active_slave_get(struct bonding *bond); 486 458 const char *bond_slave_link_status(s8 link); ··· 536 562 /* exported from bond_main.c */ 537 563 extern int bond_net_id; 538 564 extern const struct bond_parm_tbl bond_lacp_tbl[]; 539 - extern const struct bond_parm_tbl bond_mode_tbl[]; 540 565 extern const struct bond_parm_tbl xmit_hashtype_tbl[]; 541 566 extern const struct bond_parm_tbl arp_validate_tbl[]; 542 567 extern const struct bond_parm_tbl arp_all_targets_tbl[];