- Unable to ping device with MTU 9000 (jumbo frame), but default ping error message shows up
- How to test if 9000 MTU/Jumbo Frames are working
- Testing#
- MacOS#
- Linux#
- Windows#
- Additional Context#
- Troubleshooting#
- Изменить размер MTU в Debian
- Тестирование
- Возможные результаты
- Изменение MTU
- How to get maximum supported MTU size for interface?
- 2 Answers 2
Unable to ping device with MTU 9000 (jumbo frame), but default ping error message shows up
I need to set a local connection with Jumbo Frames enabled. I set up my network adapter to have a MTU of 9000.
~$ ifconfig eth0: flags=4163 mtu 9000 inet 10.0.0.3 netmask 255.255.255.0 broadcast 10.0.0.255 inet6 fe80::215:5dff:fe8a:1792 prefixlen 64 scopeid 0x20 ether 00:15:5d:8a:17:92 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5 bytes 398 (398.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
I checked my network adapter settings, everything is okay. I am using WSL2 and the MTU size is 9000 in Ubuntu and on my network adapter settings (using netsh and Get-NetAdapterAdvancedProperty from Powershell). However, when I ping my reomte device (IP 10.0.0.10) by specifying the packet size, I get a fail. The strange thing is that it is not the «large packet» error message that displays, but simply the «ping failed». To compare, let me show you the result of a normal ping (#1), a ping with a packet too large (#2), and a ping with a packet that should be handled by the jumbo frame (#3).
# 1. ~$ ping 10.0.0.10 PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data. 64 bytes from 10.0.0.10: icmp_seq=2 ttl=64 time=1.49 ms # 2. ~$ ping 10.0.0.10 -c 10 -M do -s 10000 PING 10.0.0.10 (10.0.0.10) 10000(10028) bytes of data. ping: local error: message too long, mtu=9000 # 3. ~$ ping 10.0.0.10 -c 10 -M do -s 8900 PING 10.0.0.10 (10.0.0.10) 8900(8928) bytes of data. --- 10.0.0.10 ping statistics --- 10 packets transmitted, 0 received, 100% packet loss, time 9368ms
As you see, behavior #1 and #2 are normal, but not #3. The packet size is not too big to be handled by MTU (or else, I would have had the same error as #2). I looked this problem up online and the answer I found was: my PC is configured correctly, but the receiving device does NOT have a MTU big enough. However, this device is specifically made to handle these large packets, I contacted the device’s maker and they told me that it natively handles jumbo frames. The problem seems to be on my connection, but I can’t find anything.
How to test if 9000 MTU/Jumbo Frames are working
Fairly straight forward this time, you’ve configured your MTU/jumbo frames to be 9000 on your client and destination devices (say a laptop/desktop/server/san/nas) and on ALL your switching devices in between — you’ve done that right? 😉
Testing#
So the next step is, we want to test if our new 9000 byte MTU is actually working and we can reap the benefits of a larger packet size (whether it’s on iSCSI, LAN, whatever) being of course a higher latency but also higher throughput. This depends on the OS you are running.
MacOS#
On Mac OSX (that I run) it’s:
ping -D -s 8184 [destinationIP]
Note: Some commenters have noted that in newer versions of macOS (unknown from what version — but effective in 11.x and 12.x at least) that the max frame size for the ping should be as follows:
ping -D -s 8164 [destinationIP]
Linux#
ping -M do -s 8972 [destinationIP]
Windows#
ping -f -l 9000 [destinationIP]
Additional Context#
The reason for the 8972 on *nix devices is that the ICMP/ping implementation doesn’t encapsulate the 28 byte ICMP (8) + IP (20) (ping + standard internet protocol packet) header — thus we must take the 9000 and subtract 28 = 8972 .
On Mac’s even though they are *nix kernels, the ping implementation only supports packets 8192 in size so we must remove the ICMP ( 8 byte ) header as the ping implementation has already included the 20 byte IP header, 8192 — 8 = 8184 .
(Apple macs DO support packets up to 9000 bytes, just the ICMP implementation they sport doesn’t…)
EDIT 31/10/13: According to BernieC in a comment here OSX does support 9000+ byte packets if you run the following command to increase its maximum datagram size:
sudo sysctl -w net.inet.raw.maxdgram=16384
It is also important to understand where I got my values from this is an IP packet’s layout, you can see the IP info is 20 bytes:
Troubleshooting#
If you’ve forgotten to enable jumbo frames/9k MTU on your client device you’re sending the ping from you’ll see:
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 8184 data bytes ping: sendto: Message too long
If you have enabled jumbo frames on your client but not the destination (or a switch in between) you’ll see:
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 8184 data bytes Request timeout for icmp_seq 0
If you’ve done everything right and you’re set up ready to go you’ll get this:
PING xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx): 8184 data bytes 8192 bytes from xxx.xxx.xxx.xxx: icmp_seq=0 ttl=128 time=0.714 ms
Now rejoice in your lovely jumbo-framey goodness and a good 20-30% in sustained data throughput.
Why not follow @mylesagray on Twitter ↗ for more like this!
Изменить размер MTU в Debian
Стандартный MTU (Maximum Transmission Unit, то есть максимальный блок передаваемых за раз данных) составляет 1500 байт, однако может быть увеличен до числа в диапазоне 1501 — 9198, что зависит от производителя оборудования. Чтобы увеличение MTU прошло успешно, заданный размер должен поддерживаться оборудованием на обоих концах кабеля.
Тестирование
Чтобы убедиться, что ваше оборудование поддерживает большие пакеты, можно воспользоваться утилитой ping. Для тестирования на MacOS используйте команду:
ping -M do -s 8972 ip.add.re.ss
В *nix системах ping не включает заголовки ICMP (8 байт) и TCP (20 байт), поэтому мы должны вычесть их самостоятельно. Что касается MacOS, то в этом случае реализация ping не позволяет передавать больше 8192 байт, а также мы должны дополнительно вычесть 28 байт.
Возможные результаты
Если вы забыли включить jumbo frames/9k MTU на вашем клиентском устройстве, то получите следующий вывод:
PING ip.add.re.ss (ip.add.re.ss): 8184 data bytes ping: sendto: Message too long
Если вы увеличили размер MTU на клиенте, но не на конечной точке (или свиче посередине), то вывод будет следующим:
PING ip.add.re.ss (ip.add.re.ss): 8184 data bytes Request timeout for icmp_seq 0
Если же все хорошо, то результат работы ping будет таким:
PING ip.add.re.ss (ip.add.re.ss): 8184 data bytes 8192 bytes from ip.add.re.ss: icmp_seq=0 ttl=128 time=0.714 ms
Изменение MTU
Как же изменить MTU в Debian? Выполните команду:
ip link set eth0 mtu 9000
Не забыв подставить имя нужного интерфейса.
Если вы пытаетесь изменить MTU и получаете сообщение «SIOCSIFMTU: Invalid argument», значит драйвер вашей сетевой карты не поддерживает данное значение MTU.
Чтобы новое значение MTU применялось при старте системы добавьте строку «mtu 9000» к описанию интерфейса в файле /etc/network/interfaces. К примеру, так:
auto eth1 iface eth1 inet static address 192.168.0.2 netmask 255.255.255.0 network 192.168.0.0 broadcast 192.168.0.255 mtu 9000
How to get maximum supported MTU size for interface?
However different interfaces and different machines appear to have different limits resulting in an error:
Error: mtu greater than device maximum.
I’m trying to find a way to check if NIC supporting a specific MTU size or not without trying to set it first; actually, I want to find the theoretical maximum MTU on all interfaces on all my servers. I’ve inspected all features of ethtool, looked in /sys/class/net, etc, but all I can find is the current MTU value. Are there a way to see how high MTU can be on interface without trying it?
I don’t know of any cananonical way to find out what you want, but you must ask yourself why do you want to change the MTU. 9/10 cases, your default MTU is just fine. And there is something to be said about jumbo frames, as seen here : archive.nanog.org/sites/default/files/…
I can answer this question pretty easily: because we are running network appliances and those are asking to provide them with as much MTU as we could in their cluster fabric network, but it should be the same MTU on all servers. So I want to see what number can I make without breaking stuff in the process (so, no trial and error).
@GeorgeShuklin I’ve edited the question to aid future readers, feel free to revert the edit if you think it is incorrect.
2 Answers 2
Amazingly, I found that ip reports this information if asked.
21: enxa44cc8aa52bd: mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000 link/ether a4:4c:c8:aa:52:bd brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 9194 addrgenmode none numtxqueues 1 numrxqueues 1 gso_max_size 16354 gso_max_segs 65535
minmtu and maxmtu is the answer.
Note that the reduced ip command included in busybox does not support the -d option to show the minmtu and maxmtu .
I would presume though it should be ip -d link show . Although the list works, but I don’t see it mentioned in man ip-iink or zsh autcompletions when pressing TAB. I would guess using list is deprecated.
you can send a specific mtu size with ping
being the local ip of the interface you wish to check.
Note there is an additional 28 bytes as a header when using this method.
Just keep increasing the mtu size (in the ping command) until you get a Message too long error or similar.
Current MTU setting and IP:
[root@centos7 ~]# ip l | grep ens37 | awk '' mtu 1500 [root@dev-worker1 ~]# ip addr show ens37 | grep "inet " | awk '' 10.10.10.10/24
sending a packet larger than the current MTU setting, but is still accepted:
[root@centos7 ~]# ping -M do -s 8972 10.10.10.10 PING 10.10.10.10 (10.10.10.10) 8972(9000) bytes of data. 8980 bytes from 10.10.10.10: icmp_seq=1 ttl=64 time=0.103 ms 8980 bytes from 10.10.10.10: icmp_seq=2 ttl=64 time=0.067 ms
Sending one too large. Some distros may actually tell you the maximum via this method. E.g Centos7:
[root@centos7 ~]# ping -M do -s 118972 10.10.10.10 Error: packet size 118972 is too large. Maximum is 65507
Once done, you can set it to the maximum if that’s what you desire using ip link
- Clarified I’m referring to pinging a local IP and provided example.
- I do not know for sure that some distros will output the actual limit, as my testing environment interfaces have max capabilities of 65535 bytes.