ethtool Command Explained: Linux NIC Diagnostics Guide - 夜莺博客

ethtool Command Explained: Linux NIC Diagnostics Guide

When a Linux server has slow, flaky or dead networking, ethtool is the tool that separates software problems from hardware ones - it reads settings and statistics straight from the NIC driver. This guide explains the core ethtool invocations every sysadmin needs: checking link state, driver and firmware versions, ring buffers, offload features, and the error counters that point to bad cables, dirty optics or overruns.

Basic Link and Driver Checks

ethtool eth0            # speed, duplex, auto-negotiation, link detected
ethtool -i eth0         # driver, version, firmware-version, bus-info
ethtool eth0 | grep -i speed

An outdated or mismatched driver is a classic hidden cause of packet loss; ethtool -i shows exactly which driver and firmware the NIC is running so you can compare with the vendor's recommended version.

Two facts make ethtool uniquely useful. First, it talks to the kernel driver, not to the network stack, so its answers are independent of routing, firewalls, VLANs and everything else in the path. Second, it reports both the negotiated state and the supported state, which is how you tell "the NIC cannot do 10G" apart from "the cable cannot do 10G".

If the interface name is wrong you will get Cannot get device settings: No such device. List the real names first, and remember that predictable naming on modern distributions produces names like enp3s0f0 or ens192 rather than eth0:

ip -br link show
ls /sys/class/net/
ethtool -S enp3s0f0 | head -20

Reading ethtool eth0 Output Line by Line

Settings for eth0:
        Supported ports: [ TP ]
        Supported link modes:   1000baseT/Full
                                10000baseT/Full
        Supported pause frame use: Symmetric
        Supports auto-negotiation: Yes
        Advertised link modes:  10000baseT/Full
        Advertised pause frame use: No
        Speed: 10000Mb/s
        Duplex: Full
        Port: Twisted Pair
        Auto-negotiation: on
        Link detected: yes

What each block tells you in a troubleshooting scenario:

  • Supported vs Advertised link modes — the NIC supports both 1G and 10G but is advertising only 10G. That distinction is why a link to a 1G switch sometimes refuses to come up: the port is offering a mode the peer cannot match.
  • Speed and Duplex — Duplex: Half on a modern link is a red flag. Half duplex with a full-duplex peer produces collisions, late collisions and miserable throughput, and it almost always means auto-negotiation failed on one end.
  • Auto-negotiation — off with a fixed speed means someone forced the setting. If the peer is still negotiating, you get exactly the duplex mismatch described above.
  • Link detected — no means the physical layer is down: cable, module, or the far-end port. Nothing above Layer 1 is worth investigating until this says yes.

Diagnosing with Statistics and Self-Tests

ethtool -S eth0 | grep -i error   # rx/tx errors, drops, CRC
ethtool -t eth0                   # NIC self-test
ethtool -g eth0                   # ring buffer sizes
ethtool -d eth0                   # register dump

Interpreting common counters: rx_dropped/tx_dropped often mean ring buffer overflow, rx_crc_errors point at physical-layer problems (cable or optics), and rx_fifo_errors suggest interrupt handling lag. If the self-test passes but errors persist, suspect the cable or the switch port instead of the NIC.

Not every driver exposes the same counter names. The portable approach is to filter for the handful of counters that matter and ignore the vendor-specific noise:

ethtool -S eth0 | grep -Ei 'err|drop|discard|miss|fifo|nobuf|overrun'
ethtool -S eth0 | grep -Ei 'crc|align|carrier|collision'

On many drivers the accumulators sit in a companion block — for example rx_errors, tx_errors, rx_crc_errors, rx_missed_errors and rx_length_errors are reported beside the main statistics and are easy to overlook. Cross-checking ethtool -S against ip -s link show eth0 is worthwhile, because the two views disagree when a driver keeps its counters in different places.

Interpreting the Counters You Will Actually See

  • rx_crc_errors / rx_frame_errors — frames arrived corrupted. Cable, connector, SFP or duplex mismatch. Almost never the NIC itself.
  • rx_length_errors / rx_over_errors — an MTU mismatch at Layer 2, or a frame larger than the interface can hold.
  • rx_missed_errors / rx_fifo_errors — packets lost because the driver could not empty the FIFO fast enough. Raise the ring buffer or fix interrupt coalescing and CPU affinity.
  • rx_dropped / tx_dropped — dropped in software. A rising rx_dropped with a healthy CRC count is a host problem (ring buffer, softirq backlog), not a network problem.
  • tx_aborted_errors / tx_carrier_errors — the transmit side gave up; usually duplex or link-partner trouble.
  • rx_nohandler / rx_otherhost_dropped — seen on bonded or bridged interfaces; frames arrived for a port that should not have received them, which often indicates a stale MAC or a misconfigured bond.

