Commit b3fff8a8 authored by Julien Muchembled's avatar Julien Muchembled


parent aff69950
import atexit, errno, logging, os, shutil, signal
import socket, struct, subprocess, sys, time, threading
import socket, struct, subprocess, sys
from collections import deque
from functools import partial
if 're6st' not in sys.modules:
......@@ -75,12 +75,9 @@ def getConfig():
_('-B', dest='babel_args', metavar='ARG', action='append', default=[],
help="Extra arguments to forward to Babel.")
_('-D', '--default', action='store_true',
help="Access internet via this network (in this case, make sure you"
" don't already have a default route), or if your kernel was"
" compiled without support for source address based routing"
" (CONFIG_IPV6_SUBTREES). Meaningless with --gateway.")
help="This is an obsolete option and ignored.")
_('--table', type=int, choices=(0,),
help="DEPRECATED: Use --default instead of --table=0")
help="This is an obsolete option and ignored.")
_('--gateway', action='store_true',
help="Act as a gateway for this network (the default route will be"
" exported). Do never use it if you don't know what it means.")
......@@ -159,20 +156,28 @@ def main():
if config.max_clients is None:
config.max_clients = cache.max_clients
if config.table is not None:
logging.warning("--table option is deprecated: use --default instead")
config.default = True
if config.default and config.gateway:
sys.exit("error: conflicting options --default and --gateway")
if config.disable_proto is None:
config.disable_proto = DEFAULT_DISABLED_PROTO
elif 'none' in config.disable_proto:
config.disable_proto = ()
if config.default:
x = ['ip', '-6', 'route', 'add', 'unreachable', '::/128', 'from', '::/128']
has_ipv6_subtrees = not
if has_ipv6_subtrees:
x[3] = 'del'
"Source address based routing is not enabled in your kernel"
"Assuming you don't merge several re6st networks so routes from"
" other networks will be ignored." if config.gateway else
"This node won't receive traffic to be routed to the internet."
" Make sure you don't already have a default route.")
# Make sure we won't tunnel over re6st.
config.disable_proto = tuple({'tcp6', 'udp6'}.union(
def add_tunnels(iface_list):
for iface in iface_list:
config.babel_args += '-C', 'interface %s type tunnel' % iface
......@@ -376,47 +381,12 @@ def main():
if_rt[4] = my_subnet
if config.default:
def check_no_default_route():
for route in call(('ip', '-6', 'route', 'show',
if not (' proto babel ' in route
or ' proto 42 ' in route):
sys.exit("Detected default route (%s)"
" whereas you specified --default."
" Fix your configuration." % route)
def check_no_default_route_thread():
while True:
except OSError, e:
if e.errno != errno.ENOMEM:
t = threading.Thread(target=check_no_default_route_thread)
t.daemon = True
x = ['ip', '-6', 'route', 'add',
'unreachable', '::/128', 'from', '::/128']
sys.exit('error: Source address based routing is not'
' enabled in your kernel (CONFIG_IPV6_SUBTREES).'
' Try with the --default option.')
x[3] = 'del'
ip('route', 'unreachable', my_network)
config.babel_args += config.iface_list
cleanup.append(plib.router((my_ip, len(subnet)), ipv4,
my_network if config.gateway or config.default else None,
config.gateway, cache.hello,
(my_network, config.gateway, has_ipv6_subtrees),
os.path.join(config.log, 'babeld.log'),
os.path.join(config.state, 'babeld.state'),
os.path.join(, ''),
......@@ -62,8 +62,10 @@ def client(iface, address_list, encrypt, *args, **kw):
return openvpn(iface, encrypt, *remote, **kw)
def router(ip, ip4, src, gateway, hello_interval, log_path, state_path, pidfile,
def router(ip, ip4, rt6, hello_interval, log_path, state_path, pidfile,
control_socket, default, hmac, *args, **kw):
network, gateway, has_ipv6_subtrees = rt6
network_mask = int(network[network.index('/')+1:])
ip, n = ip
hmac_sign, hmac_accept = hmac
if ip4:
......@@ -75,12 +77,6 @@ def router(ip, ip4, src, gateway, hello_interval, log_path, state_path, pidfile,
'-S', state_path,
'-I', pidfile,
# Force use of ipv6 subtrees because:
# - even Linux 2.6.32 has them
# - the fallback implementation using a separate table
# is not equivalent, at least not the way we use babeld
# (and we don't need RTA_SRC for ipv4).
'-C', 'ipv6-subtrees true',
'-C', 'redistribute local deny',
'-C', 'redistribute ip %s/%s eq %s' % (ip, n, n)]
if hmac_sign:
......@@ -97,13 +93,37 @@ def router(ip, ip4, src, gateway, hello_interval, log_path, state_path, pidfile,
cmd += '-C', 'default ' + default
if ip4:
cmd += '-C', 'redistribute ip %s/%s eq %s' % (ip4, n4, n4)
if src:
if gateway:
cmd += '-C', 'redistribute ip ::/0 eq 0 src-prefix ' + src
cmd += '-C', 'install ip ::/0 eq 0 src-prefix ' + src + ' pref-src ' + ip
if gateway:
cmd += '-C', 'redistribute ip ::/0 eq 0 src-prefix ' + network
if not has_ipv6_subtrees:
cmd += (
'-C', 'in ip %s ge %s' % (network, network_mask),
'-C', 'in ip ::/0 deny',
elif has_ipv6_subtrees:
# For backward compatibility, if the default route comes from old
# version (without source-prefix).
cmd += (
'-C', 'install ip ::/0 eq 0 src-ip ::/0 src-eq 0 src-prefix ' + network,
# We patch babeld:
# - ipv6-subtrees is always true by default
# - if false, source prefix is cleared when the route is installed
cmd += (
'-C', 'ipv6-subtrees false',
# Accept default route from our network.
'-C', 'in ip ::/0 eq 0 src-ip %s src-eq %s' % (network, network_mask),
# Ignore default route from other networks. For backward
# compatibility we accept default routes from old version
# (without source-prefix).
'-C', 'in ip ::/0 eq 0 src-ip ::/0 src-ge 1 deny',
# Tell neighbours not to route to the internet via us,
# because we could be a black hole in case of misconfiguration.
'-C', 'out ip ::/0 eq 0 deny',
cmd += ('-C', 'redistribute deny',
'-C', 'install ip ::/0 ge 1 pref-src ' + ip)
'-C', 'install pref-src ' + ip)
if ip4:
cmd += '-C', 'install pref-src ' + ip4
if control_socket:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment