Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0 |
| 2 | |
| 3 | ==================== |
| 4 | Interface statistics |
| 5 | ==================== |
| 6 | |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 7 | Overview |
| 8 | ======== |
| 9 | |
Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 10 | This document is a guide to Linux network interface statistics. |
| 11 | |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 12 | There are three main sources of interface statistics in Linux: |
Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 13 | |
| 14 | - standard interface statistics based on |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 15 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`; |
| 16 | - protocol-specific statistics; and |
Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 17 | - driver-defined statistics available via ethtool. |
| 18 | |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 19 | Standard interface statistics |
| 20 | ----------------------------- |
| 21 | |
| 22 | There are multiple interfaces to reach the standard statistics. |
| 23 | Most commonly used is the `ip` command from `iproute2`:: |
Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 24 | |
| 25 | $ ip -s -s link show dev ens4u1u1 |
| 26 | 6: ens4u1u1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000 |
| 27 | link/ether 48:2a:e3:4c:b1:d1 brd ff:ff:ff:ff:ff:ff |
| 28 | RX: bytes packets errors dropped overrun mcast |
| 29 | 74327665117 69016965 0 0 0 0 |
| 30 | RX errors: length crc frame fifo missed |
| 31 | 0 0 0 0 0 |
| 32 | TX: bytes packets errors dropped carrier collsns |
| 33 | 21405556176 44608960 0 0 0 0 |
| 34 | TX errors: aborted fifo window heartbeat transns |
| 35 | 0 0 0 0 128 |
| 36 | altname enp58s0u1u1 |
| 37 | |
| 38 | Note that `-s` has been specified twice to see all members of |
| 39 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`. |
| 40 | If `-s` is specified once the detailed errors won't be shown. |
| 41 | |
| 42 | `ip` supports JSON formatting via the `-j` option. |
| 43 | |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 44 | Protocol-specific statistics |
| 45 | ---------------------------- |
| 46 | |
Jakub Kicinski | f117c48 | 2021-04-16 12:27:37 -0700 | [diff] [blame] | 47 | Protocol-specific statistics are exposed via relevant interfaces, |
| 48 | the same interfaces as are used to configure them. |
| 49 | |
| 50 | ethtool |
| 51 | ~~~~~~~ |
| 52 | |
| 53 | Ethtool exposes common low-level statistics. |
| 54 | All the standard statistics are expected to be maintained |
| 55 | by the device, not the driver (as opposed to driver-defined stats |
| 56 | described in the next section which mix software and hardware stats). |
| 57 | For devices which contain unmanaged |
| 58 | switches (e.g. legacy SR-IOV or multi-host NICs) the events counted |
| 59 | may not pertain exclusively to the packets destined to |
| 60 | the local host interface. In other words the events may |
| 61 | be counted at the network port (MAC/PHY blocks) without separation |
| 62 | for different host side (PCIe) devices. Such ambiguity must not |
| 63 | be present when internal switch is managed by Linux (so called |
| 64 | switchdev mode for NICs). |
| 65 | |
| 66 | Standard ethtool statistics can be accessed via the interfaces used |
| 67 | for configuration. For example ethtool interface used |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 68 | to configure pause frames can report corresponding hardware counters:: |
| 69 | |
| 70 | $ ethtool --include-statistics -a eth0 |
| 71 | Pause parameters for eth0: |
| 72 | Autonegotiate: on |
| 73 | RX: on |
| 74 | TX: on |
| 75 | Statistics: |
| 76 | tx_pause_frames: 1 |
| 77 | rx_pause_frames: 1 |
| 78 | |
Jakub Kicinski | f117c48 | 2021-04-16 12:27:37 -0700 | [diff] [blame] | 79 | General Ethernet statistics not associated with any particular |
| 80 | functionality are exposed via ``ethtool -S $ifc`` by specifying |
| 81 | the ``--groups`` parameter:: |
| 82 | |
| 83 | $ ethtool -S eth0 --groups eth-phy eth-mac eth-ctrl rmon |
| 84 | Stats for eth0: |
| 85 | eth-phy-SymbolErrorDuringCarrier: 0 |
| 86 | eth-mac-FramesTransmittedOK: 1 |
| 87 | eth-mac-FrameTooLongErrors: 1 |
| 88 | eth-ctrl-MACControlFramesTransmitted: 1 |
| 89 | eth-ctrl-MACControlFramesReceived: 0 |
| 90 | eth-ctrl-UnsupportedOpcodesReceived: 1 |
| 91 | rmon-etherStatsUndersizePkts: 1 |
| 92 | rmon-etherStatsJabbers: 0 |
| 93 | rmon-rx-etherStatsPkts64Octets: 1 |
| 94 | rmon-rx-etherStatsPkts65to127Octets: 0 |
| 95 | rmon-rx-etherStatsPkts128to255Octets: 0 |
| 96 | rmon-tx-etherStatsPkts64Octets: 2 |
| 97 | rmon-tx-etherStatsPkts65to127Octets: 3 |
| 98 | rmon-tx-etherStatsPkts128to255Octets: 0 |
| 99 | |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 100 | Driver-defined statistics |
| 101 | ------------------------- |
| 102 | |
| 103 | Driver-defined ethtool statistics can be dumped using `ethtool -S $ifc`, e.g.:: |
Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 104 | |
| 105 | $ ethtool -S ens4u1u1 |
| 106 | NIC statistics: |
| 107 | tx_single_collisions: 0 |
| 108 | tx_multi_collisions: 0 |
| 109 | |
| 110 | uAPIs |
| 111 | ===== |
| 112 | |
| 113 | procfs |
| 114 | ------ |
| 115 | |
| 116 | The historical `/proc/net/dev` text interface gives access to the list |
| 117 | of interfaces as well as their statistics. |
| 118 | |
| 119 | Note that even though this interface is using |
| 120 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>` |
| 121 | internally it combines some of the fields. |
| 122 | |
| 123 | sysfs |
| 124 | ----- |
| 125 | |
| 126 | Each device directory in sysfs contains a `statistics` directory (e.g. |
| 127 | `/sys/class/net/lo/statistics/`) with files corresponding to |
| 128 | members of :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`. |
| 129 | |
| 130 | This simple interface is convenient especially in constrained/embedded |
| 131 | environments without access to tools. However, it's inefficient when |
| 132 | reading multiple stats as it internally performs a full dump of |
| 133 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>` |
| 134 | and reports only the stat corresponding to the accessed file. |
| 135 | |
| 136 | Sysfs files are documented in |
| 137 | `Documentation/ABI/testing/sysfs-class-net-statistics`. |
| 138 | |
| 139 | |
| 140 | netlink |
| 141 | ------- |
| 142 | |
| 143 | `rtnetlink` (`NETLINK_ROUTE`) is the preferred method of accessing |
| 144 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>` stats. |
| 145 | |
| 146 | Statistics are reported both in the responses to link information |
| 147 | requests (`RTM_GETLINK`) and statistic requests (`RTM_GETSTATS`, |
| 148 | when `IFLA_STATS_LINK_64` bit is set in the `.filter_mask` of the request). |
| 149 | |
| 150 | ethtool |
| 151 | ------- |
| 152 | |
| 153 | Ethtool IOCTL interface allows drivers to report implementation |
| 154 | specific statistics. Historically it has also been used to report |
| 155 | statistics for which other APIs did not exist, like per-device-queue |
| 156 | statistics, or standard-based statistics (e.g. RFC 2863). |
| 157 | |
| 158 | Statistics and their string identifiers are retrieved separately. |
| 159 | Identifiers via `ETHTOOL_GSTRINGS` with `string_set` set to `ETH_SS_STATS`, |
| 160 | and values via `ETHTOOL_GSTATS`. User space should use `ETHTOOL_GDRVINFO` |
| 161 | to retrieve the number of statistics (`.n_stats`). |
| 162 | |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 163 | ethtool-netlink |
| 164 | --------------- |
| 165 | |
| 166 | Ethtool netlink is a replacement for the older IOCTL interface. |
| 167 | |
| 168 | Protocol-related statistics can be requested in get commands by setting |
| 169 | the `ETHTOOL_FLAG_STATS` flag in `ETHTOOL_A_HEADER_FLAGS`. Currently |
| 170 | statistics are supported in the following commands: |
| 171 | |
| 172 | - `ETHTOOL_MSG_PAUSE_GET` |
Jakub Kicinski | be85dbf | 2021-04-15 15:53:15 -0700 | [diff] [blame] | 173 | - `ETHTOOL_MSG_FEC_GET` |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 174 | |
Jakub Kicinski | 0db0c34 | 2020-09-03 16:14:31 -0700 | [diff] [blame] | 175 | debugfs |
| 176 | ------- |
| 177 | |
| 178 | Some drivers expose extra statistics via `debugfs`. |
| 179 | |
| 180 | struct rtnl_link_stats64 |
| 181 | ======================== |
| 182 | |
| 183 | .. kernel-doc:: include/uapi/linux/if_link.h |
| 184 | :identifiers: rtnl_link_stats64 |
| 185 | |
| 186 | Notes for driver authors |
| 187 | ======================== |
| 188 | |
| 189 | Drivers should report all statistics which have a matching member in |
| 190 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>` exclusively |
| 191 | via `.ndo_get_stats64`. Reporting such standard stats via ethtool |
| 192 | or debugfs will not be accepted. |
| 193 | |
| 194 | Drivers must ensure best possible compliance with |
| 195 | :c:type:`struct rtnl_link_stats64 <rtnl_link_stats64>`. |
| 196 | Please note for example that detailed error statistics must be |
| 197 | added into the general `rx_error` / `tx_error` counters. |
| 198 | |
| 199 | The `.ndo_get_stats64` callback can not sleep because of accesses |
| 200 | via `/proc/net/dev`. If driver may sleep when retrieving the statistics |
| 201 | from the device it should do so periodically asynchronously and only return |
| 202 | a recent copy from `.ndo_get_stats64`. Ethtool interrupt coalescing interface |
| 203 | allows setting the frequency of refreshing statistics, if needed. |
| 204 | |
| 205 | Retrieving ethtool statistics is a multi-syscall process, drivers are advised |
| 206 | to keep the number of statistics constant to avoid race conditions with |
| 207 | user space trying to read them. |
| 208 | |
| 209 | Statistics must persist across routine operations like bringing the interface |
| 210 | down and up. |
Jakub Kicinski | 8c00bd93 | 2020-09-14 17:11:53 -0700 | [diff] [blame] | 211 | |
| 212 | Kernel-internal data structures |
| 213 | ------------------------------- |
| 214 | |
| 215 | The following structures are internal to the kernel, their members are |
| 216 | translated to netlink attributes when dumped. Drivers must not overwrite |
| 217 | the statistics they don't report with 0. |
| 218 | |
Mauro Carvalho Chehab | 97e44c4 | 2020-10-27 10:51:10 +0100 | [diff] [blame] | 219 | - ethtool_pause_stats() |
Jakub Kicinski | be85dbf | 2021-04-15 15:53:15 -0700 | [diff] [blame] | 220 | - ethtool_fec_stats() |