VLADYSLAV PASHYNSKYKH

How to calculate the right MTU size for WireGuard


WireGuard might not work for you under specific conditions, such as when using the internet via PPPoE. This could happen when the default MTU size of 1420 bytes is too large. But why could that happen, and how do you calculate the right MTU size?

Packet structure

The maximum MTU for cable and fiber optic connections is 1500 bytes. However, for DSL connections established via PPPoE, an additional 8-byte header is required, which changes the maximum MTU to 1492 bytes.

The IPv4 header takes up an additional 60 bytes. But if you use IPv6, it will be 80 bytes.

Since WireGuard uses UDP by default, an additional 8 bytes are needed for the UDP header.

Then comes the WireGuard header itself, which consists of1:

This makes the WireGuard header a total of 32 bytes.

Calculating the right MTU size

So, let’s calculate how many bytes per packet we need for WireGuard via DSL with IPv4:

  1500 (maximum MTU)
-    8 (PPPoE header)
-   60 (IPv4 header)
-    8 (UDP header)
-   32 (WireGuard header)
------
= 1392 bytes

Under these conditions, the maximum MTU is 1392 bytes.

A little experiment

If you want to test that yourself, you can make an experiment with ping.

You’ll need the following options:

So, what you want to do, is to run the ping and decrease the maximum <packet_size> of 1500 by 2 bytes with each execution, until the ping starts working:

ping -t3 -D -s <packet_size> 1.1.1.1

If you have a DSL internet connection with IPv4 and have disabled the VPN, it will start working when the packet size is set to 1424:

~> ping -t3 -D -s 1424 1.1.1.1
PING 1.1.1.1 (1.1.1.1): 1424 data bytes
1432 bytes from 1.1.1.1: icmp_seq=0 ttl=59 time=26.717 ms
1432 bytes from 1.1.1.1: icmp_seq=1 ttl=59 time=23.710 ms
1432 bytes from 1.1.1.1: icmp_seq=2 ttl=59 time=19.754 ms

B-b-but…

Wait, didn’t we calculate the maximum to be 1392 bytes? What happened?

It’s simple. The ICPM used for ping adds 8 bytes, so you see 1432 bytes in the output. Another 60 bytes are added by the IPv4 header. So in total, we have a maximum of 1492 bytes (1424 + 8 + 60).