Skip to content
LinkState
Go back

The ICMP boundary that broke PMTUD everywhere

Introduction to MTU and Packet Fragmentation

Maximum Transmission Unit (MTU) defines the largest IP packet size (including header) that a link can transmit without fragmentation. On Ethernet the default is 1500 bytes. When a packet exceeds the egress interface MTU, the sending host must either fragment the packet (IPv4) or drop it and rely on ICMP Packet Too Big (PTB) feedback to discover a smaller usable size (Path MTU Discovery, PMTUD). Mis‑aligned MTU across a path causes either unnecessary fragmentation (CPU overhead, possible reassembly failures) or silent packet loss when PTB is blocked.

In IPv4, if a router receives a packet larger than the outgoing MTU and the DF (Don’t Fragment) bit is clear, it splits the packet into fragments, each carrying a fragment offset and the More Fragments (MF) flag. The receiver reassembles using the Identification field. In IPv6, routers never fragment; they drop oversized packets and send an ICMPv6 PTB message back to the source. Fragmentation adds per‑fragment header overhead (20 bytes IPv4) and requires the receiver to hold all fragments until the last arrives, increasing buffer pressure and latency.

The Role of Filtering Boundaries in Network Traffic Management

Filtering boundaries are points where traffic is inspected and either permitted or denied based on policy. Common implementations:

Their primary function is to enforce security, QoS, or traffic engineering policies. Mis‑configured rules can inadvertently drop legitimate control plane traffic, such as ICMP PTB.

Configuring Filtering Boundaries for Optimal Network Performance

Performance‑oriented filtering avoids deep packet inspection on high‑speed paths and keeps rule sets small and ordered. Example using nftables on a Linux host acting as a border router:

# Flush existing table
nft flush table ip filter

# Create a baseline table
nft add table ip filter
nft add chain ip filter input { type filter hook input priority 0 ; }
nft add chain ip filter forward { type filter hook forward priority 0 ; policy drop ; }
nft add chain ip filter output { type filter hook output priority 0 ; }

# Allow established/related traffic
nft add rule ip filter input ct state established,related accept
nft add rule ip filter forward ct state established,related accept

# Permit ICMP echo request/reply (for basic reachability)
nft add rule ip filter input icmp type echo-request accept
nft add rule ip filter input icmp type echo-reply accept

# ***CRITICAL***: Explicitly allow ICMP Packet Too Big (type 3, code 4)
nft add rule ip filter input icmp type destination-unreachable icmp code frag-needed accept

# Drop everything else (default drop already set on forward)
nft add rule ip filter input drop

If the rule allowing icmp type destination-unreachable icmp code frag-needed is omitted or overridden by a later drop, PTB messages are consumed by the filter, breaking PMTUD.

Packet Too Big Feedback and Its Relation to MTU

Understanding ICMP Packet Too Big Messages

ICMPv4 Destination Unreachable, Code 4 (Fragmentation Needed and DF Set) and its IPv6 equivalent (ICMPv6 Type 2, Code 0) convey the MTU of the next hop that caused the drop. The payload includes the original IP header plus the first 64 bytes of the datagram, enabling the source to infer the problematic MTU.

How Packet Too Big Feedback Affects Network Traffic

When PTB is received, the source host reduces its outgoing MTU (or TCP MSS) and retransmits with a smaller segment. If PTB is lost, the sender continues to transmit oversized packets:

The symptom appears as intermittent timeouts, application‑level retries, or “random” service errors, while underlying counters show increased packet drops on the offending interface.

Local Retries and Random Service Errors

Causes of Local Retries and Their Impact on Network Performance

Local retries originate from the transport layer (TCP retransmit timer) or application layer (e.g., HTTP client retry) when an ACK is not received within the timeout. Causes include:

Each retry incurs an exponential backoff, consuming CPU and adding latency. In high‑frequency services (e.g., RPC, database connections), a small packet loss rate can amplify into noticeable latency spikes and throughput collapse.

Distinguishing Between Local Retries and Random Service Errors

A reliable way to differentiate is to capture traffic with tcpdump and verify whether the missing ACK follows an oversized IP packet (length > egress MTU) that never elicits an ICMP PTB.

Containment Layers and Their Role in Preventing Fabric‑Wide Incidents

