diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-03-11 04:57:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-17 00:23:22 -0400 |
commit | 10708f37ae729baba9b67bd134c3720709d4ae62 (patch) | |
tree | fa3e20c31e7d6907668d45eee702d02d646cae8f | |
parent | 6ce1a6df6efbbeaa262a225a1a439ebc30a75d2e (diff) |
net: core: add IFLA_STATS64 support
`ip -s link` shows interface counters truncated to 32 bit. This is
because interface statistics are transported only in 32-bit quantity
to userspace. This commit adds a new IFLA_STATS64 attribute that
exports them in full 64 bit.
References: http://lkml.indiana.edu/hypermail/linux/kernel/0307.3/0215.html
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/if_link.h | 33 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 42 |
2 files changed, 74 insertions, 1 deletions
diff --git a/include/linux/if_link.h b/include/linux/if_link.h index c9bf92cd7653..cfd420ba72df 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h | |||
@@ -37,6 +37,38 @@ struct rtnl_link_stats { | |||
37 | __u32 tx_compressed; | 37 | __u32 tx_compressed; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct rtnl_link_stats64 { | ||
41 | __u64 rx_packets; /* total packets received */ | ||
42 | __u64 tx_packets; /* total packets transmitted */ | ||
43 | __u64 rx_bytes; /* total bytes received */ | ||
44 | __u64 tx_bytes; /* total bytes transmitted */ | ||
45 | __u64 rx_errors; /* bad packets received */ | ||
46 | __u64 tx_errors; /* packet transmit problems */ | ||
47 | __u64 rx_dropped; /* no space in linux buffers */ | ||
48 | __u64 tx_dropped; /* no space available in linux */ | ||
49 | __u64 multicast; /* multicast packets received */ | ||
50 | __u64 collisions; | ||
51 | |||
52 | /* detailed rx_errors: */ | ||
53 | __u64 rx_length_errors; | ||
54 | __u64 rx_over_errors; /* receiver ring buff overflow */ | ||
55 | __u64 rx_crc_errors; /* recved pkt with crc error */ | ||
56 | __u64 rx_frame_errors; /* recv'd frame alignment error */ | ||
57 | __u64 rx_fifo_errors; /* recv'r fifo overrun */ | ||
58 | __u64 rx_missed_errors; /* receiver missed packet */ | ||
59 | |||
60 | /* detailed tx_errors */ | ||
61 | __u64 tx_aborted_errors; | ||
62 | __u64 tx_carrier_errors; | ||
63 | __u64 tx_fifo_errors; | ||
64 | __u64 tx_heartbeat_errors; | ||
65 | __u64 tx_window_errors; | ||
66 | |||
67 | /* for cslip etc */ | ||
68 | __u64 rx_compressed; | ||
69 | __u64 tx_compressed; | ||
70 | }; | ||
71 | |||
40 | /* The struct should be in sync with struct ifmap */ | 72 | /* The struct should be in sync with struct ifmap */ |
41 | struct rtnl_link_ifmap { | 73 | struct rtnl_link_ifmap { |
42 | __u64 mem_start; | 74 | __u64 mem_start; |
@@ -83,6 +115,7 @@ enum { | |||
83 | IFLA_VF_VLAN, | 115 | IFLA_VF_VLAN, |
84 | IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ | 116 | IFLA_VF_TX_RATE, /* TX Bandwidth Allocation */ |
85 | IFLA_VFINFO, | 117 | IFLA_VFINFO, |
118 | IFLA_STATS64, | ||
86 | __IFLA_MAX | 119 | __IFLA_MAX |
87 | }; | 120 | }; |
88 | 121 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 4568120d8533..e1121f0bca6a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -600,7 +600,39 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, | |||
600 | 600 | ||
601 | a->rx_compressed = b->rx_compressed; | 601 | a->rx_compressed = b->rx_compressed; |
602 | a->tx_compressed = b->tx_compressed; | 602 | a->tx_compressed = b->tx_compressed; |
603 | }; | 603 | } |
604 | |||
605 | static void copy_rtnl_link_stats64(struct rtnl_link_stats64 *a, | ||
606 | const struct net_device_stats *b) | ||
607 | { | ||
608 | a->rx_packets = b->rx_packets; | ||
609 | a->tx_packets = b->tx_packets; | ||
610 | a->rx_bytes = b->rx_bytes; | ||
611 | a->tx_bytes = b->tx_bytes; | ||
612 | a->rx_errors = b->rx_errors; | ||
613 | a->tx_errors = b->tx_errors; | ||
614 | a->rx_dropped = b->rx_dropped; | ||
615 | a->tx_dropped = b->tx_dropped; | ||
616 | |||
617 | a->multicast = b->multicast; | ||
618 | a->collisions = b->collisions; | ||
619 | |||
620 | a->rx_length_errors = b->rx_length_errors; | ||
621 | a->rx_over_errors = b->rx_over_errors; | ||
622 | a->rx_crc_errors = b->rx_crc_errors; | ||
623 | a->rx_frame_errors = b->rx_frame_errors; | ||
624 | a->rx_fifo_errors = b->rx_fifo_errors; | ||
625 | a->rx_missed_errors = b->rx_missed_errors; | ||
626 | |||
627 | a->tx_aborted_errors = b->tx_aborted_errors; | ||
628 | a->tx_carrier_errors = b->tx_carrier_errors; | ||
629 | a->tx_fifo_errors = b->tx_fifo_errors; | ||
630 | a->tx_heartbeat_errors = b->tx_heartbeat_errors; | ||
631 | a->tx_window_errors = b->tx_window_errors; | ||
632 | |||
633 | a->rx_compressed = b->rx_compressed; | ||
634 | a->tx_compressed = b->tx_compressed; | ||
635 | } | ||
604 | 636 | ||
605 | static inline int rtnl_vfinfo_size(const struct net_device *dev) | 637 | static inline int rtnl_vfinfo_size(const struct net_device *dev) |
606 | { | 638 | { |
@@ -698,6 +730,14 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
698 | stats = dev_get_stats(dev); | 730 | stats = dev_get_stats(dev); |
699 | copy_rtnl_link_stats(nla_data(attr), stats); | 731 | copy_rtnl_link_stats(nla_data(attr), stats); |
700 | 732 | ||
733 | attr = nla_reserve(skb, IFLA_STATS64, | ||
734 | sizeof(struct rtnl_link_stats64)); | ||
735 | if (attr == NULL) | ||
736 | goto nla_put_failure; | ||
737 | |||
738 | stats = dev_get_stats(dev); | ||
739 | copy_rtnl_link_stats64(nla_data(attr), stats); | ||
740 | |||
701 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { | 741 | if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { |
702 | int i; | 742 | int i; |
703 | struct ifla_vf_info ivi; | 743 | struct ifla_vf_info ivi; |