The practical rule: physical-layer counters (CRC, frame, carrier) point outward to the cable and the peer, while buffer counters (dropped, missed, fifo) point inward to the host. Reading them together tells you which side of the wire to investigate.

Checking and Tuning Offload Features

ethtool -k eth0        # offload features: TSO, GRO, GSO, checksum offload
ethtool -K eth0 tso on # enable TCP segmentation offload
ethtool -c eth0        # coalescing settings
ethtool -a eth0        # pause frame settings

Offloading lets the NIC do work the CPU would otherwise do. Verify the offload features are actually on with -k before blaming CPU for slow throughput, and remember that changing settings with -s or -K can disrupt the connection if done on the interface you are using.

The features that matter most in practice:

  • tso / gso / gro — segmentation and reassembly offload. Disabling them is standard advice when collecting packet captures, because hardware-generated segments do not appear as separate frames to tcpdump; the captured stream looks like giant packets or looks wrong entirely.
  • tx / rx checksumming — when -K reports them as off [fixed], they cannot be enabled; when they are on [fixed], they cannot be disabled by software. Comparing the fixed state with the requested state is the fastest way to understand what a NIC really does.
  • rx-vlan-offload / tx-vlan-offload — frequently disabled on virtualised or bridged interfaces because the hypervisor or bridge handles tags itself. Leaving them on in a VLAN-aware bridge is a classic cause of duplicated or missing 802.1Q headers.
  • large-receive-offload (LRO) — usually off on routers, bridges and any host forwarding traffic, because LRO rewrites packets in a way that breaks forwarding. GRO is the safe substitute.
  • pause frame settings (-a) — relevant on links to switches where flow control is enabled; a mismatch in autonegotiation of pause frames can cause throughput collapse under load.

Ring Buffers and Interrupt Coalescing

ethtool -g eth0                    # show current and maximum ring sizes
ethtool -G eth0 rx 4096 tx 4096    # raise ring buffers
ethtool -c eth0                    # interrupt coalescing settings
ethtool -C eth0 rx-usecs 32        # adjust coalescing

Ring buffers are the NIC's receive queues. When traffic arrives faster than the driver can drain the queues, packets are dropped and rx_dropped climbs — a host-side problem that looks identical to network loss from the application's point of view. The default is often 256 or 512 descriptors on a busy 10G port, which is not enough for bursty storage traffic or a firewall workload.

Raising them helps throughput at the cost of memory and, at very large values, latency. The pairing that usually works well for throughput-oriented servers is a larger ring plus moderate coalescing — for example rx-usecs 32 — while latency-sensitive workloads want smaller coalescing values so interrupts fire sooner. On multi-queue NICs, coalescing can be set per queue:

ethtool -l eth0            # number of channels (queues)
ethtool -L eth0 combined 8 # set combined queues
ethtool -S eth0 | grep -i queue | head

Check that the number of queues is a sensible fraction of the CPU count, and that irqbalance or a manual affinity scheme is distributing interrupts. A NIC with sixteen queues pinned to one core will drop packets no matter how large the ring buffer is.

Optics and Advanced Checks

ethtool -m eth0        # SFP/SFP+ module diagnostics (DOM)
ethtool --show-priv-flags eth0   # vendor private flags
ethtool -e eth0        # EEPROM dump

On fiber links, ethtool -m reads the optical module's Digital Optical Monitoring data - transmit and receive power levels that immediately reveal a dirty connector or a failing optics.

What to look for in the DOM output:

  • Transmitter output power — within the vendor's range, typically between about -3 dBm and +1 dBm for 10G SR optics.
  • Receiver signal average optical power — the light actually arriving. Compare it against the receiver sensitivity spec; a reading near the lower limit means the loss budget is exhausted.
  • Vendor name and part number — confirms whether the module is the one you think is installed, and whether it matches the far end.
  • Warnings and alarms — the high and low thresholds printed beside each value. Any value outside them is flagged, which is the fastest possible confirmation of a failing optic.

A receive level that is acceptable on one end and low on the other points at one direction of the fiber path — a single dirty ferrule, a bent patch lead or a bad splice. That directional asymmetry is exactly the kind of fault Layer 2 tools cannot see, and it is why ethtool -m belongs in the first-response toolkit for any fiber link.

For copper links, the equivalent first-response tool is the cable test, available on some drivers:

ethtool --cable-test eth0
ethtool --cable-test-tdr eth0    # time-domain reflectometry details

Not every driver supports these; when it does, the result reports pair-by-pair status and, with TDR, the distance to the fault. A pair that reports as open or short immediately tells you the cable is the problem rather than the port.

