By Jonathan Corbet
October 1, 2014
Tunneling protocols are increasingly important in modern networking
setups. By tying distant networks together, they enable the creation of
virtual private networks, access to otherwise-firewalled ports, and more.
Tunneling can happen at multiple levels in the networking stack; SSH
tunnels are implemented over TCP, while protocols like
GRE
and
IPIP work
directly at the IP level. Increasingly, though, there is interest in
implementing tunneling inside the UDP protocol. The "foo over UDP" (FOU) patch
set from Tom Herbert, which has been pulled into the net-next tree for
3.18, implements
UDP-level tunneling in a generic manner.
Why UDP? Just about any network interface out there has hardware support
for UDP at this point, handling details like checksumming. UDP adds just
enough information (port numbers, in particular) to make the routing of
encapsulated packets easy. UDP can also be made to work with protocols
like Receive Side Scaling (RSS) and the Equal-cost multipath routing
protocol (ECMP) to improve performance in highly connected settings. The
advantages of UDP tunneling are enough that some developers think it's
going to become nearly ubiquitous in the coming years.
Packet encapsulation and tunneling over UDP is a relatively straightforward
concept to understand. Suppose a simple TCP packet is presented to the
tunneling interface:
This packet has the usual IP and TCP headers, followed by the data the user
wishes to send. The encapsulation process does something like this:
At this point, the packet looks like a UDP packet that happens to have a
TCP packet buried within it. The system can now transmit it to the
destination as an ordinary UDP packet; at the receiving end, the extra
headers will be stripped off and the original packet will be fed into the
network stack.
Configuring a FOU tunnel will typically be a two-step process. The
transmit and receive sides have been separated, a feature which, among
other things, allows asymmetric setups should anybody want them. On the
receive side, configuration is really just a matter of setting up a UDP
port to be the recipient of encapsulated packets. The new "fou"
subcommand is intended for this purpose:
ip fou add port 5555 ipproto 4
This command sets aside port 5555, saying that packets arriving there will
have protocol 4, which is IP encapsulation. Packets received on that
port will have the encapsulation removed; they will then be fed back into
the network stack for delivery to the real destination.
Things are a little more complicated on the transmit side, since the
destination address must be provided and transmission needs to work with
existing encapsulation protocols. A typical command might look like:
ip link add name tun1 type ipip \
remote 192.168.1.1 local 192.168.1.2 ttl 225 \
encap fou encap-sport auto encap-dport 5555
This command will set up a new virtual interface (tun1) configured
for IPIP encapsulation. The source port for packets is left to the network
stack to decide, but the destination port will be 5555. Of course, one has
to get the encapsulation protocol to actually use this interface. At the
moment, support for doing that has been added to the IPIP, SIT
(an
IPv4-to-IPv6 tunneling protocol) and GRE (used for virtual private
networks) protocols.
Some numbers posted in the patch set show
significant performance increases for the SIT and IPIP protocols;
performance with GRE was roughly equivalent to the no-FOU case. So this
feature has a clear potential to speed things up by taking advantage of
existing optimizations around UDP transmission and receipt. The nice thing
is that no special hardware support is required; current hardware can
handle UDP just fine. So it is a simple solution that will work on
existing systems — and it should be available in the 3.18 kernel release.
(
Log in to post comments)