This post describes how you can create L2TP ethernet pseudowires by using Linux kernel’s L2TP drivers and the “ip” utility of iproute2. L2TP is a protocol that tunnels one or more sessions over an IP tunnel. It is commonly used for VPNs (L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP network infrastructure. With L2TPv3, it is also useful as a Layer-2 tunneling infrastructure.
Our topology consists of 5 virtual machines running Debian Wheezy with Linux Kernel 3.2.0. Our scenario objective is to ensure L2 connectivity between HOST01 and HOST02. In order to accomplish this we’ll create a tunnel between TUNNEL01 and TUNNEL02 that will encapsulate packets coming from the 192.168.0.0/24 network. The INTERNET box just acts as a router for the packets exchanged by TUNNEL01 and TUNNEL02.
First thing let’s make sure IP forwarding is enabled on all the machines that’ll forward packets : TUNNEL0[1-2], INTERNET:
Next thing to do is to establish L3 connectivity between TUNNEL01 and TUNNEL02 by setting static routes:
Once we’ve established L3 connectivity between the tunnel endpoints we can proceed to creating the tunnels. Before configuring the tunnels we need to load the L2TPv3 ethernet pseudowire kernel module:
We’ll notice a new interface has been created with a MTU of 1488 (1500bytes Ethernet MTU - 12bytes L2TP header):
Next thing to do is install bridge-utils and bridge the l2tp interface with the network interface that’s attached to the LAN segment we want to extend over the tunnel, in our case it’s called eth1:
Now we should be up and running and have L2 connectivity over the L2TP pseudowire:
Now let’s go further to the transport layer and do a TCP throughput test:
Looks that we’ve got a problem. It appears that the TCP session was established with a MSS of 1460bytes. This would cause packets fragmentation through the tunnel interface as the packets would exceed the maximum MTU on the Ethernet link of 1500bytes. Even though the connection should establish correctly and the transfer should run just fine fragmentation could case performance issues due to encapsulation overhead.
I thought of lowering the MTU of the internal interfaces and enforcing the MSS for the TCP connections so that all the packets that are transmitted across the tunnel interfaces do not exceed 1500bytes.
Now let’s do some basic maths and find out what’s the maximum TCP payload, also known as the maximum segment size in the TCP header:
All the virtual machines are running on my laptop so I guess it’s a decent throughput as the CPU seems to be the bottleneck.
I hope you find this post useful. I am going to continue it in a future post by configuring L2TP over IPsec.