summaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_eth.c
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2018-08-03 12:38:39 +0200
committerDavid S. Miller <davem@davemloft.net>2018-08-03 10:03:57 -0700
commite9697e2effad50c0081b3c72002d3975f8ab4347 (patch)
treeffa8f583cf4fedb528944b3b1121a1471bd7f6eb /net/l2tp/l2tp_eth.c
parent789141b215fc509defdd0f0978e4bf1bb5b31fc2 (diff)
downloadlinux-e9697e2effad50c0081b3c72002d3975f8ab4347.tar.gz
linux-e9697e2effad50c0081b3c72002d3975f8ab4347.tar.bz2
linux-e9697e2effad50c0081b3c72002d3975f8ab4347.zip
l2tp: ignore L2TP_ATTR_MTU
This attribute's handling is broken. It can only be used when creating Ethernet pseudo-wires, in which case its value can be used as the initial MTU for the l2tpeth device. However, when handling update requests, L2TP_ATTR_MTU only modifies session->mtu. This value is never propagated to the l2tpeth device. Dump requests also return the value of session->mtu, which is not synchronised anymore with the device MTU. The same problem occurs if the device MTU is properly updated using the generic IFLA_MTU attribute. In this case, session->mtu is not updated, and L2TP_ATTR_MTU will report an invalid value again when dumping the session. It does not seem worthwhile to complexify l2tp_eth.c to synchronise session->mtu with the device MTU. Even the ip-l2tp manpage advises to use 'ip link' to initialise the MTU of l2tpeth devices (iproute2 does not handle L2TP_ATTR_MTU at all anyway). So let's just ignore it entirely. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_eth.c')
-rw-r--r--net/l2tp/l2tp_eth.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index cfca5e63ae31..3728986ec885 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -234,14 +234,11 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
overhead += sizeof(struct udphdr);
dev->needed_headroom += sizeof(struct udphdr);
}
- if (session->mtu != 0) {
- dev->mtu = session->mtu;
- dev->needed_headroom += session->hdr_len;
- return;
- }
+
lock_sock(tunnel->sock);
l3_overhead = kernel_sock_ip_overhead(tunnel->sock);
release_sock(tunnel->sock);
+
if (l3_overhead == 0) {
/* L3 Overhead couldn't be identified, this could be
* because tunnel->sock was NULL or the socket's
@@ -255,12 +252,12 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
*/
overhead += session->hdr_len + ETH_HLEN + l3_overhead;
- /* If PMTU discovery was enabled, use discovered MTU on L2TP device */
- mtu = l2tp_tunnel_dst_mtu(tunnel);
- if (mtu)
+ mtu = l2tp_tunnel_dst_mtu(tunnel) - overhead;
+ if (mtu < dev->min_mtu || mtu > dev->max_mtu)
+ dev->mtu = ETH_DATA_LEN - overhead;
+ else
dev->mtu = mtu;
- session->mtu = dev->mtu - overhead;
- dev->mtu = session->mtu;
+
dev->needed_headroom += session->hdr_len;
}