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/capability.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>
19 #include <net/iw_handler.h>
21 static const char fmt_hex
[] = "%#x\n";
22 static const char fmt_long_hex
[] = "%#lx\n";
23 static const char fmt_dec
[] = "%d\n";
24 static const char fmt_ulong
[] = "%lu\n";
26 static inline int dev_isalive(const struct net_device
*dev
)
28 return dev
->reg_state
<= NETREG_REGISTERED
;
31 /* use same locking rules as GIF* ioctl's */
32 static ssize_t
netdev_show(const struct device
*dev
,
33 struct device_attribute
*attr
, char *buf
,
34 ssize_t (*format
)(const struct net_device
*, char *))
36 struct net_device
*net
= to_net_dev(dev
);
37 ssize_t ret
= -EINVAL
;
39 read_lock(&dev_base_lock
);
41 ret
= (*format
)(net
, buf
);
42 read_unlock(&dev_base_lock
);
47 /* generate a show function for simple field */
48 #define NETDEVICE_SHOW(field, format_string) \
49 static ssize_t format_##field(const struct net_device *net, char *buf) \
51 return sprintf(buf, format_string, net->field); \
53 static ssize_t show_##field(struct device *dev, \
54 struct device_attribute *attr, char *buf) \
56 return netdev_show(dev, attr, buf, format_##field); \
60 /* use same locking and permission rules as SIF* ioctl's */
61 static ssize_t
netdev_store(struct device
*dev
, struct device_attribute
*attr
,
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 NETDEVICE_SHOW(addr_len
, fmt_dec
);
88 NETDEVICE_SHOW(iflink
, fmt_dec
);
89 NETDEVICE_SHOW(ifindex
, fmt_dec
);
90 NETDEVICE_SHOW(features
, fmt_long_hex
);
91 NETDEVICE_SHOW(type
, fmt_dec
);
92 NETDEVICE_SHOW(link_mode
, fmt_dec
);
94 /* use same locking rules as GIFHWADDR ioctl's */
95 static ssize_t
format_addr(char *buf
, const unsigned char *addr
, int len
)
100 for (i
= 0; i
< len
; i
++)
101 cp
+= sprintf(cp
, "%02x%c", addr
[i
],
102 i
== (len
- 1) ? '\n' : ':');
106 static ssize_t
show_address(struct device
*dev
, struct device_attribute
*attr
,
109 struct net_device
*net
= to_net_dev(dev
);
110 ssize_t ret
= -EINVAL
;
112 read_lock(&dev_base_lock
);
113 if (dev_isalive(net
))
114 ret
= format_addr(buf
, net
->dev_addr
, net
->addr_len
);
115 read_unlock(&dev_base_lock
);
119 static ssize_t
show_broadcast(struct device
*dev
,
120 struct device_attribute
*attr
, char *buf
)
122 struct net_device
*net
= to_net_dev(dev
);
123 if (dev_isalive(net
))
124 return format_addr(buf
, net
->broadcast
, net
->addr_len
);
128 static ssize_t
show_carrier(struct device
*dev
,
129 struct device_attribute
*attr
, char *buf
)
131 struct net_device
*netdev
= to_net_dev(dev
);
132 if (netif_running(netdev
)) {
133 return sprintf(buf
, fmt_dec
, !!netif_carrier_ok(netdev
));
138 static ssize_t
show_dormant(struct device
*dev
,
139 struct device_attribute
*attr
, char *buf
)
141 struct net_device
*netdev
= to_net_dev(dev
);
143 if (netif_running(netdev
))
144 return sprintf(buf
, fmt_dec
, !!netif_dormant(netdev
));
149 static const char *operstates
[] = {
151 "notpresent", /* currently unused */
154 "testing", /* currently unused */
159 static ssize_t
show_operstate(struct device
*dev
,
160 struct device_attribute
*attr
, char *buf
)
162 const struct net_device
*netdev
= to_net_dev(dev
);
163 unsigned char operstate
;
165 read_lock(&dev_base_lock
);
166 operstate
= netdev
->operstate
;
167 if (!netif_running(netdev
))
168 operstate
= IF_OPER_DOWN
;
169 read_unlock(&dev_base_lock
);
171 if (operstate
>= ARRAY_SIZE(operstates
))
172 return -EINVAL
; /* should not happen */
174 return sprintf(buf
, "%s\n", operstates
[operstate
]);
177 /* read-write attributes */
178 NETDEVICE_SHOW(mtu
, fmt_dec
);
180 static int change_mtu(struct net_device
*net
, unsigned long new_mtu
)
182 return dev_set_mtu(net
, (int) new_mtu
);
185 static ssize_t
store_mtu(struct device
*dev
, struct device_attribute
*attr
,
186 const char *buf
, size_t len
)
188 return netdev_store(dev
, attr
, buf
, len
, change_mtu
);
191 NETDEVICE_SHOW(flags
, fmt_hex
);
193 static int change_flags(struct net_device
*net
, unsigned long new_flags
)
195 return dev_change_flags(net
, (unsigned) new_flags
);
198 static ssize_t
store_flags(struct device
*dev
, struct device_attribute
*attr
,
199 const char *buf
, size_t len
)
201 return netdev_store(dev
, attr
, buf
, len
, change_flags
);
204 NETDEVICE_SHOW(tx_queue_len
, fmt_ulong
);
206 static int change_tx_queue_len(struct net_device
*net
, unsigned long new_len
)
208 net
->tx_queue_len
= new_len
;
212 static ssize_t
store_tx_queue_len(struct device
*dev
,
213 struct device_attribute
*attr
,
214 const char *buf
, size_t len
)
216 return netdev_store(dev
, attr
, buf
, len
, change_tx_queue_len
);
219 NETDEVICE_SHOW(weight
, fmt_dec
);
221 static int change_weight(struct net_device
*net
, unsigned long new_weight
)
223 net
->weight
= new_weight
;
227 static ssize_t
store_weight(struct device
*dev
, struct device_attribute
*attr
,
228 const char *buf
, size_t len
)
230 return netdev_store(dev
, attr
, buf
, len
, change_weight
);
233 static struct device_attribute net_class_attributes
[] = {
234 __ATTR(addr_len
, S_IRUGO
, show_addr_len
, NULL
),
235 __ATTR(iflink
, S_IRUGO
, show_iflink
, NULL
),
236 __ATTR(ifindex
, S_IRUGO
, show_ifindex
, NULL
),
237 __ATTR(features
, S_IRUGO
, show_features
, NULL
),
238 __ATTR(type
, S_IRUGO
, show_type
, NULL
),
239 __ATTR(link_mode
, S_IRUGO
, show_link_mode
, NULL
),
240 __ATTR(address
, S_IRUGO
, show_address
, NULL
),
241 __ATTR(broadcast
, S_IRUGO
, show_broadcast
, NULL
),
242 __ATTR(carrier
, S_IRUGO
, show_carrier
, NULL
),
243 __ATTR(dormant
, S_IRUGO
, show_dormant
, NULL
),
244 __ATTR(operstate
, S_IRUGO
, show_operstate
, NULL
),
245 __ATTR(mtu
, S_IRUGO
| S_IWUSR
, show_mtu
, store_mtu
),
246 __ATTR(flags
, S_IRUGO
| S_IWUSR
, show_flags
, store_flags
),
247 __ATTR(tx_queue_len
, S_IRUGO
| S_IWUSR
, show_tx_queue_len
,
249 __ATTR(weight
, S_IRUGO
| S_IWUSR
, show_weight
, store_weight
),
253 /* Show a given an attribute in the statistics group */
254 static ssize_t
netstat_show(const struct device
*d
,
255 struct device_attribute
*attr
, char *buf
,
256 unsigned long offset
)
258 struct net_device
*dev
= to_net_dev(d
);
259 struct net_device_stats
*stats
;
260 ssize_t ret
= -EINVAL
;
262 if (offset
> sizeof(struct net_device_stats
) ||
263 offset
% sizeof(unsigned long) != 0)
266 read_lock(&dev_base_lock
);
267 if (dev_isalive(dev
) && dev
->get_stats
&&
268 (stats
= (*dev
->get_stats
)(dev
)))
269 ret
= sprintf(buf
, fmt_ulong
,
270 *(unsigned long *)(((u8
*) stats
) + offset
));
272 read_unlock(&dev_base_lock
);
276 /* generate a read-only statistics attribute */
277 #define NETSTAT_ENTRY(name) \
278 static ssize_t show_##name(struct device *d, \
279 struct device_attribute *attr, char *buf) \
281 return netstat_show(d, attr, buf, \
282 offsetof(struct net_device_stats, name)); \
284 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
286 NETSTAT_ENTRY(rx_packets
);
287 NETSTAT_ENTRY(tx_packets
);
288 NETSTAT_ENTRY(rx_bytes
);
289 NETSTAT_ENTRY(tx_bytes
);
290 NETSTAT_ENTRY(rx_errors
);
291 NETSTAT_ENTRY(tx_errors
);
292 NETSTAT_ENTRY(rx_dropped
);
293 NETSTAT_ENTRY(tx_dropped
);
294 NETSTAT_ENTRY(multicast
);
295 NETSTAT_ENTRY(collisions
);
296 NETSTAT_ENTRY(rx_length_errors
);
297 NETSTAT_ENTRY(rx_over_errors
);
298 NETSTAT_ENTRY(rx_crc_errors
);
299 NETSTAT_ENTRY(rx_frame_errors
);
300 NETSTAT_ENTRY(rx_fifo_errors
);
301 NETSTAT_ENTRY(rx_missed_errors
);
302 NETSTAT_ENTRY(tx_aborted_errors
);
303 NETSTAT_ENTRY(tx_carrier_errors
);
304 NETSTAT_ENTRY(tx_fifo_errors
);
305 NETSTAT_ENTRY(tx_heartbeat_errors
);
306 NETSTAT_ENTRY(tx_window_errors
);
307 NETSTAT_ENTRY(rx_compressed
);
308 NETSTAT_ENTRY(tx_compressed
);
310 static struct attribute
*netstat_attrs
[] = {
311 &dev_attr_rx_packets
.attr
,
312 &dev_attr_tx_packets
.attr
,
313 &dev_attr_rx_bytes
.attr
,
314 &dev_attr_tx_bytes
.attr
,
315 &dev_attr_rx_errors
.attr
,
316 &dev_attr_tx_errors
.attr
,
317 &dev_attr_rx_dropped
.attr
,
318 &dev_attr_tx_dropped
.attr
,
319 &dev_attr_multicast
.attr
,
320 &dev_attr_collisions
.attr
,
321 &dev_attr_rx_length_errors
.attr
,
322 &dev_attr_rx_over_errors
.attr
,
323 &dev_attr_rx_crc_errors
.attr
,
324 &dev_attr_rx_frame_errors
.attr
,
325 &dev_attr_rx_fifo_errors
.attr
,
326 &dev_attr_rx_missed_errors
.attr
,
327 &dev_attr_tx_aborted_errors
.attr
,
328 &dev_attr_tx_carrier_errors
.attr
,
329 &dev_attr_tx_fifo_errors
.attr
,
330 &dev_attr_tx_heartbeat_errors
.attr
,
331 &dev_attr_tx_window_errors
.attr
,
332 &dev_attr_rx_compressed
.attr
,
333 &dev_attr_tx_compressed
.attr
,
338 static struct attribute_group netstat_group
= {
339 .name
= "statistics",
340 .attrs
= netstat_attrs
,
343 #ifdef CONFIG_WIRELESS_EXT
344 /* helper function that does all the locking etc for wireless stats */
345 static ssize_t
wireless_show(struct device
*d
, char *buf
,
346 ssize_t (*format
)(const struct iw_statistics
*,
349 struct net_device
*dev
= to_net_dev(d
);
350 const struct iw_statistics
*iw
= NULL
;
351 ssize_t ret
= -EINVAL
;
353 read_lock(&dev_base_lock
);
354 if (dev_isalive(dev
)) {
355 if(dev
->wireless_handlers
&&
356 dev
->wireless_handlers
->get_wireless_stats
)
357 iw
= dev
->wireless_handlers
->get_wireless_stats(dev
);
359 ret
= (*format
)(iw
, buf
);
361 read_unlock(&dev_base_lock
);
366 /* show function template for wireless fields */
367 #define WIRELESS_SHOW(name, field, format_string) \
368 static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \
370 return sprintf(buf, format_string, iw->field); \
372 static ssize_t show_iw_##name(struct device *d, \
373 struct device_attribute *attr, char *buf) \
375 return wireless_show(d, buf, format_iw_##name); \
377 static DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL)
379 WIRELESS_SHOW(status
, status
, fmt_hex
);
380 WIRELESS_SHOW(link
, qual
.qual
, fmt_dec
);
381 WIRELESS_SHOW(level
, qual
.level
, fmt_dec
);
382 WIRELESS_SHOW(noise
, qual
.noise
, fmt_dec
);
383 WIRELESS_SHOW(nwid
, discard
.nwid
, fmt_dec
);
384 WIRELESS_SHOW(crypt
, discard
.code
, fmt_dec
);
385 WIRELESS_SHOW(fragment
, discard
.fragment
, fmt_dec
);
386 WIRELESS_SHOW(misc
, discard
.misc
, fmt_dec
);
387 WIRELESS_SHOW(retries
, discard
.retries
, fmt_dec
);
388 WIRELESS_SHOW(beacon
, miss
.beacon
, fmt_dec
);
390 static struct attribute
*wireless_attrs
[] = {
391 &dev_attr_status
.attr
,
393 &dev_attr_level
.attr
,
394 &dev_attr_noise
.attr
,
396 &dev_attr_crypt
.attr
,
397 &dev_attr_fragment
.attr
,
398 &dev_attr_retries
.attr
,
400 &dev_attr_beacon
.attr
,
404 static struct attribute_group wireless_group
= {
406 .attrs
= wireless_attrs
,
410 #ifdef CONFIG_HOTPLUG
411 static int netdev_uevent(struct device
*d
, char **envp
,
412 int num_envp
, char *buf
, int size
)
414 struct net_device
*dev
= to_net_dev(d
);
418 /* pass interface to uevent. */
420 n
= snprintf(buf
, size
, "INTERFACE=%s", dev
->name
) + 1;
424 if ((size
<= 0) || (i
>= num_envp
))
433 * netdev_release -- destroy and free a dead device.
434 * Called when last reference to device kobject is gone.
436 static void netdev_release(struct device
*d
)
438 struct net_device
*dev
= to_net_dev(d
);
440 BUG_ON(dev
->reg_state
!= NETREG_RELEASED
);
442 kfree((char *)dev
- dev
->padded
);
445 static struct class net_class
= {
447 .dev_release
= netdev_release
,
448 .dev_attrs
= net_class_attributes
,
449 #ifdef CONFIG_HOTPLUG
450 .dev_uevent
= netdev_uevent
,
454 void netdev_unregister_sysfs(struct net_device
* net
)
456 device_del(&(net
->dev
));
459 /* Create sysfs entries for network device. */
460 int netdev_register_sysfs(struct net_device
*net
)
462 struct device
*dev
= &(net
->dev
);
463 struct attribute_group
**groups
= net
->sysfs_groups
;
465 device_initialize(dev
);
466 dev
->class = &net_class
;
467 dev
->platform_data
= net
;
468 dev
->groups
= groups
;
470 BUILD_BUG_ON(BUS_ID_SIZE
< IFNAMSIZ
);
471 strlcpy(dev
->bus_id
, net
->name
, BUS_ID_SIZE
);
474 *groups
++ = &netstat_group
;
476 #ifdef CONFIG_WIRELESS_EXT
477 if (net
->wireless_handlers
&& net
->wireless_handlers
->get_wireless_stats
)
478 *groups
++ = &wireless_group
;
481 return device_add(dev
);
484 int netdev_sysfs_init(void)
486 return class_register(&net_class
);