Windows 7 doesn’t request MTU from DHCP server; what is it thinking

ethernetipmtunetworkingwindows 7

My computer's Ethernet adapter uses 1,500 byte Ethernet frames. Normally this means that my Local Area Connection's MTU is 1500 bytes.

But my (IPv4) connection to the Internet has some overhead. This means that my actual MTU when communicating to the Internet is 1492. This is causing all the regular problems that exist with mis-configured interface MTU.

The Router Can Fix It

Obviously i could use netsh, and override my network interface with a custom MTU. But i don't want to do that. My router's DHCP server already knows that the MTU is 1492. If asked, the DHCP Server will respond with DHCP option 26:

  • 26 MTU Interface = 1492

So it was driving me nuts why the DHCP server isn't telling my Windows 7 machine the MTU setting as one of the items it returns in the DHCP offer:

  • 54 DHCP Server Identifier = 192.168.1.1
  • 51 IP Address Lease Time = 2 hours
  • 1 Subnet Mask = 255.255.255.0
  • 15 Domain Name = example.local
  • 3 Router = 192.168.1.1
  • 6 Domain Name Server = 8.8.8.8, 8.8.4.4, 74.82.42.42

No MTU Interface! So my machine's Ethernet is stuck at 1500 bytes.

DHCP server's did what it's supposed to do

It took more digging, but i realized that DHCP Server's only give what the client asked for. During my Windows 7 DHCP Discover, Windows 7 enumerates the list of all the DHCP options it would like returned:

  • 1 Subnet Mask
  • 15 Domain Name
  • 3 Router
  • 6 Domain Name Server
  • 44 NetBIOS over TCP/IP Name Server
  • 46 NetBIOS over TCP/IP Node Type
  • 47 NetBIOS over TCP/IP Scope
  • 31 Perform Router Discovery
  • 33 Static Route
  • 121 Classless Static Route
  • 249 Classless Static Route (Microsoft)
  • 43 Vendor-Specific Information

Windows 7 isn't even asking for the MTU!

It must know what it's doing

Windows must have a reason why it's not asking for the MTU; but i don't know what it is. At first i thought it was because it was using Path Maximum MTU Discovery. But PMTU only works for TCP connections, uses the TCP MSS (Maximum Segment Size) option, and requires that the local MSS option be correct.

In my case the TCP MSS setting (which comes from the MTU option) is wrong. It is 1460 bytes

  1500 interface MTU
-   20 bytes IP header = 1480 bytes
-   20 bytes TCP header
= 1460 bytes MSS

which is too high.

Note: I can confirm Windows is using an MSS of 1460 bytes from a SYN packet, when a TCP connection is being established.

If not PathMTU, then what?

What is Windows 7 thinking? What is the intended behavior here? What were the network stack developers at Microsoft thinking should happen?

Now pretend that my Internet MTU is actually 1472 (which it is), and pretend that my Ethernet adapter actually uses 8,192 byte Ethernet frames (which it does). What is a corporation supposed to do? Am i supposed to walk up to every machine in the enterprise and type:

>netsh interface ipv4 set interface interface="Local Area Connection" mtu=1472 store=persistent

That's not reasonable. And even if it were reasonable, it's not what i'm asking.

I'm trying to understand what Windows wants to have happen. i'm trying to understand how it should behave. i'm trying to learn something here. Pretend that my Internet gateway is a 576 byte ATM; how do i instruct Windows 7 machines that the MTU if they want to send to the Internet is 576 bytes?

Bonus Reading

Best Answer

Path MTU is not TCP only and doesn't use MSS (though as you have surmised, MSS is derived from MTU). Any hop that receives a packet too big to forward will send an ICMP fragmentation needed packet back to the origin. This is part of layer 3 and is independent of TCP.

The problem with PMTU is that the incoming ICMP packets are often dropped or not forwarded to the origin, and so the origin does not know to reduce the packet size.

As your router knows that the next hop MTU is 1472, it should be sending PMTU packets to your clients. You can check this with wireshark, and if it is not doing this, it needs fixing.

You have a couple of workarounds. One is to set the inside interface of the router's MTU to 1472, which will mean it gets actioned before the router does any processing. The other option is (if you can do it with your router) is to turn on the DF bit for every packet. This is a pretty brutal workaround as any full size packets will end up as two separate packets, one small, one large, with the resultant overhead.

In a corporate setting, all three approaches may be used, but hard setting mtu on the router LAN interface is pretty common.

(I have never come across an instance where DHCP is used to mediate MTU, it wouldn't be the right place in most cases, because the internal MTU and border MTU often different, where you might use jumbo frames internally, but need to reduce to normal size for internet traffic)