Hi James,
Please see inline: On Mon, 20 Mar 2017, James Chapman wrote: > I suggest change the wording of the first paragraph in the patch comment > to better represent why the changes are being made. Perhaps something > like the following? > > "Existing L2TP kernel code does not derive the optimal MTU for Ethernet > pseudowires and instead leaves this to a userspace L2TP daemon or > operator. If an MTU is not specified, the existing kernel code chooses > an MTU that does not take account of all tunnel header overheads, which > can lead to unwanted IP fragmentation. When L2TP is used without a > control plane (userspace daemon), we would prefer that the kernel does a > better job of choosing a default pseudowire MTU, taking account of all > tunnel header overheads, including IP header options, if any. This patch > addresses this." > This reads quite a bit better, thanks for suggesting this. I will pick it up. Plan to retain the second paragraph while removing the 1/2, 2/2 references, while keeping the patch rev at v4. I'll also respond to your email on the other patch in a bit, with suggested text which you could review/comment on. I'll re-post with changes after that. thanks, Ramkumar > > On 18/03/17 02:00, R. Parameswaran wrote: > > In existing kernel code, when setting up the L2TP interface, all of the > > tunnel encapsulation headers are not taken into account when setting > > up the MTU on the L2TP logical interface device. Due to this, the > > packets created by the applications on top of the L2TP layer are larger > > than they ought to be, relative to the underlay MTU, which leads to > > needless fragmentation once the L2TP packet is encapsulated in an outer IP > > packet. Specifically, the MTU calculation does not take into account the > > (outer) IP header imposed on the encapsulated L2TP packet, and the Layer 2 > > header imposed on the inner L2TP packet prior to encapsulation. > > > > Change-set here (2/2) uses the new kernel API to compute the IP overhead > > on an IPv4 or IPv6 socket, introduced in 1/2, in the L2TP Eth device setup > > to factor the additional encap overheads from the underlay IP header and > > Ethernet header on overlay (inner packet), to size the MTU on the L2TP > > logical device to its correct value. > > > > Signed-off-by: R. Parameswaran <rpara...@brocade.com> > > --- > > net/l2tp/l2tp_eth.c | 55 > > +++++++++++++++++++++++++++++++++++++++++++++++++---- > > 1 file changed, 51 insertions(+), 4 deletions(-) > > > > diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c > > index 8bf18a5..f143fa4 100644 > > --- a/net/l2tp/l2tp_eth.c > > +++ b/net/l2tp/l2tp_eth.c > > @@ -30,6 +30,9 @@ > > #include <net/xfrm.h> > > #include <net/net_namespace.h> > > #include <net/netns/generic.h> > > +#include <linux/ip.h> > > +#include <linux/ipv6.h> > > +#include <linux/udp.h> > > > > #include "l2tp_core.h" > > > > @@ -204,6 +207,53 @@ static void l2tp_eth_show(struct seq_file *m, void > > *arg) > > } > > #endif > > > > +static void l2tp_eth_adjust_mtu(struct l2tp_tunnel *tunnel, > > + struct l2tp_session *session, > > + struct net_device *dev) > > +{ > > + unsigned int overhead = 0; > > + struct dst_entry *dst; > > + u32 l3_overhead = 0; > > + > > + /* if the encap is UDP, account for UDP header size */ > > + if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { > > + 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; > > + } > > + l3_overhead = kernel_sock_ip_overhead(tunnel->sock); > > + if (l3_overhead == 0) { > > + /* L3 Overhead couldn't be identified, this could be > > + * because tunnel->sock was NULL or the socket's > > + * address family was not IPv4 or IPv6, > > + * dev mtu stays at 1500. > > + */ > > + return; > > + } > > + /* Adjust MTU, factor overhead - underlay L3, overlay L2 hdr > > + * UDP overhead, if any, was already factored in above. > > + */ > > + overhead += session->hdr_len + ETH_HLEN + l3_overhead; > > + > > + /* If PMTU discovery was enabled, use discovered MTU on L2TP device */ > > + dst = sk_dst_get(tunnel->sock); > > + if (dst) { > > + /* dst_mtu will use PMTU if found, else fallback to intf MTU */ > > + u32 pmtu = dst_mtu(dst); > > + > > + if (pmtu != 0) > > + dev->mtu = pmtu; > > + dst_release(dst); > > + } > > + session->mtu = dev->mtu - overhead; > > + dev->mtu = session->mtu; > > + dev->needed_headroom += session->hdr_len; > > +} > > + > > static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, > > u32 peer_session_id, struct l2tp_session_cfg *cfg) > > { > > struct net_device *dev; > > @@ -253,13 +303,10 @@ static int l2tp_eth_create(struct net *net, u32 > > tunnel_id, u32 session_id, u32 p > > } > > > > dev_net_set(dev, net); > > - if (session->mtu == 0) > > - session->mtu = dev->mtu - session->hdr_len; > > - dev->mtu = session->mtu; > > - dev->needed_headroom += session->hdr_len; > > dev->min_mtu = 0; > > dev->max_mtu = ETH_MAX_MTU; > > > > + l2tp_eth_adjust_mtu(tunnel, session, dev); > > priv = netdev_priv(dev); > > priv->dev = dev; > > priv->session = session; > > > -- > James Chapman > Katalix Systems Ltd > http://www.katalix.com > Catalysts for your Embedded Linux software development > > >