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 investigate further.
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.