bond_netlink.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
  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/module.h>
  12. #include <linux/errno.h>
  13. #include <linux/netdevice.h>
  14. #include <linux/etherdevice.h>
  15. #include <linux/if_link.h>
  16. #include <linux/if_ether.h>
  17. #include <net/netlink.h>
  18. #include <net/rtnetlink.h>
  19. #include "bonding.h"
  20. static const struct nla_policy bond_policy[IFLA_BOND_MAX + 1] = {
  21. [IFLA_BOND_MODE] = { .type = NLA_U8 },
  22. [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 },
  23. };
  24. static int bond_validate(struct nlattr *tb[], struct nlattr *data[])
  25. {
  26. if (tb[IFLA_ADDRESS]) {
  27. if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
  28. return -EINVAL;
  29. if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
  30. return -EADDRNOTAVAIL;
  31. }
  32. return 0;
  33. }
  34. static int bond_changelink(struct net_device *bond_dev,
  35. struct nlattr *tb[], struct nlattr *data[])
  36. {
  37. struct bonding *bond = netdev_priv(bond_dev);
  38. int err;
  39. if (data && data[IFLA_BOND_MODE]) {
  40. int mode = nla_get_u8(data[IFLA_BOND_MODE]);
  41. err = bond_option_mode_set(bond, mode);
  42. if (err)
  43. return err;
  44. }
  45. if (data && data[IFLA_BOND_ACTIVE_SLAVE]) {
  46. int ifindex = nla_get_u32(data[IFLA_BOND_ACTIVE_SLAVE]);
  47. struct net_device *slave_dev;
  48. if (ifindex == 0) {
  49. slave_dev = NULL;
  50. } else {
  51. slave_dev = __dev_get_by_index(dev_net(bond_dev),
  52. ifindex);
  53. if (!slave_dev)
  54. return -ENODEV;
  55. }
  56. err = bond_option_active_slave_set(bond, slave_dev);
  57. if (err)
  58. return err;
  59. }
  60. return 0;
  61. }
  62. static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
  63. struct nlattr *tb[], struct nlattr *data[])
  64. {
  65. int err;
  66. err = bond_changelink(bond_dev, tb, data);
  67. if (err < 0)
  68. return err;
  69. return register_netdevice(bond_dev);
  70. }
  71. static size_t bond_get_size(const struct net_device *bond_dev)
  72. {
  73. return nla_total_size(sizeof(u8)); /* IFLA_BOND_MODE */
  74. + nla_total_size(sizeof(u32)); /* IFLA_BOND_ACTIVE_SLAVE */
  75. }
  76. static int bond_fill_info(struct sk_buff *skb,
  77. const struct net_device *bond_dev)
  78. {
  79. struct bonding *bond = netdev_priv(bond_dev);
  80. struct net_device *slave_dev = bond_option_active_slave_get(bond);
  81. if (nla_put_u8(skb, IFLA_BOND_MODE, bond->params.mode) ||
  82. (slave_dev &&
  83. nla_put_u32(skb, IFLA_BOND_ACTIVE_SLAVE, slave_dev->ifindex)))
  84. goto nla_put_failure;
  85. return 0;
  86. nla_put_failure:
  87. return -EMSGSIZE;
  88. }
  89. struct rtnl_link_ops bond_link_ops __read_mostly = {
  90. .kind = "bond",
  91. .priv_size = sizeof(struct bonding),
  92. .setup = bond_setup,
  93. .maxtype = IFLA_BOND_MAX,
  94. .policy = bond_policy,
  95. .validate = bond_validate,
  96. .newlink = bond_newlink,
  97. .changelink = bond_changelink,
  98. .get_size = bond_get_size,
  99. .fill_info = bond_fill_info,
  100. .get_num_tx_queues = bond_get_num_tx_queues,
  101. .get_num_rx_queues = bond_get_num_tx_queues, /* Use the same number
  102. as for TX queues */
  103. };
  104. int __init bond_netlink_init(void)
  105. {
  106. return rtnl_link_register(&bond_link_ops);
  107. }
  108. void bond_netlink_fini(void)
  109. {
  110. rtnl_link_unregister(&bond_link_ops);
  111. }
  112. MODULE_ALIAS_RTNL_LINK("bond");