Changing Speed, Duplex and Auto-negotiation

ethtool -s eth0 speed 1000 duplex full autoneg on
ethtool -s eth0 speed 10000 duplex full

Forcing speed and duplex is occasionally necessary for older peers, but it is worth understanding the trap: if you disable auto-negotiation on one side only, the peer cannot advertise its capabilities and you will usually end up with a duplex mismatch — the peer settles on half duplex while you are running full duplex. The resulting symptoms (errors climbing, throughput collapsing under load, no obvious link-down event) are among the most misdiagnosed problems in networking. If you must hardcode, hardcode both ends, or leave auto-negotiation on and let the two sides find each other.

Note also that modern high-speed links often refuse to negotiate below a fixed set of speeds, and some NICs do not allow -s at all with Cannot set new settings: Operation not supported. In that case the speed is determined by the module and the driver, and the only remedies are a different optic or a different port.

Persisting Settings Across Reboots

Every ethtool -s, -K, -G and -C change is runtime-only and disappears on reboot or on a driver reload. The options, roughly in order of robustness:

  • NetworkManager — nmcli connection modify <name> 802-3-ethernet.wake-on-lan magic for power features, and ethtool offloads via the connection's ethtool.feature-*, ethtool.ring-* and ethtool.coalesce-* properties.
  • systemd-networkd — the [Link] section of a .link file, with settings such as RxBufferSize, TXQueueLength and the Feature* keys.
  • udev rules — a debatable but very portable fallback: ACTION=="add", SUBSYSTEM=="net", KERNEL=="enp3s0f0", RUN+="/sbin/ethtool -K enp3s0f0 gro on".
  • Simple init script or systemd unit — acceptable for a one-off setting on a pet server, and easy to audit.

Whichever mechanism you use, be aware that offload and ring settings may be reset by a driver reload (for example after a firmware update or a bonding change), not only by a reboot. Verify after any driver-level event.

Common Errors and Fixes

  • No such device - wrong interface name; list interfaces with ip link show.
  • Operation not permitted - settings changes require root; re-run with sudo.
  • Setting changes lost after reboot - ethtool changes are runtime only; persist them via udev rules, systemd or your network manager config.
  • Cannot get module EEPROM information — the interface has no pluggable module (copper or onboard ports), or the driver does not expose DOM data.
  • Cannot get device ring settings: Operation not supported — the driver does not implement ring buffer control; the value is fixed in firmware.
  • netlink error: Operation not supported — the requested feature cannot be changed on this NIC. Check ethtool -k for the [fixed] marker.
  • Statistics all zero — some virtual interfaces and bridges report counters elsewhere; check ip -s link or the hypervisor's view of the vNIC instead.

A Quick Diagnostic Workflow

  1. ethtool eth0 — is the link up, and at the speed and duplex you expect?
  2. ethtool -i eth0 — which driver and firmware are running?
  3. ethtool -S eth0 | grep -Ei 'err|drop' — are there errors, and are they physical-layer or buffer counters?
  4. ethtool -m eth0 — on fiber, are the light levels healthy in both directions?
  5. ethtool -g eth0 and ethtool -S again — if the errors are drops, are the ring buffers large enough?
  6. ethtool -k eth0 — are the offloads in the state you expect for this role?

In roughly that order, the output narrows the fault to cable, module, driver, or host configuration without touching anything above Layer 2. That is the whole point of the tool: it answers Layer 1 and Layer 2 questions definitively, so you can stop guessing about them and move up the stack.

FAQ

Does ethtool work on wireless interfaces? Most wireless drivers do not implement the ETHTOOL_GSET interface, so ethtool wlan0 reports limited or no settings. Use iw and iwconfig for wireless link information instead.

Can I use ethtool on a bond or bridge? Yes for statistics and features, and this is often useful, but speed and duplex are governed by the member interfaces. Configure those individually.

Why do packet captures look wrong after enabling offloads? Hardware segmentation and checksum offload mean the kernel sees large, not-yet-checksummed frames. Disable TSO, GSO and checksum offload with ethtool -K before capturing, then re-enable them.

Is ethtool deprecated? No. It remains the standard interface to NIC parameters and is actively maintained; nstat, ss, ip -s and tcpdump answer different questions at higher layers.

Pair this with Linux network troubleshooting with ss, netstat and tcpdump for the full toolchain, optical module link maintenance for the fiber side of link problems, Jumbo Frame MTU Mismatch: Ping DF Bit Troubleshooting for MTU-related drops and iperf3 Bandwidth Testing Guide to measure the throughput you are trying to fix.

原文链接:https://ioflood.com/blog/ethtool-linux-command