bond_options.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * drivers/net/bond/bond_options.c - bonding options
  3. * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
  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. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  11. #include <linux/errno.h>
  12. #include <linux/if.h>
  13. #include <linux/netdevice.h>
  14. #include <linux/rwlock.h>
  15. #include <linux/rcupdate.h>
  16. #include "bonding.h"
  17. static bool bond_mode_is_valid(int mode)
  18. {
  19. int i;
  20. for (i = 0; bond_mode_tbl[i].modename; i++);
  21. return mode >= 0 && mode < i;
  22. }
  23. int bond_option_mode_set(struct bonding *bond, int mode)
  24. {
  25. if (!bond_mode_is_valid(mode)) {
  26. pr_err("invalid mode value %d.\n", mode);
  27. return -EINVAL;
  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. if (bond_has_slaves(bond)) {
  35. pr_err("%s: unable to update mode because bond has slaves.\n",
  36. bond->dev->name);
  37. return -EPERM;
  38. }
  39. if (BOND_MODE_IS_LB(mode) && bond->params.arp_interval) {
  40. pr_err("%s: %s mode is incompatible with arp monitoring.\n",
  41. bond->dev->name, bond_mode_tbl[mode].modename);
  42. return -EINVAL;
  43. }
  44. /* don't cache arp_validate between modes */
  45. bond->params.arp_validate = BOND_ARP_VALIDATE_NONE;
  46. bond->params.mode = mode;
  47. return 0;
  48. }
  49. static struct net_device *__bond_option_active_slave_get(struct bonding *bond,
  50. struct slave *slave)
  51. {
  52. return USES_PRIMARY(bond->params.mode) && slave ? slave->dev : NULL;
  53. }
  54. struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond)
  55. {
  56. struct slave *slave = rcu_dereference(bond->curr_active_slave);
  57. return __bond_option_active_slave_get(bond, slave);
  58. }
  59. struct net_device *bond_option_active_slave_get(struct bonding *bond)
  60. {
  61. return __bond_option_active_slave_get(bond, bond->curr_active_slave);
  62. }
  63. int bond_option_active_slave_set(struct bonding *bond,
  64. struct net_device *slave_dev)
  65. {
  66. int ret = 0;
  67. if (slave_dev) {
  68. if (!netif_is_bond_slave(slave_dev)) {
  69. pr_err("Device %s is not bonding slave.\n",
  70. slave_dev->name);
  71. return -EINVAL;
  72. }
  73. if (bond->dev != netdev_master_upper_dev_get(slave_dev)) {
  74. pr_err("%s: Device %s is not our slave.\n",
  75. bond->dev->name, slave_dev->name);
  76. return -EINVAL;
  77. }
  78. }
  79. if (!USES_PRIMARY(bond->params.mode)) {
  80. pr_err("%s: Unable to change active slave; %s is in mode %d\n",
  81. bond->dev->name, bond->dev->name, bond->params.mode);
  82. return -EINVAL;
  83. }
  84. block_netpoll_tx();
  85. read_lock(&bond->lock);
  86. write_lock_bh(&bond->curr_slave_lock);
  87. /* check to see if we are clearing active */
  88. if (!slave_dev) {
  89. pr_info("%s: Clearing current active slave.\n",
  90. bond->dev->name);
  91. rcu_assign_pointer(bond->curr_active_slave, NULL);
  92. bond_select_active_slave(bond);
  93. } else {
  94. struct slave *old_active = bond->curr_active_slave;
  95. struct slave *new_active = bond_slave_get_rtnl(slave_dev);
  96. BUG_ON(!new_active);
  97. if (new_active == old_active) {
  98. /* do nothing */
  99. pr_info("%s: %s is already the current active slave.\n",
  100. bond->dev->name, new_active->dev->name);
  101. } else {
  102. if (old_active && (new_active->link == BOND_LINK_UP) &&
  103. IS_UP(new_active->dev)) {
  104. pr_info("%s: Setting %s as active slave.\n",
  105. bond->dev->name, new_active->dev->name);
  106. bond_change_active_slave(bond, new_active);
  107. } else {
  108. pr_err("%s: Could not set %s as active slave; either %s is down or the link is down.\n",
  109. bond->dev->name, new_active->dev->name,
  110. new_active->dev->name);
  111. ret = -EINVAL;
  112. }
  113. }
  114. }
  115. write_unlock_bh(&bond->curr_slave_lock);
  116. read_unlock(&bond->lock);
  117. unblock_netpoll_tx();
  118. return ret;
  119. }