2 * net-sysfs.c - network device class and attributes
4 * Copyright (c) 2003 Stephen Hemminger <shemminger@osdl.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/netdevice.h>
15 #include <linux/if_arp.h>
17 #include <linux/rtnetlink.h>
18 #include <linux/wireless.h>
20 #define to_class_dev(obj) container_of(obj,struct class_device,kobj)
21 #define to_net_dev(class) container_of(class, struct net_device, class_dev)
23 static const char fmt_hex
[] = "%#x\n";
24 static const char fmt_long_hex
[] = "%#lx\n";
25 static const char fmt_dec
[] = "%d\n";
26 static const char fmt_ulong
[] = "%lu\n";
28 static inline int dev_isalive(const struct net_device
*dev
)
30 return dev
->reg_state
== NETREG_REGISTERED
;
33 /* use same locking rules as GIF* ioctl's */
34 static ssize_t
netdev_show(const struct class_device
*cd
, char *buf
,
35 ssize_t (*format
)(const struct net_device
*, char *))
37 struct net_device
*net
= to_net_dev(cd
);
38 ssize_t ret
= -EINVAL
;
40 read_lock(&dev_base_lock
);
42 ret
= (*format
)(net
, buf
);
43 read_unlock(&dev_base_lock
);
48 /* generate a show function for simple field */
49 #define NETDEVICE_SHOW(field, format_string) \
50 static ssize_t format_##field(const struct net_device *net, char *buf) \
52 return sprintf(buf, format_string, net->field); \
54 static ssize_t show_##field(struct class_device *cd, char *buf) \
56 return netdev_show(cd, buf, format_##field); \
60 /* use same locking and permission rules as SIF* ioctl's */
61 static ssize_t
netdev_store(struct class_device
*dev
,
62 const char *buf
, size_t len
,
63 int (*set
)(struct net_device
*, unsigned long))
65 struct net_device
*net
= to_net_dev(dev
);
70 if (!capable(CAP_NET_ADMIN
))
73 new = simple_strtoul(buf
, &endp
, 0);
78 if (dev_isalive(net
)) {
79 if ((ret
= (*set
)(net
, new)) == 0)
87 /* generate a read-only network device class attribute */
88 #define NETDEVICE_ATTR(field, format_string) \
89 NETDEVICE_SHOW(field, format_string) \
90 static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \
92 NETDEVICE_ATTR(addr_len, fmt_dec);
93 NETDEVICE_ATTR(iflink
, fmt_dec
);
94 NETDEVICE_ATTR(ifindex
, fmt_dec
);
95 NETDEVICE_ATTR(features
, fmt_long_hex
);
96 NETDEVICE_ATTR(type
, fmt_dec
);
98 /* use same locking rules as GIFHWADDR ioctl's */
99 static ssize_t
format_addr(char *buf
, const unsigned char *addr
, int len
)
104 for (i
= 0; i
< len
; i
++)
105 cp
+= sprintf(cp
, "%02x%c", addr
[i
],
106 i
== (len
- 1) ? '\n' : ':');
110 static ssize_t
show_address(struct class_device
*dev
, char *buf
)
112 struct net_device
*net
= to_net_dev(dev
);
113 ssize_t ret
= -EINVAL
;
115 read_lock(&dev_base_lock
);
116 if (dev_isalive(net
))
117 ret
= format_addr(buf
, net
->dev_addr
, net
->addr_len
);
118 read_unlock(&dev_base_lock
);
122 static ssize_t
show_broadcast(struct class_device
*dev
, char *buf
)
124 struct net_device
*net
= to_net_dev(dev
);
125 if (dev_isalive(net
))
126 return format_addr(buf
, net
->broadcast
, net
->addr_len
);
130 static ssize_t
show_carrier(struct class_device
*dev
, char *buf
)
132 struct net_device
*netdev
= to_net_dev(dev
);
133 if (netif_running(netdev
)) {
134 return sprintf(buf
, fmt_dec
, !!netif_carrier_ok(netdev
));
139 static CLASS_DEVICE_ATTR(address
, S_IRUGO
, show_address
, NULL
);
140 static CLASS_DEVICE_ATTR(broadcast
, S_IRUGO
, show_broadcast
, NULL
);
141 static CLASS_DEVICE_ATTR(carrier
, S_IRUGO
, show_carrier
, NULL
);
143 /* read-write attributes */
144 NETDEVICE_SHOW(mtu
, fmt_dec
);
146 static int change_mtu(struct net_device
*net
, unsigned long new_mtu
)
148 return dev_set_mtu(net
, (int) new_mtu
);
151 static ssize_t
store_mtu(struct class_device
*dev
, const char *buf
, size_t len
)
153 return netdev_store(dev
, buf
, len
, change_mtu
);
156 static CLASS_DEVICE_ATTR(mtu
, S_IRUGO
| S_IWUSR
, show_mtu
, store_mtu
);
158 NETDEVICE_SHOW(flags
, fmt_hex
);
160 static int change_flags(struct net_device
*net
, unsigned long new_flags
)
162 return dev_change_flags(net
, (unsigned) new_flags
);
165 static ssize_t
store_flags(struct class_device
*dev
, const char *buf
, size_t len
)
167 return netdev_store(dev
, buf
, len
, change_flags
);
170 static CLASS_DEVICE_ATTR(flags
, S_IRUGO
| S_IWUSR
, show_flags
, store_flags
);
172 NETDEVICE_SHOW(tx_queue_len
, fmt_ulong
);
174 static int change_tx_queue_len(struct net_device
*net
, unsigned long new_len
)
176 net
->tx_queue_len
= new_len
;
180 static ssize_t
store_tx_queue_len(struct class_device
*dev
, const char *buf
, size_t len
)
182 return netdev_store(dev
, buf
, len
, change_tx_queue_len
);
185 static CLASS_DEVICE_ATTR(tx_queue_len
, S_IRUGO
| S_IWUSR
, show_tx_queue_len
,
188 NETDEVICE_SHOW(weight
, fmt_dec
);
190 static int change_weight(struct net_device
*net
, unsigned long new_weight
)
192 net
->weight
= new_weight
;
196 static ssize_t
store_weight(struct class_device
*dev
, const char *buf
, size_t len
)
198 return netdev_store(dev
, buf
, len
, change_weight
);
201 static CLASS_DEVICE_ATTR(weight
, S_IRUGO
| S_IWUSR
, show_weight
,
205 static struct class_device_attribute
*net_class_attributes
[] = {
206 &class_device_attr_ifindex
,
207 &class_device_attr_iflink
,
208 &class_device_attr_addr_len
,
209 &class_device_attr_tx_queue_len
,
210 &class_device_attr_features
,
211 &class_device_attr_mtu
,
212 &class_device_attr_flags
,
213 &class_device_attr_weight
,
214 &class_device_attr_type
,
215 &class_device_attr_address
,
216 &class_device_attr_broadcast
,
217 &class_device_attr_carrier
,
221 /* Show a given an attribute in the statistics group */
222 static ssize_t
netstat_show(const struct class_device
*cd
, char *buf
,
223 unsigned long offset
)
225 struct net_device
*dev
= to_net_dev(cd
);
226 struct net_device_stats
*stats
;
227 ssize_t ret
= -EINVAL
;
229 if (offset
> sizeof(struct net_device_stats
) ||
230 offset
% sizeof(unsigned long) != 0)
233 read_lock(&dev_base_lock
);
234 if (dev_isalive(dev
) && dev
->get_stats
&&
235 (stats
= (*dev
->get_stats
)(dev
)))
236 ret
= sprintf(buf
, fmt_ulong
,
237 *(unsigned long *)(((u8
*) stats
) + offset
));
239 read_unlock(&dev_base_lock
);
243 /* generate a read-only statistics attribute */
244 #define NETSTAT_ENTRY(name) \
245 static ssize_t show_##name(struct class_device *cd, char *buf) \
247 return netstat_show(cd, buf, \
248 offsetof(struct net_device_stats, name)); \
250 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
252 NETSTAT_ENTRY(rx_packets
);
253 NETSTAT_ENTRY(tx_packets
);
254 NETSTAT_ENTRY(rx_bytes
);
255 NETSTAT_ENTRY(tx_bytes
);
256 NETSTAT_ENTRY(rx_errors
);
257 NETSTAT_ENTRY(tx_errors
);
258 NETSTAT_ENTRY(rx_dropped
);
259 NETSTAT_ENTRY(tx_dropped
);
260 NETSTAT_ENTRY(multicast
);
261 NETSTAT_ENTRY(collisions
);
262 NETSTAT_ENTRY(rx_length_errors
);
263 NETSTAT_ENTRY(rx_over_errors
);
264 NETSTAT_ENTRY(rx_crc_errors
);
265 NETSTAT_ENTRY(rx_frame_errors
);
266 NETSTAT_ENTRY(rx_fifo_errors
);
267 NETSTAT_ENTRY(rx_missed_errors
);
268 NETSTAT_ENTRY(tx_aborted_errors
);
269 NETSTAT_ENTRY(tx_carrier_errors
);
270 NETSTAT_ENTRY(tx_fifo_errors
);
271 NETSTAT_ENTRY(tx_heartbeat_errors
);
272 NETSTAT_ENTRY(tx_window_errors
);
273 NETSTAT_ENTRY(rx_compressed
);
274 NETSTAT_ENTRY(tx_compressed
);
276 static struct attribute
*netstat_attrs
[] = {
277 &class_device_attr_rx_packets
.attr
,
278 &class_device_attr_tx_packets
.attr
,
279 &class_device_attr_rx_bytes
.attr
,
280 &class_device_attr_tx_bytes
.attr
,
281 &class_device_attr_rx_errors
.attr
,
282 &class_device_attr_tx_errors
.attr
,
283 &class_device_attr_rx_dropped
.attr
,
284 &class_device_attr_tx_dropped
.attr
,
285 &class_device_attr_multicast
.attr
,
286 &class_device_attr_collisions
.attr
,
287 &class_device_attr_rx_length_errors
.attr
,
288 &class_device_attr_rx_over_errors
.attr
,
289 &class_device_attr_rx_crc_errors
.attr
,
290 &class_device_attr_rx_frame_errors
.attr
,
291 &class_device_attr_rx_fifo_errors
.attr
,
292 &class_device_attr_rx_missed_errors
.attr
,
293 &class_device_attr_tx_aborted_errors
.attr
,
294 &class_device_attr_tx_carrier_errors
.attr
,
295 &class_device_attr_tx_fifo_errors
.attr
,
296 &class_device_attr_tx_heartbeat_errors
.attr
,
297 &class_device_attr_tx_window_errors
.attr
,
298 &class_device_attr_rx_compressed
.attr
,
299 &class_device_attr_tx_compressed
.attr
,
304 static struct attribute_group netstat_group
= {
305 .name
= "statistics",
306 .attrs
= netstat_attrs
,
310 /* helper function that does all the locking etc for wireless stats */
311 static ssize_t
wireless_show(struct class_device
*cd
, char *buf
,
312 ssize_t (*format
)(const struct iw_statistics
*,
315 struct net_device
*dev
= to_net_dev(cd
);
316 const struct iw_statistics
*iw
;
317 ssize_t ret
= -EINVAL
;
319 read_lock(&dev_base_lock
);
320 if (dev_isalive(dev
) && dev
->get_wireless_stats
321 && (iw
= dev
->get_wireless_stats(dev
)) != NULL
)
322 ret
= (*format
)(iw
, buf
);
323 read_unlock(&dev_base_lock
);
328 /* show function template for wireless fields */
329 #define WIRELESS_SHOW(name, field, format_string) \
330 static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \
332 return sprintf(buf, format_string, iw->field); \
334 static ssize_t show_iw_##name(struct class_device *cd, char *buf) \
336 return wireless_show(cd, buf, format_iw_##name); \
338 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL)
340 WIRELESS_SHOW(status
, status
, fmt_hex
);
341 WIRELESS_SHOW(link
, qual
.qual
, fmt_dec
);
342 WIRELESS_SHOW(level
, qual
.level
, fmt_dec
);
343 WIRELESS_SHOW(noise
, qual
.noise
, fmt_dec
);
344 WIRELESS_SHOW(nwid
, discard
.nwid
, fmt_dec
);
345 WIRELESS_SHOW(crypt
, discard
.code
, fmt_dec
);
346 WIRELESS_SHOW(fragment
, discard
.fragment
, fmt_dec
);
347 WIRELESS_SHOW(misc
, discard
.misc
, fmt_dec
);
348 WIRELESS_SHOW(retries
, discard
.retries
, fmt_dec
);
349 WIRELESS_SHOW(beacon
, miss
.beacon
, fmt_dec
);
351 static struct attribute
*wireless_attrs
[] = {
352 &class_device_attr_status
.attr
,
353 &class_device_attr_link
.attr
,
354 &class_device_attr_level
.attr
,
355 &class_device_attr_noise
.attr
,
356 &class_device_attr_nwid
.attr
,
357 &class_device_attr_crypt
.attr
,
358 &class_device_attr_fragment
.attr
,
359 &class_device_attr_retries
.attr
,
360 &class_device_attr_misc
.attr
,
361 &class_device_attr_beacon
.attr
,
365 static struct attribute_group wireless_group
= {
367 .attrs
= wireless_attrs
,
371 #ifdef CONFIG_HOTPLUG
372 static int netdev_hotplug(struct class_device
*cd
, char **envp
,
373 int num_envp
, char *buf
, int size
)
375 struct net_device
*dev
= to_net_dev(cd
);
379 /* pass interface in env to hotplug. */
381 n
= snprintf(buf
, size
, "INTERFACE=%s", dev
->name
) + 1;
385 if ((size
<= 0) || (i
>= num_envp
))
394 * netdev_release -- destroy and free a dead device.
395 * Called when last reference to class_device kobject is gone.
397 static void netdev_release(struct class_device
*cd
)
399 struct net_device
*dev
400 = container_of(cd
, struct net_device
, class_dev
);
402 BUG_ON(dev
->reg_state
!= NETREG_RELEASED
);
404 kfree((char *)dev
- dev
->padded
);
407 static struct class net_class
= {
409 .release
= netdev_release
,
410 #ifdef CONFIG_HOTPLUG
411 .hotplug
= netdev_hotplug
,
415 void netdev_unregister_sysfs(struct net_device
* net
)
417 struct class_device
* class_dev
= &(net
->class_dev
);
420 sysfs_remove_group(&class_dev
->kobj
, &netstat_group
);
423 if (net
->get_wireless_stats
)
424 sysfs_remove_group(&class_dev
->kobj
, &wireless_group
);
426 class_device_del(class_dev
);
430 /* Create sysfs entries for network device. */
431 int netdev_register_sysfs(struct net_device
*net
)
433 struct class_device
*class_dev
= &(net
->class_dev
);
435 struct class_device_attribute
*attr
;
438 class_dev
->class = &net_class
;
439 class_dev
->class_data
= net
;
441 strlcpy(class_dev
->class_id
, net
->name
, BUS_ID_SIZE
);
442 if ((ret
= class_device_register(class_dev
)))
445 for (i
= 0; (attr
= net_class_attributes
[i
]) != NULL
; i
++) {
446 if ((ret
= class_device_create_file(class_dev
, attr
)))
451 if (net
->get_stats
&&
452 (ret
= sysfs_create_group(&class_dev
->kobj
, &netstat_group
)))
456 if (net
->get_wireless_stats
&&
457 (ret
= sysfs_create_group(&class_dev
->kobj
, &wireless_group
)))
463 sysfs_remove_group(&class_dev
->kobj
, &netstat_group
);
469 printk(KERN_WARNING
"%s: sysfs attribute registration failed %d\n",
471 class_device_unregister(class_dev
);
476 int netdev_sysfs_init(void)
478 return class_register(&net_class
);