summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Wong <v4l@stuffedcow.net>2011-09-18 13:41:49 +0000
committerDavid S. Miller <davem@davemloft.net>2011-09-20 15:20:58 -0400
commit22e83a2926998fe132ae4dd26f1e998c70ae2e38 (patch)
treeda0cf3a2682dbd6dd899fb932dc3cde686862b40
parentd706f00f65146822c0097b796b3557ea8980c305 (diff)
downloadlinux-3.10-22e83a2926998fe132ae4dd26f1e998c70ae2e38.tar.gz
linux-3.10-22e83a2926998fe132ae4dd26f1e998c70ae2e38.tar.bz2
linux-3.10-22e83a2926998fe132ae4dd26f1e998c70ae2e38.zip
ppp_generic: fix multilink fragment MTU calculation (again)
When using MLPPP, the maximum size of a fragment is incorrectly calculated with an offset of -2. This patch reverses the changes in the patch found here: http://marc.info/?l=linux-netdev&m=123541324010539&w=2 The value of hdrlen includes the size of both the 2-byte PPP protocol field and the 2- or 4-byte multilink header (2+4=6 for long sequence numbers, 2+2=4 for short sequence numbers). Section 2 of RFC1661 says that the MRU that is negotiated (i.e., the MTU of the sending system) includes only the PPP payload but not the protocol field, thus the correct MTU should be the link's MTU minus the multilink header (mtu - (hdrlen-2)). The incorrect calculation causes Linux to fragment packets to a size two bytes smaller than the allowed MTU. While not technically illegal, this behaviour confounds MRU-tuning to avoid PPP-layer fragmentation. Signed-off-by: Henry Wong <henry@stuffedcow.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ppp_generic.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 10e5d985afa..edfa15d2e79 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -1465,7 +1465,12 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
continue;
}
- mtu = pch->chan->mtu - hdrlen;
+ /*
+ * hdrlen includes the 2-byte PPP protocol field, but the
+ * MTU counts only the payload excluding the protocol field.
+ * (RFC1661 Section 2)
+ */
+ mtu = pch->chan->mtu - (hdrlen - 2);
if (mtu < 4)
mtu = 4;
if (flen > mtu)