Babel Routing over Wireguard for the Tubes

What are The Tubes? They were an experimental overlay network for doing, uh, sysadmin LARP? Some public information about the setup could be seen over at (archive link; the network is no longer running). Anyways, as the overlay network grew, we wanted to make the network more mesh-like instead of star-like. And that means we needed a routing protocol.

After considering BGP and OSPF, I found some information about the Babel routing protocol. It promised to be simpler to set up, capable of handling optimal routing in a mesh network, and even has specialized metrics such as RTT-based metrics designed for use on overlay networks like the Tubes.

Here’s a public duplicate of the Tubes-internal document on setting up the Wireguard link and Babel configuration for this usage. This configuration as it stands is not well tested – it’s probably going to change as we bring on more links and find issues!

Babel Routing for the Tubes

The instructions below assume you are using wg-quick style Wireguard configuration, and babeld as your Babel routing daemon. Other tools may be used, but you will have to translate the configuration examples for it.

Configuring a Wireguard link for Babel routing

Wireguard links that will be running Babel routing need some configuration changes to allow the Babel protocol to run over them. Here’s an example configuration for a Wireguard link in wg-quick format.

# Leave the PrivateKey, ListenPort
# options unchanged from the normal configuration

# Assign an IPv6 link local address on the tunnel so multicast works
# This address must be distinct from the remote side! Consider using your
# participant number for the address.
Address = fe80::XX/64
# Also configure your router's local addresses on this interface
Address = 10.42.N.1, fd70:feed:cafe:XX00::1

# Disable automatically adding routes for AllowedIPs. That's Babel's job
Table = off

# An interface used for Babel MUST only have one peer
# Leave the PublicKey, PresharedKey, Endpoint, PersistentKeepalive
# options unchanged from the normal configuration

# Since we're doing mesh routing, allow all Tubes IPv4 & IPv6 addresses
AllowedIPs =, fd70:feed:cafe::/48

# The Babel protocol uses IPv6 link-local unicast and multicast addresses
AllowedIPs = fe80::/64, ff02::1:6/128

When this Wireguard link is running, there should be no IPv4 routes shown in ip route with dev wgN. There should be one IPv6 route shown with ip -6 route on the Wireguard device, for the link local range: fe80::/64 dev wgN proto kernel metric 256 pref medium

Configuring babeld

The babeld configuration file is usually located at /etc/babeld.conf

# Set default options that will apply to all wireguard interfaces
# Tunnel mode enables timestamps and RTT metrics
default type tunnel
# An optimization for point-to-point or wired links
default split-horizon true
# Override this to false on a specific interface if the remote node is
# close enough to have wifi interference on routed subnets.
default faraway true
# Prefer using unicast messages over the tunnel
default unicast true

# For each Wireguard interface that will be running babel, add an interface line:
interface wgN

# To protect against misconfigured remote Babel nodes, reject prefixes
# in the wrong subnet, or with the wrong prefix length.
in ip fd70:feed:cafe::/48 le 64 ge 56 allow
in ip fd70:feed:cafe::/56 eq 128 allow
in ip eq 24 allow
in ip eq 32 allow
in deny

# Advertise locally configured routes in the Tubes ranges
redistribute ip fd70:feed:cafe::/48 le 64 ge 56 allow
redistribute ip fd70:feed:cafe::/56 eq 128 allow
# If you are redistributing subnets on behalf of wireguard-connected
# peers who aren't using babel, increase the metrics for those subnets
#redistribute ip eq 24 metric 256
redistribute ip eq 24 allow
redistribute ip eq 32 allow
redistribute local ip eq 32 allow
redistribute local deny

If you send the running babeld process SIGUSR1, it will print out the list of known routes to the log. Please use this to verify that it has imported the correct local routes – marked (exported) – before linking to another node.

If Babel is not exporting your subnet address, there’s a couple possible reasons:

If you have a route for the subnet address, but the output of the ip route (or ip -6 route) command does not include a proto keyword, then it’s probably proto boot, and is excluded by default in babel. You can add the appropriate IPv4 or v6 lines to the redistribute section of the babel config to include that route:

redistribute ip proto 3 eq 24 allow
redistribute ip fd70:feed:cafe::/48 proto 3 le 64 ge 56 allow

Alternately, maybe you don’t have a single route configured covering the entire subnet – for example, if you are assigning individual addresses in a VPN concentrator, or are using smaller subnet sizes. In this case, consider adding local “unreachable” routes that cover your entire subnet for babeld to pick up:

ip route add unreachable 10.42.N.0/24
ip -6 route add unreachable fd70:feed:cafe:XX00::/56

Disabling transit traffic

If you want to use babel to automatically receive routes, but do not want to allow traffic to different systems to transit through your system, you can configure that by using out filters in the babel config:

# Allow announcing routes for your own local subnets
out ip 10.42.N.0/24 allow
out ip fd70:feed:cafe:XX00::/56 allow
# Don't announce routes to anything else
out deny


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.