bond_sysfs_slave.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* Sysfs attributes of bond slaves
  2. *
  3. * Copyright (c) 2014 Scott Feldman <sfeldma@cumulusnetworks.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version
  8. * 2 of the License, or (at your option) any later version.
  9. */
  10. #include <linux/capability.h>
  11. #include <linux/kernel.h>
  12. #include <linux/netdevice.h>
  13. #include <net/bonding.h>
  14. struct slave_attribute {
  15. struct attribute attr;
  16. ssize_t (*show)(struct slave *, char *);
  17. };
  18. #define SLAVE_ATTR(_name, _mode, _show) \
  19. const struct slave_attribute slave_attr_##_name = { \
  20. .attr = {.name = __stringify(_name), \
  21. .mode = _mode }, \
  22. .show = _show, \
  23. };
  24. #define SLAVE_ATTR_RO(_name) \
  25. SLAVE_ATTR(_name, S_IRUGO, _name##_show)
  26. static ssize_t state_show(struct slave *slave, char *buf)
  27. {
  28. switch (bond_slave_state(slave)) {
  29. case BOND_STATE_ACTIVE:
  30. return sprintf(buf, "active\n");
  31. case BOND_STATE_BACKUP:
  32. return sprintf(buf, "backup\n");
  33. default:
  34. return sprintf(buf, "UNKNOWN\n");
  35. }
  36. }
  37. static SLAVE_ATTR_RO(state);
  38. static ssize_t mii_status_show(struct slave *slave, char *buf)
  39. {
  40. return sprintf(buf, "%s\n", bond_slave_link_status(slave->link));
  41. }
  42. static SLAVE_ATTR_RO(mii_status);
  43. static ssize_t link_failure_count_show(struct slave *slave, char *buf)
  44. {
  45. return sprintf(buf, "%d\n", slave->link_failure_count);
  46. }
  47. static SLAVE_ATTR_RO(link_failure_count);
  48. static ssize_t perm_hwaddr_show(struct slave *slave, char *buf)
  49. {
  50. return sprintf(buf, "%pM\n", slave->perm_hwaddr);
  51. }
  52. static SLAVE_ATTR_RO(perm_hwaddr);
  53. static ssize_t queue_id_show(struct slave *slave, char *buf)
  54. {
  55. return sprintf(buf, "%d\n", slave->queue_id);
  56. }
  57. static SLAVE_ATTR_RO(queue_id);
  58. static ssize_t ad_aggregator_id_show(struct slave *slave, char *buf)
  59. {
  60. const struct aggregator *agg;
  61. if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
  62. agg = SLAVE_AD_INFO(slave)->port.aggregator;
  63. if (agg)
  64. return sprintf(buf, "%d\n",
  65. agg->aggregator_identifier);
  66. }
  67. return sprintf(buf, "N/A\n");
  68. }
  69. static SLAVE_ATTR_RO(ad_aggregator_id);
  70. static ssize_t ad_actor_oper_port_state_show(struct slave *slave, char *buf)
  71. {
  72. const struct port *ad_port;
  73. if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
  74. ad_port = &SLAVE_AD_INFO(slave)->port;
  75. if (ad_port->aggregator)
  76. return sprintf(buf, "%u\n",
  77. ad_port->actor_oper_port_state);
  78. }
  79. return sprintf(buf, "N/A\n");
  80. }
  81. static SLAVE_ATTR_RO(ad_actor_oper_port_state);
  82. static ssize_t ad_partner_oper_port_state_show(struct slave *slave, char *buf)
  83. {
  84. const struct port *ad_port;
  85. if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
  86. ad_port = &SLAVE_AD_INFO(slave)->port;
  87. if (ad_port->aggregator)
  88. return sprintf(buf, "%u\n",
  89. ad_port->partner_oper.port_state);
  90. }
  91. return sprintf(buf, "N/A\n");
  92. }
  93. static SLAVE_ATTR_RO(ad_partner_oper_port_state);
  94. static const struct slave_attribute *slave_attrs[] = {
  95. &slave_attr_state,
  96. &slave_attr_mii_status,
  97. &slave_attr_link_failure_count,
  98. &slave_attr_perm_hwaddr,
  99. &slave_attr_queue_id,
  100. &slave_attr_ad_aggregator_id,
  101. &slave_attr_ad_actor_oper_port_state,
  102. &slave_attr_ad_partner_oper_port_state,
  103. NULL
  104. };
  105. #define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr)
  106. #define to_slave(obj) container_of(obj, struct slave, kobj)
  107. static ssize_t slave_show(struct kobject *kobj,
  108. struct attribute *attr, char *buf)
  109. {
  110. struct slave_attribute *slave_attr = to_slave_attr(attr);
  111. struct slave *slave = to_slave(kobj);
  112. return slave_attr->show(slave, buf);
  113. }
  114. static const struct sysfs_ops slave_sysfs_ops = {
  115. .show = slave_show,
  116. };
  117. static struct kobj_type slave_ktype = {
  118. #ifdef CONFIG_SYSFS
  119. .sysfs_ops = &slave_sysfs_ops,
  120. #endif
  121. };
  122. int bond_sysfs_slave_add(struct slave *slave)
  123. {
  124. const struct slave_attribute **a;
  125. int err;
  126. err = kobject_init_and_add(&slave->kobj, &slave_ktype,
  127. &(slave->dev->dev.kobj), "bonding_slave");
  128. if (err)
  129. return err;
  130. for (a = slave_attrs; *a; ++a) {
  131. err = sysfs_create_file(&slave->kobj, &((*a)->attr));
  132. if (err) {
  133. kobject_put(&slave->kobj);
  134. return err;
  135. }
  136. }
  137. return 0;
  138. }
  139. void bond_sysfs_slave_del(struct slave *slave)
  140. {
  141. const struct slave_attribute **a;
  142. for (a = slave_attrs; *a; ++a)
  143. sysfs_remove_file(&slave->kobj, &((*a)->attr));
  144. kobject_put(&slave->kobj);
  145. }