aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-08-03 13:03:57 -0400
committerDavid S. Miller <davem@davemloft.net>2018-08-03 13:03:57 -0400
commit723a00436adc2ab474a2501c18a8e72ea1fc73f1 (patch)
treeffa8f583cf4fedb528944b3b1121a1471bd7f6eb
parentf3184645cb0409d4ab0e63d65a0adcb565f55df4 (diff)
parente9697e2effad50c0081b3c72002d3975f8ab4347 (diff)
Merge branch 'l2tp-mtu'
Guillaume Nault says: ==================== l2tp: sanitise MTU handling on sessions Most of the code handling sessions' MTU has no effect. The ->mtu field in struct l2tp_session might be used at session creation time, but neither PPP nor Ethernet pseudo-wires take updates into account. L2TP sessions don't have a concept of MTU, which is the reason why ->mtu is mostly ignored. MTU should remain a network device thing. Therefore this patch set does not try to propagate/update ->mtu to/from the device. That would complicate the code unnecessarily. Instead this field and the associated ioctl commands and netlink attributes are removed. Patch #1 defines l2tp_tunnel_dst_mtu() in order to simplify the following patches. Then patches #2 and #3 remove MTU handling from PPP and Ethernet pseudo-wires respectively. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/uapi/linux/l2tp.h2
-rw-r--r--net/l2tp/l2tp_core.c1
-rw-r--r--net/l2tp/l2tp_core.h20
-rw-r--r--net/l2tp/l2tp_debugfs.c3
-rw-r--r--net/l2tp/l2tp_eth.c25
-rw-r--r--net/l2tp/l2tp_netlink.c9
-rw-r--r--net/l2tp/l2tp_ppp.c74
7 files changed, 47 insertions, 87 deletions
diff --git a/include/uapi/linux/l2tp.h b/include/uapi/linux/l2tp.h
index 8bb8c7cfabe5..61158f5a1a5b 100644
--- a/include/uapi/linux/l2tp.h
+++ b/include/uapi/linux/l2tp.h
@@ -119,7 +119,7 @@ enum {
119 L2TP_ATTR_IP_DADDR, /* u32 */ 119 L2TP_ATTR_IP_DADDR, /* u32 */
120 L2TP_ATTR_UDP_SPORT, /* u16 */ 120 L2TP_ATTR_UDP_SPORT, /* u16 */
121 L2TP_ATTR_UDP_DPORT, /* u16 */ 121 L2TP_ATTR_UDP_DPORT, /* u16 */
122 L2TP_ATTR_MTU, /* u16 */ 122 L2TP_ATTR_MTU, /* u16 (not used) */
123 L2TP_ATTR_MRU, /* u16 (not used) */ 123 L2TP_ATTR_MRU, /* u16 (not used) */
124 L2TP_ATTR_STATS, /* nested */ 124 L2TP_ATTR_STATS, /* nested */
125 L2TP_ATTR_IP6_SADDR, /* struct in6_addr */ 125 L2TP_ATTR_IP6_SADDR, /* struct in6_addr */
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index c61a467fd9b8..ac6a00bcec71 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1674,7 +1674,6 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
1674 if (cfg) { 1674 if (cfg) {
1675 session->pwtype = cfg->pw_type; 1675 session->pwtype = cfg->pw_type;
1676 session->debug = cfg->debug; 1676 session->debug = cfg->debug;
1677 session->mtu = cfg->mtu;
1678 session->send_seq = cfg->send_seq; 1677 session->send_seq = cfg->send_seq;
1679 session->recv_seq = cfg->recv_seq; 1678 session->recv_seq = cfg->recv_seq;
1680 session->lns_mode = cfg->lns_mode; 1679 session->lns_mode = cfg->lns_mode;
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index fa5ae9432d38..5804065dfbfb 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -12,6 +12,9 @@
12#ifndef _L2TP_CORE_H_ 12#ifndef _L2TP_CORE_H_
13#define _L2TP_CORE_H_ 13#define _L2TP_CORE_H_
14 14
15#include <net/dst.h>
16#include <net/sock.h>
17
15/* Just some random numbers */ 18/* Just some random numbers */
16#define L2TP_TUNNEL_MAGIC 0x42114DDA 19#define L2TP_TUNNEL_MAGIC 0x42114DDA
17#define L2TP_SESSION_MAGIC 0x0C04EB7D 20#define L2TP_SESSION_MAGIC 0x0C04EB7D
@@ -61,7 +64,6 @@ struct l2tp_session_cfg {
61 int peer_cookie_len; /* 0, 4 or 8 bytes */ 64 int peer_cookie_len; /* 0, 4 or 8 bytes */
62 int reorder_timeout; /* configured reorder timeout 65 int reorder_timeout; /* configured reorder timeout
63 * (in jiffies) */ 66 * (in jiffies) */
64 int mtu;
65 char *ifname; 67 char *ifname;
66}; 68};
67 69
@@ -105,7 +107,6 @@ struct l2tp_session {
105 int reorder_timeout; /* configured reorder timeout 107 int reorder_timeout; /* configured reorder timeout
106 * (in jiffies) */ 108 * (in jiffies) */
107 int reorder_skip; /* set if skip to next nr */ 109 int reorder_skip; /* set if skip to next nr */
108 int mtu;
109 enum l2tp_pwtype pwtype; 110 enum l2tp_pwtype pwtype;
110 struct l2tp_stats stats; 111 struct l2tp_stats stats;
111 struct hlist_node global_hlist; /* Global hash list node */ 112 struct hlist_node global_hlist; /* Global hash list node */
@@ -268,6 +269,21 @@ static inline int l2tp_get_l2specific_len(struct l2tp_session *session)
268 } 269 }
269} 270}
270 271
272static inline u32 l2tp_tunnel_dst_mtu(const struct l2tp_tunnel *tunnel)
273{
274 struct dst_entry *dst;
275 u32 mtu;
276
277 dst = sk_dst_get(tunnel->sock);
278 if (!dst)
279 return 0;
280
281 mtu = dst_mtu(dst);
282 dst_release(dst);
283
284 return mtu;
285}
286
271#define l2tp_printk(ptr, type, func, fmt, ...) \ 287#define l2tp_printk(ptr, type, func, fmt, ...) \
272do { \ 288do { \
273 if (((ptr)->debug) & (type)) \ 289 if (((ptr)->debug) & (type)) \
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c
index aee271741f5b..9821a1458555 100644
--- a/net/l2tp/l2tp_debugfs.c
+++ b/net/l2tp/l2tp_debugfs.c
@@ -191,8 +191,7 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
191 if (session->send_seq || session->recv_seq) 191 if (session->send_seq || session->recv_seq)
192 seq_printf(m, " nr %hu, ns %hu\n", session->nr, session->ns); 192 seq_printf(m, " nr %hu, ns %hu\n", session->nr, session->ns);
193 seq_printf(m, " refcnt %d\n", refcount_read(&session->ref_count)); 193 seq_printf(m, " refcnt %d\n", refcount_read(&session->ref_count));
194 seq_printf(m, " config %d/0/%c/%c/-/%s %08x %u\n", 194 seq_printf(m, " config 0/0/%c/%c/-/%s %08x %u\n",
195 session->mtu,
196 session->recv_seq ? 'R' : '-', 195 session->recv_seq ? 'R' : '-',
197 session->send_seq ? 'S' : '-', 196 session->send_seq ? 'S' : '-',
198 session->lns_mode ? "LNS" : "LAC", 197 session->lns_mode ? "LNS" : "LAC",
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index 5c366ecfa1cb..3728986ec885 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -226,22 +226,19 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
226 struct net_device *dev) 226 struct net_device *dev)
227{ 227{
228 unsigned int overhead = 0; 228 unsigned int overhead = 0;
229 struct dst_entry *dst;
230 u32 l3_overhead = 0; 229 u32 l3_overhead = 0;
230 u32 mtu;
231 231
232 /* if the encap is UDP, account for UDP header size */ 232 /* if the encap is UDP, account for UDP header size */
233 if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { 233 if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
234 overhead += sizeof(struct udphdr); 234 overhead += sizeof(struct udphdr);
235 dev->needed_headroom += sizeof(struct udphdr); 235 dev->needed_headroom += sizeof(struct udphdr);
236 } 236 }
237 if (session->mtu != 0) { 237
238 dev->mtu = session->mtu;
239 dev->needed_headroom += session->hdr_len;
240 return;
241 }
242 lock_sock(tunnel->sock); 238 lock_sock(tunnel->sock);
243 l3_overhead = kernel_sock_ip_overhead(tunnel->sock); 239 l3_overhead = kernel_sock_ip_overhead(tunnel->sock);
244 release_sock(tunnel->sock); 240 release_sock(tunnel->sock);
241
245 if (l3_overhead == 0) { 242 if (l3_overhead == 0) {
246 /* L3 Overhead couldn't be identified, this could be 243 /* L3 Overhead couldn't be identified, this could be
247 * because tunnel->sock was NULL or the socket's 244 * because tunnel->sock was NULL or the socket's
@@ -255,18 +252,12 @@ static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel,
255 */ 252 */
256 overhead += session->hdr_len + ETH_HLEN + l3_overhead; 253 overhead += session->hdr_len + ETH_HLEN + l3_overhead;
257 254
258 /* If PMTU discovery was enabled, use discovered MTU on L2TP device */ 255 mtu = l2tp_tunnel_dst_mtu(tunnel) - overhead;
259 dst = sk_dst_get(tunnel->sock); 256 if (mtu < dev->min_mtu || mtu > dev->max_mtu)
260 if (dst) { 257 dev->mtu = ETH_DATA_LEN - overhead;
261 /* dst_mtu will use PMTU if found, else fallback to intf MTU */ 258 else
262 u32 pmtu = dst_mtu(dst); 259 dev->mtu = mtu;
263 260
264 if (pmtu != 0)
265 dev->mtu = pmtu;
266 dst_release(dst);
267 }
268 session->mtu = dev->mtu - overhead;
269 dev->mtu = session->mtu;
270 dev->needed_headroom += session->hdr_len; 261 dev->needed_headroom += session->hdr_len;
271} 262}
272 263
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index a7c409215336..2e1e92651545 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -608,9 +608,6 @@ static int l2tp_nl_cmd_session_create(struct sk_buff *skb, struct genl_info *inf
608 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) 608 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
609 cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); 609 cfg.reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
610 610
611 if (info->attrs[L2TP_ATTR_MTU])
612 cfg.mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
613
614#ifdef CONFIG_MODULES 611#ifdef CONFIG_MODULES
615 if (l2tp_nl_cmd_ops[cfg.pw_type] == NULL) { 612 if (l2tp_nl_cmd_ops[cfg.pw_type] == NULL) {
616 genl_unlock(); 613 genl_unlock();
@@ -698,9 +695,6 @@ static int l2tp_nl_cmd_session_modify(struct sk_buff *skb, struct genl_info *inf
698 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT]) 695 if (info->attrs[L2TP_ATTR_RECV_TIMEOUT])
699 session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]); 696 session->reorder_timeout = nla_get_msecs(info->attrs[L2TP_ATTR_RECV_TIMEOUT]);
700 697
701 if (info->attrs[L2TP_ATTR_MTU])
702 session->mtu = nla_get_u16(info->attrs[L2TP_ATTR_MTU]);
703
704 ret = l2tp_session_notify(&l2tp_nl_family, info, 698 ret = l2tp_session_notify(&l2tp_nl_family, info,
705 session, L2TP_CMD_SESSION_MODIFY); 699 session, L2TP_CMD_SESSION_MODIFY);
706 700
@@ -730,8 +724,7 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
730 nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID, 724 nla_put_u32(skb, L2TP_ATTR_PEER_SESSION_ID,
731 session->peer_session_id) || 725 session->peer_session_id) ||
732 nla_put_u32(skb, L2TP_ATTR_DEBUG, session->debug) || 726 nla_put_u32(skb, L2TP_ATTR_DEBUG, session->debug) ||
733 nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype) || 727 nla_put_u16(skb, L2TP_ATTR_PW_TYPE, session->pwtype))
734 nla_put_u16(skb, L2TP_ATTR_MTU, session->mtu))
735 goto nla_put_failure; 728 goto nla_put_failure;
736 729
737 if ((session->ifname[0] && 730 if ((session->ifname[0] &&
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 44cac66284a5..b403728e2757 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -93,7 +93,6 @@
93#include <linux/nsproxy.h> 93#include <linux/nsproxy.h>
94#include <net/net_namespace.h> 94#include <net/net_namespace.h>
95#include <net/netns/generic.h> 95#include <net/netns/generic.h>
96#include <net/dst.h>
97#include <net/ip.h> 96#include <net/ip.h>
98#include <net/udp.h> 97#include <net/udp.h>
99#include <net/xfrm.h> 98#include <net/xfrm.h>
@@ -554,7 +553,6 @@ static void pppol2tp_show(struct seq_file *m, void *arg)
554static void pppol2tp_session_init(struct l2tp_session *session) 553static void pppol2tp_session_init(struct l2tp_session *session)
555{ 554{
556 struct pppol2tp_session *ps; 555 struct pppol2tp_session *ps;
557 struct dst_entry *dst;
558 556
559 session->recv_skb = pppol2tp_recv; 557 session->recv_skb = pppol2tp_recv;
560#if IS_ENABLED(CONFIG_L2TP_DEBUGFS) 558#if IS_ENABLED(CONFIG_L2TP_DEBUGFS)
@@ -564,17 +562,6 @@ static void pppol2tp_session_init(struct l2tp_session *session)
564 ps = l2tp_session_priv(session); 562 ps = l2tp_session_priv(session);
565 mutex_init(&ps->sk_lock); 563 mutex_init(&ps->sk_lock);
566 ps->owner = current->pid; 564 ps->owner = current->pid;
567
568 /* If PMTU discovery was enabled, use the MTU that was discovered */
569 dst = sk_dst_get(session->tunnel->sock);
570 if (dst) {
571 u32 pmtu = dst_mtu(dst);
572
573 if (pmtu)
574 session->mtu = pmtu - PPPOL2TP_HEADER_OVERHEAD;
575
576 dst_release(dst);
577 }
578} 565}
579 566
580struct l2tp_connect_info { 567struct l2tp_connect_info {
@@ -661,6 +648,22 @@ static int pppol2tp_sockaddr_get_info(const void *sa, int sa_len,
661 return 0; 648 return 0;
662} 649}
663 650
651/* Rough estimation of the maximum payload size a tunnel can transmit without
652 * fragmenting at the lower IP layer. Assumes L2TPv2 with sequence
653 * numbers and no IP option. Not quite accurate, but the result is mostly
654 * unused anyway.
655 */
656static int pppol2tp_tunnel_mtu(const struct l2tp_tunnel *tunnel)
657{
658 int mtu;
659
660 mtu = l2tp_tunnel_dst_mtu(tunnel);
661 if (mtu <= PPPOL2TP_HEADER_OVERHEAD)
662 return 1500 - PPPOL2TP_HEADER_OVERHEAD;
663
664 return mtu - PPPOL2TP_HEADER_OVERHEAD;
665}
666
664/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket 667/* connect() handler. Attach a PPPoX socket to a tunnel UDP socket
665 */ 668 */
666static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr, 669static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
@@ -778,8 +781,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
778 goto end; 781 goto end;
779 } 782 }
780 } else { 783 } else {
781 /* Default MTU must allow space for UDP/L2TP/PPP headers */
782 cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
783 cfg.pw_type = L2TP_PWTYPE_PPP; 784 cfg.pw_type = L2TP_PWTYPE_PPP;
784 785
785 session = l2tp_session_create(sizeof(struct pppol2tp_session), 786 session = l2tp_session_create(sizeof(struct pppol2tp_session),
@@ -824,7 +825,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
824 825
825 po->chan.private = sk; 826 po->chan.private = sk;
826 po->chan.ops = &pppol2tp_chan_ops; 827 po->chan.ops = &pppol2tp_chan_ops;
827 po->chan.mtu = session->mtu; 828 po->chan.mtu = pppol2tp_tunnel_mtu(tunnel);
828 829
829 error = ppp_register_net_channel(sock_net(sk), &po->chan); 830 error = ppp_register_net_channel(sock_net(sk), &po->chan);
830 if (error) { 831 if (error) {
@@ -880,10 +881,6 @@ static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel,
880 goto err; 881 goto err;
881 } 882 }
882 883
883 /* Default MTU values. */
884 if (cfg->mtu == 0)
885 cfg->mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
886
887 /* Allocate and initialize a new session context. */ 884 /* Allocate and initialize a new session context. */
888 session = l2tp_session_create(sizeof(struct pppol2tp_session), 885 session = l2tp_session_create(sizeof(struct pppol2tp_session),
889 tunnel, session_id, 886 tunnel, session_id,
@@ -1047,7 +1044,6 @@ static void pppol2tp_copy_stats(struct pppol2tp_ioc_stats *dest,
1047static int pppol2tp_session_ioctl(struct l2tp_session *session, 1044static int pppol2tp_session_ioctl(struct l2tp_session *session,
1048 unsigned int cmd, unsigned long arg) 1045 unsigned int cmd, unsigned long arg)
1049{ 1046{
1050 struct ifreq ifr;
1051 int err = 0; 1047 int err = 0;
1052 struct sock *sk; 1048 struct sock *sk;
1053 int val = (int) arg; 1049 int val = (int) arg;
@@ -1063,39 +1059,6 @@ static int pppol2tp_session_ioctl(struct l2tp_session *session,
1063 return -EBADR; 1059 return -EBADR;
1064 1060
1065 switch (cmd) { 1061 switch (cmd) {
1066 case SIOCGIFMTU:
1067 err = -ENXIO;
1068 if (!(sk->sk_state & PPPOX_CONNECTED))
1069 break;
1070
1071 err = -EFAULT;
1072 if (copy_from_user(&ifr, (void __user *) arg, sizeof(struct ifreq)))
1073 break;
1074 ifr.ifr_mtu = session->mtu;
1075 if (copy_to_user((void __user *) arg, &ifr, sizeof(struct ifreq)))
1076 break;
1077
1078 l2tp_info(session, L2TP_MSG_CONTROL, "%s: get mtu=%d\n",
1079 session->name, session->mtu);
1080 err = 0;
1081 break;
1082
1083 case SIOCSIFMTU:
1084 err = -ENXIO;
1085 if (!(sk->sk_state & PPPOX_CONNECTED))
1086 break;
1087
1088 err = -EFAULT;
1089 if (copy_from_user(&ifr, (void __user *) arg, sizeof(struct ifreq)))
1090 break;
1091
1092 session->mtu = ifr.ifr_mtu;
1093
1094 l2tp_info(session, L2TP_MSG_CONTROL, "%s: set mtu=%d\n",
1095 session->name, session->mtu);
1096 err = 0;
1097 break;
1098
1099 case PPPIOCGMRU: 1062 case PPPIOCGMRU:
1100 case PPPIOCGFLAGS: 1063 case PPPIOCGFLAGS:
1101 err = -EFAULT; 1064 err = -EFAULT;
@@ -1692,8 +1655,7 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
1692 tunnel->peer_tunnel_id, 1655 tunnel->peer_tunnel_id,
1693 session->peer_session_id, 1656 session->peer_session_id,
1694 state, user_data_ok); 1657 state, user_data_ok);
1695 seq_printf(m, " %d/0/%c/%c/%s %08x %u\n", 1658 seq_printf(m, " 0/0/%c/%c/%s %08x %u\n",
1696 session->mtu,
1697 session->recv_seq ? 'R' : '-', 1659 session->recv_seq ? 'R' : '-',
1698 session->send_seq ? 'S' : '-', 1660 session->send_seq ? 'S' : '-',
1699 session->lns_mode ? "LNS" : "LAC", 1661 session->lns_mode ? "LNS" : "LAC",