Merge branch 'reciprocal'
[deliverable/linux.git] / drivers / net / bonding / bond_options.c
CommitLineData
72be35fe
JP
1/*
2 * drivers/net/bond/bond_options.c - bonding options
3 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
eecdaa6e 4 * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
72be35fe
JP
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#include <linux/errno.h>
15#include <linux/if.h>
d9e32b21
JP
16#include <linux/netdevice.h>
17#include <linux/rwlock.h>
18#include <linux/rcupdate.h>
72be35fe
JP
19#include "bonding.h"
20
72be35fe
JP
21int bond_option_mode_set(struct bonding *bond, int mode)
22{
3243c47b 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);
72be35fe
JP
26 return -EINVAL;
27 }
28
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 }
34
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;
39 }
40
fe9d04af 41 if (BOND_NO_USES_ARP(mode) && bond->params.arp_interval) {
42 pr_info("%s: %s mode is incompatible with arp monitoring, start mii monitoring\n",
43 bond->dev->name, bond_mode_tbl[mode].modename);
44 /* disable arp monitoring */
45 bond->params.arp_interval = 0;
46 /* set miimon to default value */
47 bond->params.miimon = BOND_DEFAULT_MIIMON;
48 pr_info("%s: Setting MII monitoring interval to %d.\n",
49 bond->dev->name, bond->params.miimon);
72be35fe
JP
50 }
51
52 /* don't cache arp_validate between modes */
53 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
54 bond->params.mode = mode;
55 return 0;
56}
d9e32b21 57
752d48b5
JP
58static struct net_device *__bond_option_active_slave_get(struct bonding *bond,
59 struct slave *slave)
60{
61 return USES_PRIMARY(bond->params.mode) && slave ? slave->dev : NULL;
62}
63
64struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
65{
66 struct slave *slave = rcu_dereference(bond->curr_active_slave);
67
68 return __bond_option_active_slave_get(bond, slave);
69}
70
71struct net_device *bond_option_active_slave_get(struct bonding *bond)
72{
73 return __bond_option_active_slave_get(bond, bond->curr_active_slave);
74}
75
d9e32b21
JP
76int bond_option_active_slave_set(struct bonding *bond,
77 struct net_device *slave_dev)
78{
79 int ret = 0;
80
81 if (slave_dev) {
82 if (!netif_is_bond_slave(slave_dev)) {
83 pr_err("Device %s is not bonding slave.\n",
84 slave_dev->name);
85 return -EINVAL;
86 }
87
88 if (bond->dev != netdev_master_upper_dev_get(slave_dev)) {
89 pr_err("%s: Device %s is not our slave.\n",
90 bond->dev->name, slave_dev->name);
91 return -EINVAL;
92 }
93 }
94
95 if (!USES_PRIMARY(bond->params.mode)) {
96 pr_err("%s: Unable to change active slave; %s is in mode %d\n",
97 bond->dev->name, bond->dev->name, bond->params.mode);
98 return -EINVAL;
99 }
100
101 block_netpoll_tx();
d9e32b21
JP
102 write_lock_bh(&bond->curr_slave_lock);
103
104 /* check to see if we are clearing active */
105 if (!slave_dev) {
106 pr_info("%s: Clearing current active slave.\n",
107 bond->dev->name);
108 rcu_assign_pointer(bond->curr_active_slave, NULL);
109 bond_select_active_slave(bond);
110 } else {
111 struct slave *old_active = bond->curr_active_slave;
112 struct slave *new_active = bond_slave_get_rtnl(slave_dev);
113
114 BUG_ON(!new_active);
115
116 if (new_active == old_active) {
117 /* do nothing */
118 pr_info("%s: %s is already the current active slave.\n",
119 bond->dev->name, new_active->dev->name);
120 } else {
121 if (old_active && (new_active->link == BOND_LINK_UP) &&
122 IS_UP(new_active->dev)) {
123 pr_info("%s: Setting %s as active slave.\n",
124 bond->dev->name, new_active->dev->name);
125 bond_change_active_slave(bond, new_active);
126 } else {
127 pr_err("%s: Could not set %s as active slave; either %s is down or the link is down.\n",
128 bond->dev->name, new_active->dev->name,
129 new_active->dev->name);
130 ret = -EINVAL;
131 }
132 }
133 }
134
135 write_unlock_bh(&bond->curr_slave_lock);
d9e32b21
JP
136 unblock_netpoll_tx();
137 return ret;
138}
eecdaa6e 139
140int bond_option_miimon_set(struct bonding *bond, int miimon)
141{
142 if (miimon < 0) {
143 pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n",
144 bond->dev->name, miimon, 0, INT_MAX);
145 return -EINVAL;
146 }
147 pr_info("%s: Setting MII monitoring interval to %d.\n",
148 bond->dev->name, miimon);
149 bond->params.miimon = miimon;
150 if (bond->params.updelay)
151 pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n",
152 bond->dev->name,
153 bond->params.updelay * bond->params.miimon);
154 if (bond->params.downdelay)
155 pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n",
156 bond->dev->name,
157 bond->params.downdelay * bond->params.miimon);
158 if (miimon && bond->params.arp_interval) {
159 pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n",
160 bond->dev->name);
161 bond->params.arp_interval = 0;
162 if (bond->params.arp_validate)
163 bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
164 }
165 if (bond->dev->flags & IFF_UP) {
166 /* If the interface is up, we may need to fire off
167 * the MII timer. If the interface is down, the
168 * timer will get fired off when the open function
169 * is called.
170 */
171 if (!miimon) {
172 cancel_delayed_work_sync(&bond->mii_work);
173 } else {
174 cancel_delayed_work_sync(&bond->arp_work);
175 queue_delayed_work(bond->wq, &bond->mii_work, 0);
176 }
177 }
178 return 0;
179}
25852e29 180
181int bond_option_updelay_set(struct bonding *bond, int updelay)
182{
183 if (!(bond->params.miimon)) {
184 pr_err("%s: Unable to set up delay as MII monitoring is disabled\n",
185 bond->dev->name);
186 return -EPERM;
187 }
188
189 if (updelay < 0) {
190 pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n",
191 bond->dev->name, updelay, 0, INT_MAX);
192 return -EINVAL;
193 } else {
194 if ((updelay % bond->params.miimon) != 0) {
195 pr_warn("%s: Warning: up delay (%d) is not a multiple of miimon (%d), updelay rounded to %d ms\n",
196 bond->dev->name, updelay,
197 bond->params.miimon,
198 (updelay / bond->params.miimon) *
199 bond->params.miimon);
200 }
201 bond->params.updelay = updelay / bond->params.miimon;
202 pr_info("%s: Setting up delay to %d.\n",
203 bond->dev->name,
204 bond->params.updelay * bond->params.miimon);
205 }
206
207 return 0;
208}
c7461f9b 209
210int bond_option_downdelay_set(struct bonding *bond, int downdelay)
211{
212 if (!(bond->params.miimon)) {
213 pr_err("%s: Unable to set down delay as MII monitoring is disabled\n",
214 bond->dev->name);
215 return -EPERM;
216 }
217
218 if (downdelay < 0) {
219 pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n",
220 bond->dev->name, downdelay, 0, INT_MAX);
221 return -EINVAL;
222 } else {
223 if ((downdelay % bond->params.miimon) != 0) {
224 pr_warn("%s: Warning: down delay (%d) is not a multiple of miimon (%d), delay rounded to %d ms\n",
225 bond->dev->name, downdelay,
226 bond->params.miimon,
227 (downdelay / bond->params.miimon) *
228 bond->params.miimon);
229 }
230 bond->params.downdelay = downdelay / bond->params.miimon;
231 pr_info("%s: Setting down delay to %d.\n",
232 bond->dev->name,
233 bond->params.downdelay * bond->params.miimon);
234 }
235
236 return 0;
237}
9f53e14e 238
239int bond_option_use_carrier_set(struct bonding *bond, int use_carrier)
240{
241 if ((use_carrier == 0) || (use_carrier == 1)) {
242 bond->params.use_carrier = use_carrier;
243 pr_info("%s: Setting use_carrier to %d.\n",
244 bond->dev->name, use_carrier);
245 } else {
246 pr_info("%s: Ignoring invalid use_carrier value %d.\n",
247 bond->dev->name, use_carrier);
248 }
249
250 return 0;
251}
06151dbc 252
253int bond_option_arp_interval_set(struct bonding *bond, int arp_interval)
254{
255 if (arp_interval < 0) {
256 pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n",
257 bond->dev->name, arp_interval, INT_MAX);
258 return -EINVAL;
259 }
260 if (BOND_NO_USES_ARP(bond->params.mode)) {
261 pr_info("%s: ARP monitoring cannot be used with ALB/TLB/802.3ad. Only MII monitoring is supported on %s.\n",
262 bond->dev->name, bond->dev->name);
263 return -EINVAL;
264 }
265 pr_info("%s: Setting ARP monitoring interval to %d.\n",
266 bond->dev->name, arp_interval);
267 bond->params.arp_interval = arp_interval;
268 if (arp_interval) {
269 if (bond->params.miimon) {
270 pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n",
271 bond->dev->name, bond->dev->name);
272 bond->params.miimon = 0;
273 }
274 if (!bond->params.arp_targets[0])
275 pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n",
276 bond->dev->name);
277 }
278 if (bond->dev->flags & IFF_UP) {
279 /* If the interface is up, we may need to fire off
280 * the ARP timer. If the interface is down, the
281 * timer will get fired off when the open function
282 * is called.
283 */
284 if (!arp_interval) {
285 if (bond->params.arp_validate)
286 bond->recv_probe = NULL;
287 cancel_delayed_work_sync(&bond->arp_work);
288 } else {
289 /* arp_validate can be set only in active-backup mode */
290 if (bond->params.arp_validate)
291 bond->recv_probe = bond_arp_rcv;
292 cancel_delayed_work_sync(&bond->mii_work);
293 queue_delayed_work(bond->wq, &bond->arp_work, 0);
294 }
295 }
296
297 return 0;
298}
7f28fa10 299
300static void _bond_options_arp_ip_target_set(struct bonding *bond, int slot,
301 __be32 target,
302 unsigned long last_rx)
303{
304 __be32 *targets = bond->params.arp_targets;
305 struct list_head *iter;
306 struct slave *slave;
307
308 if (slot >= 0 && slot < BOND_MAX_ARP_TARGETS) {
309 bond_for_each_slave(bond, slave, iter)
310 slave->target_last_arp_rx[slot] = last_rx;
311 targets[slot] = target;
312 }
313}
314
315static int _bond_option_arp_ip_target_add(struct bonding *bond, __be32 target)
316{
317 __be32 *targets = bond->params.arp_targets;
318 int ind;
319
320 if (IS_IP_TARGET_UNUSABLE_ADDRESS(target)) {
321 pr_err("%s: invalid ARP target %pI4 specified for addition\n",
322 bond->dev->name, &target);
323 return -EINVAL;
324 }
325
326 if (bond_get_targets_ip(targets, target) != -1) { /* dup */
327 pr_err("%s: ARP target %pI4 is already present\n",
328 bond->dev->name, &target);
329 return -EINVAL;
330 }
331
332 ind = bond_get_targets_ip(targets, 0); /* first free slot */
333 if (ind == -1) {
334 pr_err("%s: ARP target table is full!\n",
335 bond->dev->name);
336 return -EINVAL;
337 }
338
339 pr_info("%s: adding ARP target %pI4.\n", bond->dev->name, &target);
340
341 _bond_options_arp_ip_target_set(bond, ind, target, jiffies);
342
343 return 0;
344}
345
346int bond_option_arp_ip_target_add(struct bonding *bond, __be32 target)
347{
348 int ret;
349
350 /* not to race with bond_arp_rcv */
351 write_lock_bh(&bond->lock);
352 ret = _bond_option_arp_ip_target_add(bond, target);
353 write_unlock_bh(&bond->lock);
354
355 return ret;
356}
357
358int bond_option_arp_ip_target_rem(struct bonding *bond, __be32 target)
359{
360 __be32 *targets = bond->params.arp_targets;
361 struct list_head *iter;
362 struct slave *slave;
363 unsigned long *targets_rx;
364 int ind, i;
365
366 if (IS_IP_TARGET_UNUSABLE_ADDRESS(target)) {
367 pr_err("%s: invalid ARP target %pI4 specified for removal\n",
368 bond->dev->name, &target);
369 return -EINVAL;
370 }
371
372 ind = bond_get_targets_ip(targets, target);
373 if (ind == -1) {
374 pr_err("%s: unable to remove nonexistent ARP target %pI4.\n",
375 bond->dev->name, &target);
376 return -EINVAL;
377 }
378
379 if (ind == 0 && !targets[1] && bond->params.arp_interval)
380 pr_warn("%s: removing last arp target with arp_interval on\n",
381 bond->dev->name);
382
383 pr_info("%s: removing ARP target %pI4.\n", bond->dev->name,
384 &target);
385
386 /* not to race with bond_arp_rcv */
387 write_lock_bh(&bond->lock);
388
389 bond_for_each_slave(bond, slave, iter) {
390 targets_rx = slave->target_last_arp_rx;
391 for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
392 targets_rx[i] = targets_rx[i+1];
393 targets_rx[i] = 0;
394 }
395 for (i = ind; (i < BOND_MAX_ARP_TARGETS-1) && targets[i+1]; i++)
396 targets[i] = targets[i+1];
397 targets[i] = 0;
398
399 write_unlock_bh(&bond->lock);
400
401 return 0;
402}
403
404int bond_option_arp_ip_targets_set(struct bonding *bond, __be32 *targets,
405 int count)
406{
407 int i, ret = 0;
408
409 /* not to race with bond_arp_rcv */
410 write_lock_bh(&bond->lock);
411
412 /* clear table */
413 for (i = 0; i < BOND_MAX_ARP_TARGETS; i++)
414 _bond_options_arp_ip_target_set(bond, i, 0, 0);
415
416 if (count == 0 && bond->params.arp_interval)
417 pr_warn("%s: removing last arp target with arp_interval on\n",
418 bond->dev->name);
419
420 for (i = 0; i < count; i++) {
421 ret = _bond_option_arp_ip_target_add(bond, targets[i]);
422 if (ret)
423 break;
424 }
425
426 write_unlock_bh(&bond->lock);
427 return ret;
428}
29c49482 429
430int bond_option_arp_validate_set(struct bonding *bond, int arp_validate)
431{
3243c47b 432 if (bond_parm_tbl_lookup(arp_validate, arp_validate_tbl) < 0) {
433 pr_err("%s: Ignoring invalid arp_validate value %d.\n",
434 bond->dev->name, arp_validate);
435 return -EINVAL;
436 }
437
29c49482 438 if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
439 pr_err("%s: arp_validate only supported in active-backup mode.\n",
440 bond->dev->name);
441 return -EINVAL;
442 }
3243c47b 443
29c49482 444 pr_info("%s: setting arp_validate to %s (%d).\n",
445 bond->dev->name, arp_validate_tbl[arp_validate].modename,
446 arp_validate);
447
448 if (bond->dev->flags & IFF_UP) {
449 if (!arp_validate)
450 bond->recv_probe = NULL;
451 else if (bond->params.arp_interval)
452 bond->recv_probe = bond_arp_rcv;
453 }
454 bond->params.arp_validate = arp_validate;
455
456 return 0;
457}
d5c84254 458
459int bond_option_arp_all_targets_set(struct bonding *bond, int arp_all_targets)
460{
3243c47b 461 if (bond_parm_tbl_lookup(arp_all_targets, arp_all_targets_tbl) < 0) {
462 pr_err("%s: Ignoring invalid arp_all_targets value %d.\n",
463 bond->dev->name, arp_all_targets);
464 return -EINVAL;
465 }
466
d5c84254 467 pr_info("%s: setting arp_all_targets to %s (%d).\n",
468 bond->dev->name, arp_all_targets_tbl[arp_all_targets].modename,
469 arp_all_targets);
470
471 bond->params.arp_all_targets = arp_all_targets;
472
473 return 0;
474}
0a98a0d1 475
476int bond_option_primary_set(struct bonding *bond, const char *primary)
477{
478 struct list_head *iter;
479 struct slave *slave;
480 int err = 0;
481
482 block_netpoll_tx();
483 read_lock(&bond->lock);
484 write_lock_bh(&bond->curr_slave_lock);
485
486 if (!USES_PRIMARY(bond->params.mode)) {
487 pr_err("%s: Unable to set primary slave; %s is in mode %d\n",
488 bond->dev->name, bond->dev->name, bond->params.mode);
489 err = -EINVAL;
490 goto out;
491 }
492
493 /* check to see if we are clearing primary */
494 if (!strlen(primary)) {
495 pr_info("%s: Setting primary slave to None.\n",
496 bond->dev->name);
497 bond->primary_slave = NULL;
498 memset(bond->params.primary, 0, sizeof(bond->params.primary));
499 bond_select_active_slave(bond);
500 goto out;
501 }
502
503 bond_for_each_slave(bond, slave, iter) {
504 if (strncmp(slave->dev->name, primary, IFNAMSIZ) == 0) {
505 pr_info("%s: Setting %s as primary slave.\n",
506 bond->dev->name, slave->dev->name);
507 bond->primary_slave = slave;
508 strcpy(bond->params.primary, slave->dev->name);
509 bond_select_active_slave(bond);
510 goto out;
511 }
512 }
513
514 strncpy(bond->params.primary, primary, IFNAMSIZ);
515 bond->params.primary[IFNAMSIZ - 1] = 0;
516
517 pr_info("%s: Recording %s as primary, but it has not been enslaved to %s yet.\n",
518 bond->dev->name, primary, bond->dev->name);
519
520out:
521 write_unlock_bh(&bond->curr_slave_lock);
522 read_unlock(&bond->lock);
523 unblock_netpoll_tx();
524
525 return err;
526}
8a41ae44 527
528int bond_option_primary_reselect_set(struct bonding *bond, int primary_reselect)
529{
3243c47b 530 if (bond_parm_tbl_lookup(primary_reselect, pri_reselect_tbl) < 0) {
531 pr_err("%s: Ignoring invalid primary_reselect value %d.\n",
532 bond->dev->name, primary_reselect);
533 return -EINVAL;
534 }
535
8a41ae44 536 bond->params.primary_reselect = primary_reselect;
537 pr_info("%s: setting primary_reselect to %s (%d).\n",
538 bond->dev->name, pri_reselect_tbl[primary_reselect].modename,
539 primary_reselect);
540
541 block_netpoll_tx();
542 write_lock_bh(&bond->curr_slave_lock);
543 bond_select_active_slave(bond);
544 write_unlock_bh(&bond->curr_slave_lock);
545 unblock_netpoll_tx();
546
547 return 0;
548}
89901972 549
550int bond_option_fail_over_mac_set(struct bonding *bond, int fail_over_mac)
551{
3243c47b 552 if (bond_parm_tbl_lookup(fail_over_mac, fail_over_mac_tbl) < 0) {
553 pr_err("%s: Ignoring invalid fail_over_mac value %d.\n",
554 bond->dev->name, fail_over_mac);
555 return -EINVAL;
556 }
557
89901972 558 if (bond_has_slaves(bond)) {
559 pr_err("%s: Can't alter fail_over_mac with slaves in bond.\n",
560 bond->dev->name);
561 return -EPERM;
562 }
563
564 bond->params.fail_over_mac = fail_over_mac;
565 pr_info("%s: Setting fail_over_mac to %s (%d).\n",
566 bond->dev->name, fail_over_mac_tbl[fail_over_mac].modename,
567 fail_over_mac);
568
569 return 0;
570}
f70161c6 571
572int bond_option_xmit_hash_policy_set(struct bonding *bond, int xmit_hash_policy)
573{
3243c47b 574 if (bond_parm_tbl_lookup(xmit_hash_policy, xmit_hashtype_tbl) < 0) {
575 pr_err("%s: Ignoring invalid xmit_hash_policy value %d.\n",
576 bond->dev->name, xmit_hash_policy);
577 return -EINVAL;
578 }
579
f70161c6 580 bond->params.xmit_policy = xmit_hash_policy;
581 pr_info("%s: setting xmit hash policy to %s (%d).\n",
582 bond->dev->name,
583 xmit_hashtype_tbl[xmit_hash_policy].modename, xmit_hash_policy);
584
585 return 0;
586}
d8838de7 587
588int bond_option_resend_igmp_set(struct bonding *bond, int resend_igmp)
589{
590 if (resend_igmp < 0 || resend_igmp > 255) {
591 pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n",
592 bond->dev->name, resend_igmp);
593 return -EINVAL;
594 }
595
596 bond->params.resend_igmp = resend_igmp;
597 pr_info("%s: Setting resend_igmp to %d.\n",
598 bond->dev->name, resend_igmp);
599
600 return 0;
601}
2c9839c1 602
603int bond_option_num_peer_notif_set(struct bonding *bond, int num_peer_notif)
604{
605 bond->params.num_peer_notif = num_peer_notif;
606 return 0;
607}
1cc0b1e3 608
609int bond_option_all_slaves_active_set(struct bonding *bond,
610 int all_slaves_active)
611{
612 struct list_head *iter;
613 struct slave *slave;
614
615 if (all_slaves_active == bond->params.all_slaves_active)
616 return 0;
617
618 if ((all_slaves_active == 0) || (all_slaves_active == 1)) {
619 bond->params.all_slaves_active = all_slaves_active;
620 } else {
621 pr_info("%s: Ignoring invalid all_slaves_active value %d.\n",
622 bond->dev->name, all_slaves_active);
623 return -EINVAL;
624 }
625
626 bond_for_each_slave(bond, slave, iter) {
627 if (!bond_is_active_slave(slave)) {
628 if (all_slaves_active)
629 slave->inactive = 0;
630 else
631 slave->inactive = 1;
632 }
633 }
634
635 return 0;
636}
7d101008 637
638int bond_option_min_links_set(struct bonding *bond, int min_links)
639{
640 pr_info("%s: Setting min links value to %u\n",
641 bond->dev->name, min_links);
642 bond->params.min_links = min_links;
643
644 return 0;
645}
8d836d09 646
647int bond_option_lp_interval_set(struct bonding *bond, int lp_interval)
648{
649 if (lp_interval <= 0) {
650 pr_err("%s: lp_interval must be between 1 and %d\n",
651 bond->dev->name, INT_MAX);
652 return -EINVAL;
653 }
654
655 bond->params.lp_interval = lp_interval;
656
657 return 0;
658}
c13ab3ff 659
660int bond_option_packets_per_slave_set(struct bonding *bond,
661 int packets_per_slave)
662{
663 if (packets_per_slave < 0 || packets_per_slave > USHRT_MAX) {
664 pr_err("%s: packets_per_slave must be between 0 and %u\n",
665 bond->dev->name, USHRT_MAX);
666 return -EINVAL;
667 }
668
669 if (bond->params.mode != BOND_MODE_ROUNDROBIN)
670 pr_warn("%s: Warning: packets_per_slave has effect only in balance-rr mode\n",
671 bond->dev->name);
672
809fa972
HFS
673 bond->params.packets_per_slave = packets_per_slave;
674 if (packets_per_slave > 0) {
675 bond->params.reciprocal_packets_per_slave =
c13ab3ff 676 reciprocal_value(packets_per_slave);
809fa972
HFS
677 } else {
678 /* reciprocal_packets_per_slave is unused if
679 * packets_per_slave is 0 or 1, just initialize it
680 */
681 bond->params.reciprocal_packets_per_slave =
682 (struct reciprocal_value) { 0 };
683 }
c13ab3ff 684
685 return 0;
686}
998e40bb 687
688int bond_option_lacp_rate_set(struct bonding *bond, int lacp_rate)
689{
3243c47b 690 if (bond_parm_tbl_lookup(lacp_rate, bond_lacp_tbl) < 0) {
691 pr_err("%s: Ignoring invalid LACP rate value %d.\n",
692 bond->dev->name, lacp_rate);
693 return -EINVAL;
694 }
695
998e40bb 696 if (bond->dev->flags & IFF_UP) {
697 pr_err("%s: Unable to update LACP rate because interface is up.\n",
698 bond->dev->name);
699 return -EPERM;
700 }
701
702 if (bond->params.mode != BOND_MODE_8023AD) {
703 pr_err("%s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
704 bond->dev->name);
705 return -EPERM;
706 }
707
3243c47b 708 bond->params.lacp_fast = lacp_rate;
709 bond_3ad_update_lacp_rate(bond);
710 pr_info("%s: Setting LACP rate to %s (%d).\n",
711 bond->dev->name, bond_lacp_tbl[lacp_rate].modename,
712 lacp_rate);
998e40bb 713
714 return 0;
715}
ec029fac 716
717int bond_option_ad_select_set(struct bonding *bond, int ad_select)
718{
ec029fac 719 if (bond_parm_tbl_lookup(ad_select, ad_select_tbl) < 0) {
720 pr_err("%s: Ignoring invalid ad_select value %d.\n",
721 bond->dev->name, ad_select);
722 return -EINVAL;
723 }
724
3243c47b 725 if (bond->dev->flags & IFF_UP) {
726 pr_err("%s: Unable to update ad_select because interface is up.\n",
727 bond->dev->name);
728 return -EPERM;
729 }
730
ec029fac 731 bond->params.ad_select = ad_select;
732 pr_info("%s: Setting ad_select to %s (%d).\n",
733 bond->dev->name, ad_select_tbl[ad_select].modename,
734 ad_select);
735
736 return 0;
737}
This page took 0.078727 seconds and 5 git commands to generate.