2 * net-sysfs.c - network device class and attributes
4 * Copyright (c) 2003 Stephen Hemminger <shemminger@osdl.org>
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/netdevice.h>
11 #include <linux/if_arp.h>
13 #include <linux/rtnetlink.h>
15 #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
16 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
18 static inline int dev_isalive(const struct net_device
*dev
)
20 return dev
->reg_state
== NETREG_REGISTERED
;
23 /* use same locking rules as GIF* ioctl's */
24 static ssize_t
netdev_show(const struct class_device
*cd
, char *buf
,
25 ssize_t (*format
)(const struct net_device
*, char *))
27 struct net_device
*net
= to_net_dev(cd
);
28 ssize_t ret
= -EINVAL
;
30 read_lock(&dev_base_lock
);
32 ret
= (*format
)(net
, buf
);
33 read_unlock(&dev_base_lock
);
38 /* generate a show function for simple field */
39 #define NETDEVICE_SHOW(field, format_string) \
40 static ssize_t format_##field(const struct net_device *net, char *buf) \
42 return sprintf(buf, format_string, net->field); \
44 static ssize_t show_##field(struct class_device *cd, char *buf) \
46 return netdev_show(cd, buf, format_##field); \
50 /* use same locking and permission rules as SIF* ioctl's */
51 static ssize_t
netdev_store(struct class_device
*dev
,
52 const char *buf
, size_t len
,
53 int (*set
)(struct net_device
*, unsigned long))
55 struct net_device
*net
= to_net_dev(dev
);
60 if (!capable(CAP_NET_ADMIN
))
63 new = simple_strtoul(buf
, &endp
, 0);
68 if (dev_isalive(net
)) {
69 if ((ret
= (*set
)(net
, new)) == 0)
77 /* generate a read-only network device class attribute */
78 #define NETDEVICE_ATTR(field, format_string) \
79 NETDEVICE_SHOW(field, format_string) \
80 static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \
82 NETDEVICE_ATTR(addr_len, "%d\n");
83 NETDEVICE_ATTR(iflink
, "%d\n");
84 NETDEVICE_ATTR(ifindex
, "%d\n");
85 NETDEVICE_ATTR(features
, "%#x\n");
86 NETDEVICE_ATTR(type
, "%d\n");
88 /* use same locking rules as GIFHWADDR ioctl's */
89 static ssize_t
format_addr(char *buf
, const unsigned char *addr
, int len
)
94 read_lock(&dev_base_lock
);
95 for (i
= 0; i
< len
; i
++)
96 cp
+= sprintf(cp
, "%02x%c", addr
[i
],
97 i
== (len
- 1) ? '\n' : ':');
98 read_unlock(&dev_base_lock
);
102 static ssize_t
show_address(struct class_device
*dev
, char *buf
)
104 struct net_device
*net
= to_net_dev(dev
);
105 if (dev_isalive(net
))
106 return format_addr(buf
, net
->dev_addr
, net
->addr_len
);
110 static ssize_t
show_broadcast(struct class_device
*dev
, char *buf
)
112 struct net_device
*net
= to_net_dev(dev
);
113 if (dev_isalive(net
))
114 return format_addr(buf
, net
->broadcast
, net
->addr_len
);
118 static CLASS_DEVICE_ATTR(address
, S_IRUGO
, show_address
, NULL
);
119 static CLASS_DEVICE_ATTR(broadcast
, S_IRUGO
, show_broadcast
, NULL
);
121 /* read-write attributes */
122 NETDEVICE_SHOW(mtu
, "%d\n");
124 static int change_mtu(struct net_device
*net
, unsigned long new_mtu
)
126 return dev_set_mtu(net
, (int) new_mtu
);
129 static ssize_t
store_mtu(struct class_device
*dev
, const char *buf
, size_t len
)
131 return netdev_store(dev
, buf
, len
, change_mtu
);
134 static CLASS_DEVICE_ATTR(mtu
, S_IRUGO
| S_IWUSR
, show_mtu
, store_mtu
);
136 NETDEVICE_SHOW(flags
, "%#x\n");
138 static int change_flags(struct net_device
*net
, unsigned long new_flags
)
140 return dev_change_flags(net
, (unsigned) new_flags
);
143 static ssize_t
store_flags(struct class_device
*dev
, const char *buf
, size_t len
)
145 return netdev_store(dev
, buf
, len
, change_flags
);
148 static CLASS_DEVICE_ATTR(flags
, S_IRUGO
| S_IWUSR
, show_flags
, store_flags
);
150 NETDEVICE_SHOW(tx_queue_len
, "%lu\n");
152 static int change_tx_queue_len(struct net_device
*net
, unsigned long new_len
)
154 net
->tx_queue_len
= new_len
;
158 static ssize_t
store_tx_queue_len(struct class_device
*dev
, const char *buf
, size_t len
)
160 return netdev_store(dev
, buf
, len
, change_tx_queue_len
);
163 static CLASS_DEVICE_ATTR(tx_queue_len
, S_IRUGO
| S_IWUSR
, show_tx_queue_len
,
167 static struct class_device_attribute
*net_class_attributes
[] = {
168 &class_device_attr_ifindex
,
169 &class_device_attr_iflink
,
170 &class_device_attr_addr_len
,
171 &class_device_attr_tx_queue_len
,
172 &class_device_attr_features
,
173 &class_device_attr_mtu
,
174 &class_device_attr_flags
,
175 &class_device_attr_type
,
176 &class_device_attr_address
,
177 &class_device_attr_broadcast
,
181 struct netstat_fs_entry
{
182 struct attribute attr
;
183 ssize_t (*show
)(const struct net_device_stats
*, char *);
184 ssize_t (*store
)(struct net_device_stats
*, const char *, size_t);
187 static ssize_t
net_device_stat_show(unsigned long var
, char *buf
)
189 return sprintf(buf
, "%ld\n", var
);
192 /* generate a read-only statistics attribute */
193 #define NETDEVICE_STAT(_NAME) \
194 static ssize_t show_stat_##_NAME(const struct net_device_stats *stats, \
197 return net_device_stat_show(stats->_NAME, buf); \
199 static struct netstat_fs_entry net_stat_##_NAME = { \
200 .attr = {.name = __stringify(_NAME), .mode = S_IRUGO }, \
201 .show = show_stat_##_NAME, \
204 NETDEVICE_STAT(rx_packets
);
205 NETDEVICE_STAT(tx_packets
);
206 NETDEVICE_STAT(rx_bytes
);
207 NETDEVICE_STAT(tx_bytes
);
208 NETDEVICE_STAT(rx_errors
);
209 NETDEVICE_STAT(tx_errors
);
210 NETDEVICE_STAT(rx_dropped
);
211 NETDEVICE_STAT(tx_dropped
);
212 NETDEVICE_STAT(multicast
);
213 NETDEVICE_STAT(collisions
);
214 NETDEVICE_STAT(rx_length_errors
);
215 NETDEVICE_STAT(rx_over_errors
);
216 NETDEVICE_STAT(rx_crc_errors
);
217 NETDEVICE_STAT(rx_frame_errors
);
218 NETDEVICE_STAT(rx_fifo_errors
);
219 NETDEVICE_STAT(rx_missed_errors
);
220 NETDEVICE_STAT(tx_aborted_errors
);
221 NETDEVICE_STAT(tx_carrier_errors
);
222 NETDEVICE_STAT(tx_fifo_errors
);
223 NETDEVICE_STAT(tx_heartbeat_errors
);
224 NETDEVICE_STAT(tx_window_errors
);
225 NETDEVICE_STAT(rx_compressed
);
226 NETDEVICE_STAT(tx_compressed
);
228 static struct attribute
*default_attrs
[] = {
229 &net_stat_rx_packets
.attr
,
230 &net_stat_tx_packets
.attr
,
231 &net_stat_rx_bytes
.attr
,
232 &net_stat_tx_bytes
.attr
,
233 &net_stat_rx_errors
.attr
,
234 &net_stat_tx_errors
.attr
,
235 &net_stat_rx_dropped
.attr
,
236 &net_stat_tx_dropped
.attr
,
237 &net_stat_multicast
.attr
,
238 &net_stat_collisions
.attr
,
239 &net_stat_rx_length_errors
.attr
,
240 &net_stat_rx_over_errors
.attr
,
241 &net_stat_rx_crc_errors
.attr
,
242 &net_stat_rx_frame_errors
.attr
,
243 &net_stat_rx_fifo_errors
.attr
,
244 &net_stat_rx_missed_errors
.attr
,
245 &net_stat_tx_aborted_errors
.attr
,
246 &net_stat_tx_carrier_errors
.attr
,
247 &net_stat_tx_fifo_errors
.attr
,
248 &net_stat_tx_heartbeat_errors
.attr
,
249 &net_stat_tx_window_errors
.attr
,
250 &net_stat_rx_compressed
.attr
,
251 &net_stat_tx_compressed
.attr
,
257 netstat_attr_show(struct kobject
*kobj
, struct attribute
*attr
, char *buf
)
259 struct netstat_fs_entry
*entry
260 = container_of(attr
, struct netstat_fs_entry
, attr
);
261 struct net_device
*dev
262 = to_net_dev(to_class_dev(kobj
->parent
));
263 struct net_device_stats
*stats
;
264 ssize_t ret
= -EINVAL
;
266 read_lock(&dev_base_lock
);
267 if (dev_isalive(dev
) && entry
->show
&& dev
->get_stats
&&
268 (stats
= (*dev
->get_stats
)(dev
)))
269 ret
= entry
->show(stats
, buf
);
270 read_unlock(&dev_base_lock
);
274 static struct sysfs_ops netstat_sysfs_ops
= {
275 .show
= netstat_attr_show
,
278 static struct kobj_type netstat_ktype
= {
279 .sysfs_ops
= &netstat_sysfs_ops
,
280 .default_attrs
= default_attrs
,
283 #ifdef CONFIG_HOTPLUG
284 static int netdev_hotplug(struct class_device
*cd
, char **envp
,
285 int num_envp
, char *buf
, int size
)
287 struct net_device
*dev
= to_net_dev(cd
);
291 /* pass interface in env to hotplug. */
293 n
= snprintf(buf
, size
, "INTERFACE=%s", dev
->name
) + 1;
297 if ((size
<= 0) || (i
>= num_envp
))
305 static struct class net_class
= {
307 #ifdef CONFIG_HOTPLUG
308 .hotplug
= netdev_hotplug
,
312 /* Create sysfs entries for network device. */
313 int netdev_register_sysfs(struct net_device
*net
)
315 struct class_device
*class_dev
= &(net
->class_dev
);
317 struct class_device_attribute
*attr
;
320 class_dev
->class = &net_class
;
321 class_dev
->class_data
= net
;
323 strlcpy(class_dev
->class_id
, net
->name
, BUS_ID_SIZE
);
324 if ((ret
= class_device_register(class_dev
)))
327 for (i
= 0; (attr
= net_class_attributes
[i
]); i
++) {
328 if ((ret
= class_device_create_file(class_dev
, attr
)))
332 net
->stats_kobj
.parent
= NULL
;
333 if (net
->get_stats
) {
334 struct kobject
*k
= &net
->stats_kobj
;
336 k
->parent
= &class_dev
->kobj
;
337 strlcpy(k
->name
, "statistics", KOBJ_NAME_LEN
);
338 k
->ktype
= &netstat_ktype
;
340 if((ret
= kobject_register(k
)))
347 printk(KERN_WARNING
"%s: sysfs attribute registration failed %d\n",
349 class_device_unregister(class_dev
);
353 void netdev_unregister_sysfs(struct net_device
*net
)
355 if (net
->stats_kobj
.parent
)
356 kobject_unregister(&net
->stats_kobj
);
358 class_device_unregister(&net
->class_dev
);
361 int netdev_sysfs_init(void)
363 return class_register(&net_class
);