linux/drivers/net/bonding/bond_sysfs_slave.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*      Sysfs attributes of bond slaves
   3 *
   4 *      Copyright (c) 2014 Scott Feldman <sfeldma@cumulusnetworks.com>
   5 */
   6
   7#include <linux/capability.h>
   8#include <linux/kernel.h>
   9#include <linux/netdevice.h>
  10
  11#include <net/bonding.h>
  12
  13struct slave_attribute {
  14        struct attribute attr;
  15        ssize_t (*show)(struct slave *, char *);
  16};
  17
  18#define SLAVE_ATTR(_name, _mode, _show)                         \
  19const 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, 0444, _name##_show)
  26
  27static ssize_t state_show(struct slave *slave, char *buf)
  28{
  29        switch (bond_slave_state(slave)) {
  30        case BOND_STATE_ACTIVE:
  31                return sprintf(buf, "active\n");
  32        case BOND_STATE_BACKUP:
  33                return sprintf(buf, "backup\n");
  34        default:
  35                return sprintf(buf, "UNKNOWN\n");
  36        }
  37}
  38static SLAVE_ATTR_RO(state);
  39
  40static ssize_t mii_status_show(struct slave *slave, char *buf)
  41{
  42        return sprintf(buf, "%s\n", bond_slave_link_status(slave->link));
  43}
  44static SLAVE_ATTR_RO(mii_status);
  45
  46static ssize_t link_failure_count_show(struct slave *slave, char *buf)
  47{
  48        return sprintf(buf, "%d\n", slave->link_failure_count);
  49}
  50static SLAVE_ATTR_RO(link_failure_count);
  51
  52static ssize_t perm_hwaddr_show(struct slave *slave, char *buf)
  53{
  54        return sprintf(buf, "%*phC\n",
  55                       slave->dev->addr_len,
  56                       slave->perm_hwaddr);
  57}
  58static SLAVE_ATTR_RO(perm_hwaddr);
  59
  60static ssize_t queue_id_show(struct slave *slave, char *buf)
  61{
  62        return sprintf(buf, "%d\n", slave->queue_id);
  63}
  64static SLAVE_ATTR_RO(queue_id);
  65
  66static ssize_t ad_aggregator_id_show(struct slave *slave, char *buf)
  67{
  68        const struct aggregator *agg;
  69
  70        if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
  71                agg = SLAVE_AD_INFO(slave)->port.aggregator;
  72                if (agg)
  73                        return sprintf(buf, "%d\n",
  74                                       agg->aggregator_identifier);
  75        }
  76
  77        return sprintf(buf, "N/A\n");
  78}
  79static SLAVE_ATTR_RO(ad_aggregator_id);
  80
  81static ssize_t ad_actor_oper_port_state_show(struct slave *slave, char *buf)
  82{
  83        const struct port *ad_port;
  84
  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->actor_oper_port_state);
  90        }
  91
  92        return sprintf(buf, "N/A\n");
  93}
  94static SLAVE_ATTR_RO(ad_actor_oper_port_state);
  95
  96static ssize_t ad_partner_oper_port_state_show(struct slave *slave, char *buf)
  97{
  98        const struct port *ad_port;
  99
 100        if (BOND_MODE(slave->bond) == BOND_MODE_8023AD) {
 101                ad_port = &SLAVE_AD_INFO(slave)->port;
 102                if (ad_port->aggregator)
 103                        return sprintf(buf, "%u\n",
 104                                       ad_port->partner_oper.port_state);
 105        }
 106
 107        return sprintf(buf, "N/A\n");
 108}
 109static SLAVE_ATTR_RO(ad_partner_oper_port_state);
 110
 111static const struct slave_attribute *slave_attrs[] = {
 112        &slave_attr_state,
 113        &slave_attr_mii_status,
 114        &slave_attr_link_failure_count,
 115        &slave_attr_perm_hwaddr,
 116        &slave_attr_queue_id,
 117        &slave_attr_ad_aggregator_id,
 118        &slave_attr_ad_actor_oper_port_state,
 119        &slave_attr_ad_partner_oper_port_state,
 120        NULL
 121};
 122
 123#define to_slave_attr(_at) container_of(_at, struct slave_attribute, attr)
 124
 125static ssize_t slave_show(struct kobject *kobj,
 126                          struct attribute *attr, char *buf)
 127{
 128        struct slave_attribute *slave_attr = to_slave_attr(attr);
 129        struct slave *slave = to_slave(kobj);
 130
 131        return slave_attr->show(slave, buf);
 132}
 133
 134const struct sysfs_ops slave_sysfs_ops = {
 135        .show = slave_show,
 136};
 137
 138int bond_sysfs_slave_add(struct slave *slave)
 139{
 140        const struct slave_attribute **a;
 141        int err;
 142
 143        for (a = slave_attrs; *a; ++a) {
 144                err = sysfs_create_file(&slave->kobj, &((*a)->attr));
 145                if (err) {
 146                        kobject_put(&slave->kobj);
 147                        return err;
 148                }
 149        }
 150
 151        return 0;
 152}
 153
 154void bond_sysfs_slave_del(struct slave *slave)
 155{
 156        const struct slave_attribute **a;
 157
 158        for (a = slave_attrs; *a; ++a)
 159                sysfs_remove_file(&slave->kobj, &((*a)->attr));
 160}
 161