Containment layers limit the blast radius of a misconfiguration:

  1. Link‑level MTU enforcement – switch port MTU, server NIC MTU, and host‑level ip link set mtu. If all devices in a segment agree, oversized packets are dropped locally before entering the fabric.
  2. Ingress PTB whitelist – firewall rules that explicitly allow ICMP PTB (as shown earlier). This is a control‑plane containment: it ensures feedback can traverse the boundary.
  3. eBPF/XDP drop‑oversized – attach an XDP program that drops packets exceeding a safe MTU before they reach the routing table, preventing them from being forwarded with DF set.
  4. BGP flowspec MTU policing – propagate a rule that limits packet size on edge routers, causing early drop and PTB generation closer to the source.
  5. Service‑side MSS clamping – TCP stacks (Linux net.ipv4.tcp_mtu_probing=2) automatically reduce MSS based on PTB, limiting the amount of data sent per segment.

If any of these layers is missing or mis‑configured, a local MTU mismatch can propagate outward, causing fabric‑wide blackholes.

Configuring Containment Layers for Optimal Network Performance

Example: enforce an MTU ceiling of 1500 on a Linux bridge used in a Containerlab topology, and attach an XDP program that drops packets >1500 before they reach the routing stack.

# Create bridge
ip link add name br0 type bridge
ip link set dev br0 up
# Set bridge MTU
ip link set dev br0 mtu 1500

# Add member interfaces (veth pairs from lab)
ip link set dev veth1 master br0
ip link set dev veth2 master br0
ip link set dev veth1 up
ip link set dev veth2 up

# Simple XDP drop program (C, compiled with clang)
cat > /opt/xdp_drop_oversized.c <<'EOF'
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/in.h>

SEC("xdp")
int drop_oversized(struct xdp_md *ctx) {
    void *data_end = (void *)(long)ctx->data_end;
    void *data = (void *)(long)ctx->data;
    struct ethhdr *eth = data;
    if ((void *)(eth + 1) > data_end)
        return XDP_PASS;

    if (eth->h_proto == htons(ETH_P_IP)) {
        struct iphdr *ip = data + sizeof(struct ethhdr);
        if ((void *)(ip + 1) > data_end)
            return XDP_PASS;
        uint16_t tot_len = ntohs(ip->tot_len);
        if (tot_len > 1500)   // MTU + IP header (20) + eth header (14) = 1534 on wire
            return XDP_DROP;
    }
    return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
EOF

# Compile and load
clang -O2 -target bpf -c /opt/xdp_drop_oversized.c -o /opt/xdp_drop_oversized.o
ip link set dev br0 xdp obj /opt/xdp_drop_oversized.o sec xdp

The XDP drop ensures that any packet exceeding 1500 bytes on the wire is discarded before it could be forwarded with DF set, preventing the generation of blackhole traffic. The bridge MTU ensures that even if a host attempts to send a larger frame, the link layer will fragment or drop it locally, providing a second containment layer.

Case Study: MTU Incident Due to Policy Mistake

Background and Causes of the Incident

A Containerlab topology simulated a three‑tier leaf‑spine fabric. Leaf switches were configured with an MTU of 9000 (jumbo frames) to support storage traffic. Hosts attached to the leaves retained the default Ethernet MTU of 1500. A leaf‑side ACL was tightened to drop all ICMP traffic except echo‑request/reply for “security hardening”. The ACL omitted the PTB rule (ICMP Type 3, Code 4). Consequently:

Analysis of the Incident and Its Impact on Network Performance

The incident remained undetected for ~15 minutes until application latency alerts fired, at which point the MTU mismatch was identified by comparing ip link show on hosts vs. switches.

Troubleshooting MTU‑Related Issues

Identifying and Diagnosing MTU‑Related Problems

  1. Verify interface MTU on both ends: ip link show dev <iface>.
  2. Test Path MTU using ping with DF set:
    # Determine the largest packet that gets through without fragmentation
    ping -M do -s 1472 <destination>   # 1472 + 28 (IP+ICMP) = 1500
    Increase size until you get “Frag needed and DF set” (or timeout). The last successful size minus 28 is the path MTU.
  3. Capture ICMP PTB:
    tcpdump -i any icmp and icmp[0]=3 and icmp[1]=4 -w ptb.pcap
    Absence of

Share this post on:

Previous Post
EVPN MAC mobility storms after isolation gaps
Next Post
Canarying MTU fixes without creating new loss