This problem also appears in the ppp component.
The PPP driver in the linux kernel resets all requested MRU values less
than the default (1500) to the default. For example, if you request an MRU
of 552 (reasonable for a dialup connection), the driver actually sets it to
1500. The faulty code is in drivers/net/ppp.c:
if (temp_i < PPP_MRU)
temp_i = PPP_MRU;
The value of PPP_MRU is 1500, the default.
This problem also appears in the ppp component, at least through
ppp-2.3.11. That version also defines a constant PPP_MINMRU with the value
of 128, which is the minimum MRU allowed under IPv4. It appears that the
snippet above should actually read:
if (temp_i < PPP_MINMRU)
temp_i = PPP_MINMRU;
However, the version of include/linux/ppp_defs.h in the kernel does not
include the definition of PPP_MINMRU, so that would need to be added as
well. I am working on building a kernel to test this fix, but I am
inexperienced at custom kernel building, so it is going slowly.
To verify the bug: establish a PPP connection using pppd with the options
'kdebug 7' and 'mru 552'. The pppd log (usually /var/log/messages) will
contain the message 'ppp_ioctl: set mru to 5dc'; 0x5dc is 1500.
I suspect that this bug is causing problems with my PPP connection. While
small TCP transfers (web pages, small FTP downloads) work fine, larger
transfers stall at about 100K (large downloads, fetching a full POP
mailbox). I think that MRU 1500 is too large for my 56K modem, but the
usual dialup MRU of 552 is impossible with this driver. Other fixes, such
as clearing the asyncmap or setting -vj do not work.
It's possible that this is not a bug; perhaps the ppp driver doesn't care if the
MRU is less than 1500, because it's only concerned about buffer space or
something like that. It still seems suspicious, however; I will try to
After some more investigation, I determined that this was not in fact causing my
troubles. Setting an MRU less than 1500 seems to work just fine. I was looking
in the wrong place (oops). My problem was actually an incompatibility between
sysctl tcp_timestamps and pppd VJ compression.