Calculate exactly how much each tunnel or encapsulation layer eats out of your MTU — and what MSS your TCP sessions actually end up with.
Why this matters. A standard Ethernet MTU is 1500 bytes. Once you stack tunnels (GRE, VXLAN, WireGuard, IPSec) on top, each layer steals header bytes. The TCP inside thinks it has 1460 bytes of MSS, but the outer frame is now bigger than the path MTU — packets get fragmented, or silently dropped if DF is set. Path-MTU black holes are one of the most common causes of "weird, intermittent" connectivity on SD-WAN, k8s CNI overlays, and IPSec VPNs.
How it works. Start from the interface MTU (the outermost frame's payload budget). Subtract each encapsulation layer's overhead in order, outermost first. What's left after all layers is the MTU available to the inner IP packet. Subtract the IP header (20 bytes for IPv4, 40 for IPv6) and the TCP header (20 bytes default) to get the effective MSS.
Overhead table used (per layer, from RFCs):
- Ethernet header is not counted — MTU already refers to the L3 payload.
- VLAN 802.1Q — 4 bytes (adds a tag between SA and EtherType).
- Q-in-Q — 8 bytes (two VLAN tags).
- PPPoE — 8 bytes (6-byte PPPoE header + 2-byte PPP protocol).
- GRE — 4 bytes minimum; +4 if the Checksum/Key/Sequence options are present.
- VXLAN — 8 bytes (VXLAN header; outer UDP + outer IP counted separately by your encapsulating host — included here as part of the overlay budget if you're inside the tunnel).
- Geneve — 8 bytes base (variable TLVs not included).
- WireGuard — 80 bytes over IPv4 (32 outer IP + 8 outer UDP + 32 WG data msg + 8 poly1305 tag) or 100 over IPv6 (60 outer IP + 8 outer UDP + 32 WG data msg). Wider variants exist; this uses the common Noise_IK transport.
- IPSec ESP — depends on cipher + auth + trailer. AES-GCM in transport mode ≈ 55 bytes (SPI 4 + Seq 4 + IV 8 + ciphertext padding + 16-byte ICV + 2 trailer); tunnel mode ≈ +20 for the new outer IP header.
Diagnostic output. For each stack the tool reports:
- the per-layer overhead and the running total;
- the remaining MTU after encapsulation;
- the effective MSS after IP + TCP headers;
- the exact DF probe size to use with
ping -M do -s <size> (Linux) or ping -f -l <size> (Windows) to find the path MTU without fragmentation;
- a warning if the effective MSS drops below 1360 (small enough to cause TCP performance issues or PMTUD failures).
Tips.
- WireGuard users: set the WireGuard interface MTU to
outer MTU − 80 (IPv4) or − 100 (IPv6) to avoid double fragmentation.
- VXLAN in a datacenter with 1500-byte underlay: set the overlay MTU to 1450 (1500 − 50 for VXLAN + outer UDP + outer IP) to leave headroom.
- PPPoE DSL:
ping -M do -s 1472 on the WAN side tells you the true path MTU before PPPoE steals 8 more.