Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.20-rc5 228 lines 6.3 kB view raw
1/* 2 * Sysfs attributes of bridge ports 3 * Linux ethernet bridge 4 * 5 * Authors: 6 * Stephen Hemminger <shemminger@osdl.org> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 */ 13 14#include <linux/capability.h> 15#include <linux/kernel.h> 16#include <linux/netdevice.h> 17#include <linux/if_bridge.h> 18#include <linux/rtnetlink.h> 19#include <linux/spinlock.h> 20 21#include "br_private.h" 22 23struct brport_attribute { 24 struct attribute attr; 25 ssize_t (*show)(struct net_bridge_port *, char *); 26 ssize_t (*store)(struct net_bridge_port *, unsigned long); 27}; 28 29#define BRPORT_ATTR(_name,_mode,_show,_store) \ 30struct brport_attribute brport_attr_##_name = { \ 31 .attr = {.name = __stringify(_name), \ 32 .mode = _mode, \ 33 .owner = THIS_MODULE, }, \ 34 .show = _show, \ 35 .store = _store, \ 36}; 37 38static ssize_t show_path_cost(struct net_bridge_port *p, char *buf) 39{ 40 return sprintf(buf, "%d\n", p->path_cost); 41} 42static ssize_t store_path_cost(struct net_bridge_port *p, unsigned long v) 43{ 44 br_stp_set_path_cost(p, v); 45 return 0; 46} 47static BRPORT_ATTR(path_cost, S_IRUGO | S_IWUSR, 48 show_path_cost, store_path_cost); 49 50static ssize_t show_priority(struct net_bridge_port *p, char *buf) 51{ 52 return sprintf(buf, "%d\n", p->priority); 53} 54static ssize_t store_priority(struct net_bridge_port *p, unsigned long v) 55{ 56 if (v >= (1<<(16-BR_PORT_BITS))) 57 return -ERANGE; 58 br_stp_set_port_priority(p, v); 59 return 0; 60} 61static BRPORT_ATTR(priority, S_IRUGO | S_IWUSR, 62 show_priority, store_priority); 63 64static ssize_t show_designated_root(struct net_bridge_port *p, char *buf) 65{ 66 return br_show_bridge_id(buf, &p->designated_root); 67} 68static BRPORT_ATTR(designated_root, S_IRUGO, show_designated_root, NULL); 69 70static ssize_t show_designated_bridge(struct net_bridge_port *p, char *buf) 71{ 72 return br_show_bridge_id(buf, &p->designated_bridge); 73} 74static BRPORT_ATTR(designated_bridge, S_IRUGO, show_designated_bridge, NULL); 75 76static ssize_t show_designated_port(struct net_bridge_port *p, char *buf) 77{ 78 return sprintf(buf, "%d\n", p->designated_port); 79} 80static BRPORT_ATTR(designated_port, S_IRUGO, show_designated_port, NULL); 81 82static ssize_t show_designated_cost(struct net_bridge_port *p, char *buf) 83{ 84 return sprintf(buf, "%d\n", p->designated_cost); 85} 86static BRPORT_ATTR(designated_cost, S_IRUGO, show_designated_cost, NULL); 87 88static ssize_t show_port_id(struct net_bridge_port *p, char *buf) 89{ 90 return sprintf(buf, "0x%x\n", p->port_id); 91} 92static BRPORT_ATTR(port_id, S_IRUGO, show_port_id, NULL); 93 94static ssize_t show_port_no(struct net_bridge_port *p, char *buf) 95{ 96 return sprintf(buf, "0x%x\n", p->port_no); 97} 98 99static BRPORT_ATTR(port_no, S_IRUGO, show_port_no, NULL); 100 101static ssize_t show_change_ack(struct net_bridge_port *p, char *buf) 102{ 103 return sprintf(buf, "%d\n", p->topology_change_ack); 104} 105static BRPORT_ATTR(change_ack, S_IRUGO, show_change_ack, NULL); 106 107static ssize_t show_config_pending(struct net_bridge_port *p, char *buf) 108{ 109 return sprintf(buf, "%d\n", p->config_pending); 110} 111static BRPORT_ATTR(config_pending, S_IRUGO, show_config_pending, NULL); 112 113static ssize_t show_port_state(struct net_bridge_port *p, char *buf) 114{ 115 return sprintf(buf, "%d\n", p->state); 116} 117static BRPORT_ATTR(state, S_IRUGO, show_port_state, NULL); 118 119static ssize_t show_message_age_timer(struct net_bridge_port *p, 120 char *buf) 121{ 122 return sprintf(buf, "%ld\n", br_timer_value(&p->message_age_timer)); 123} 124static BRPORT_ATTR(message_age_timer, S_IRUGO, show_message_age_timer, NULL); 125 126static ssize_t show_forward_delay_timer(struct net_bridge_port *p, 127 char *buf) 128{ 129 return sprintf(buf, "%ld\n", br_timer_value(&p->forward_delay_timer)); 130} 131static BRPORT_ATTR(forward_delay_timer, S_IRUGO, show_forward_delay_timer, NULL); 132 133static ssize_t show_hold_timer(struct net_bridge_port *p, 134 char *buf) 135{ 136 return sprintf(buf, "%ld\n", br_timer_value(&p->hold_timer)); 137} 138static BRPORT_ATTR(hold_timer, S_IRUGO, show_hold_timer, NULL); 139 140static struct brport_attribute *brport_attrs[] = { 141 &brport_attr_path_cost, 142 &brport_attr_priority, 143 &brport_attr_port_id, 144 &brport_attr_port_no, 145 &brport_attr_designated_root, 146 &brport_attr_designated_bridge, 147 &brport_attr_designated_port, 148 &brport_attr_designated_cost, 149 &brport_attr_state, 150 &brport_attr_change_ack, 151 &brport_attr_config_pending, 152 &brport_attr_message_age_timer, 153 &brport_attr_forward_delay_timer, 154 &brport_attr_hold_timer, 155 NULL 156}; 157 158#define to_brport_attr(_at) container_of(_at, struct brport_attribute, attr) 159#define to_brport(obj) container_of(obj, struct net_bridge_port, kobj) 160 161static ssize_t brport_show(struct kobject * kobj, 162 struct attribute * attr, char * buf) 163{ 164 struct brport_attribute * brport_attr = to_brport_attr(attr); 165 struct net_bridge_port * p = to_brport(kobj); 166 167 return brport_attr->show(p, buf); 168} 169 170static ssize_t brport_store(struct kobject * kobj, 171 struct attribute * attr, 172 const char * buf, size_t count) 173{ 174 struct brport_attribute * brport_attr = to_brport_attr(attr); 175 struct net_bridge_port * p = to_brport(kobj); 176 ssize_t ret = -EINVAL; 177 char *endp; 178 unsigned long val; 179 180 if (!capable(CAP_NET_ADMIN)) 181 return -EPERM; 182 183 val = simple_strtoul(buf, &endp, 0); 184 if (endp != buf) { 185 rtnl_lock(); 186 if (p->dev && p->br && brport_attr->store) { 187 spin_lock_bh(&p->br->lock); 188 ret = brport_attr->store(p, val); 189 spin_unlock_bh(&p->br->lock); 190 if (ret == 0) 191 ret = count; 192 } 193 rtnl_unlock(); 194 } 195 return ret; 196} 197 198struct sysfs_ops brport_sysfs_ops = { 199 .show = brport_show, 200 .store = brport_store, 201}; 202 203/* 204 * Add sysfs entries to ethernet device added to a bridge. 205 * Creates a brport subdirectory with bridge attributes. 206 * Puts symlink in bridge's brport subdirectory 207 */ 208int br_sysfs_addif(struct net_bridge_port *p) 209{ 210 struct net_bridge *br = p->br; 211 struct brport_attribute **a; 212 int err; 213 214 err = sysfs_create_link(&p->kobj, &br->dev->class_dev.kobj, 215 SYSFS_BRIDGE_PORT_LINK); 216 if (err) 217 goto out2; 218 219 for (a = brport_attrs; *a; ++a) { 220 err = sysfs_create_file(&p->kobj, &((*a)->attr)); 221 if (err) 222 goto out2; 223 } 224 225 err= sysfs_create_link(&br->ifobj, &p->kobj, p->dev->name); 226out2: 227 return err; 228}