Skip to content

ethtool: network interface diagnostics and tuning

Network issues hide well — interface is up, IP is assigned, iptables is quiet, yet packet loss or micro-freezes only surface under load. ethtool gives direct access to hardware state, driver behavior, and offload mechanisms that neither ip nor netstat expose.

Installation is straightforward:

# RHEL/Alma/Rocky
sudo dnf install ethtool -y

# Debian/Ubuntu
sudo apt install ethtool

Running ethtool without flags prints a summary:

$ ethtool eth0
Settings for eth0:
    Supported ports: [ TP ]
    Supported link modes:   1000baseT/Full
    Supported pause frame use: Symmetric
    Supported auto-negotiation: Yes
    Advertised link modes:  1000baseT/Full
    Advertised pause frame use: Symmetric
    Advertised auto-negotiation: Yes
    Speed: 1000Mb/s
    Duplex: Full
    Port: Twisted Pair
    PHYAD: 0
    Transceiver: internal
    Auto-negotiation: on
    MDI-X: Unknown
    Link detected: yes

First thing I check when network complaints come in — Link detected. If no, cable or transceiver is dead. Speed and Duplex tell you whether the link dropped to 100Mb/s or half-duplex.

Driver and Hardware: -i and -a

-i shows driver information:

$ ethtool -i eth0
driver: ixgbe
version: 5.19.0
firmware-version: 0x8000095d
expansion-rom-version: [trimmed]
bus-info: 0000:01:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

Firmware version matters for Intel and Broadcom — older versions have known bugs. If you do not see error counters you expect, update firmware first, not the driver.

-a displays auto-negotiation and pause settings:

$ ethtool -a eth0
Pause parameters for eth0:
Autonegotiate:  on
RX:             on
TX:             on
Warning

Disabling flow control on one end of a link without agreement on the other causes packet loss during bursty traffic. If the switch has PAUSE disabled — disable it on the host too.

Speed and Duplex: -s and autoneg

-s changes interface parameters. To set fixed speed and duplex, disable auto-negotiation first, then specify the values:

# Fix 1G full-duplex, disable auto-negotiation
sudo ethtool -s eth0 speed 1000 duplex full autoneg off

# Re-enable auto-negotiation
sudo ethtool -s eth0 autoneg on

After changing parameters, verify the link again — not all cards re-negotiate cleanly without an interface bounce.

ethtool flagPurpose
speed NSpeed in Mb/s (100, 1000, 10000, …)
duplex full|halfDuplex mode
autoneg on|offAuto-negotiation control
port tp|fiber|aui|bnc|miiPort type (not available on all cards)
advertise NBitmask of modes for auto-negotiation

All flags combine in a single call. Persisting across reboots requires writing to /etc/sysconfig/network-scripts/ifcfg-eth0 on RHEL or using a systemd override:

# RHEL-style: /etc/sysconfig/network-scripts/ifcfg-eth0
ETHTOOL_OPTS="speed 1000 duplex full autoneg off"

Offload Flags: -k, -K and Common Pitfalls

-k shows current offload flags, -K modifies them:

$ ethtool -k eth0 | head -20
Features for eth0:
tcp-segment-offload: on
tcp-segment-offload: on [fixed]
generic-segment-offload: on
generic-receive-offload: on
generic-segment-offload: on [fixed]
large-receive-offload: on
rx-vlan-offload: on
tx-vlan-offload: on [fixed]
ntuple-filters: off [fixed]
receive-hashing: off

The [fixed] label means the flag is hardware-enforced and cannot be changed.

Disabling offload flags is a frequent cause of VPN, monitoring, and virtualization issues:

# Disable TSO to force the kernel to send raw segments
sudo ethtool -K eth0 tso off

# Disable VLAN offload if the 802.1Q driver filter is buggy
sudo ethtool -K eth0 rxvlan off txvlan off

# Verify changes
ethtool -k eth0 | grep -E 'tcp-segment|vlan'
Note

GRO (generic-receive-offload) and TSO (tcp-segment-offload) work as a pair. Disabling one without the other causes fragmentation at the kernel level — CPU usage spikes for no good reason.

Statistics: -S and Packet Loss Investigation

-S outputs driver statistics. Format and available counters vary by driver:

$ ethtool -S eth0 | grep -E 'error|drop|miss'
     rx_errors: 0
     tx_errors: 0
     rx_dropped: 0
     tx_dropped: 0
     multicast: 42
     rx_no_buffer_count: 0
     rx_missed_errors: 0

For Intel drivers (ixgbe, i40e), relevant counters include:

$ ethtool -S eth0 | grep -iE 'flow-director|rss|mbus|over'
     rx_fifo_errors: 0
     rx_pause_pfc_ignored: 0
     tx_fifo_errors: 0
Tip

rx_fifo_errors and tx_fifo_errors indicate congestion. If they grow despite normal CPU utilization, the problem lies with memory or the bus.

For scripted problem detection:

#!/bin/bash
IFACE=${1:-eth0}
ethtool -S $IFACE | awk '/error|drop|miss|overflow|fifo|discard/ {if ($2 > 0) print}'

Run periodically via cron — peak loss spikes become impossible to explain retroactively.

Taskip linkethtool
Bring interface up/downip link set eth0 up/downno
MAC addressip link show eth0no
MTUip link set eth0 mtu 9000no
Speed/duplexnoethtool -s eth0 speed 1000 duplex full
Auto-negotiationnoethtool -s eth0 autoneg off
Offload flagspartially via ethtool -kethtool -K eth0 tso off
Error statisticsip -s link show eth0ethtool -S eth0 (more detailed)
Driver informationnoethtool -i eth0
Wake-on-LANnoethtool eth0 (shown in output)

ethtool does not replace ip, it complements it. Network configuration stack: ip link → ip addr → ethtool → tc.

Troubleshooting: Link/Duplex Mismatch

Classic scenario: server and switch failed to agree on parameters. Symptoms — link is up, pings work, but under load there are sudden drops.

Diagnostic sequence:

# 1. Check what the host sees
ethtool eth0 | grep -E 'Speed|Duplex|Auto-negotiation|Link'

# 2. Inspect error counters
ethtool -S eth0 | grep -iE 'error|drop|miss|fifo'

# 3. Compare with the peer
# On the switch (Cisco): show interfaces GigabitEthernet0/1

# 4. Lock parameters on both sides
# On the host:
sudo ethtool -s eth0 speed 1000 duplex full autoneg off

# On the switch (Cisco):
interface Gi0/1
  speed 1000
  duplex full
  no negotiate
Warning

Always negotiate both ends. If the switch runs fixed mode without autoneg and the host has autoneg enabled — the 802.3 standard mandates fallback behavior, but vendors implement it poorly.

If the interface still drops packets after parameter alignment, investigate:

  • Driver and firmware: update the network card firmware
  • Cable or transceiver: a 10G SFP module plugged into a 1G port without auto-negotiation guarantees loss
  • RSS and IRQ issues: cat /proc/interrupts | grep eth0, check IRQ balancing