Commit abf8211e authored by Alain Takoudjou's avatar Alain Takoudjou

Merge branch 'proto' into re6st-slapos

parents 47d1bb85 40d4e496
......@@ -7,7 +7,7 @@ Standards-Version: 3.9.1
Package: re6stnet
Architecture: all
Depends: ${misc:Depends}, python (>= 2.6.6-3), python (<< 2.8), python-argparse, python-openssl (>= 0.13), openvpn (>= 2.1.3), babeld (= 1.5.1-nxd2), iproute2 | iproute, openssl
Depends: ${misc:Depends}, python (>= 2.6.6-3), python (<< 2.8), python-argparse, python-openssl (>= 0.13), openvpn (>= 2.1.3), babeld (= 1.6.0~1.g8950d3b-nxd1), iproute2 | iproute, openssl
Recommends: ${python:Recommends}, logrotate
Suggests: ndisc6
Description: resilient, scalable, IPv6 network application
#!/usr/bin/python
import math, nemu, os, signal, socket, subprocess, sys, time, weakref
import math, nemu, os, re, signal, socket, subprocess, sys, time, weakref
from collections import defaultdict
IPTABLES = 'iptables'
SCREEN = 'screen'
......@@ -38,6 +38,8 @@ def _add_interface(node, iface):
return Node__add_interface(node, iface)
nemu.Node._add_interface = _add_interface
execfile("fixnemu.py")
# create nodes
for name in """internet=I registry=R
gateway1=g1 machine1=1 machine2=2
......@@ -48,6 +50,8 @@ for name in """internet=I registry=R
globals()[name] = node = nemu.Node()
node.name = name
node.short = short
node.Popen(('sysctl', '-q',
'net.ipv4.icmp_echo_ignore_broadcasts=0')).wait()
node._screen = node.Popen((SCREEN, '-DmS', name))
node.screen = (lambda name: lambda *cmd:
subprocess.call([SCREEN, '-r', name, '-X', 'eval'] + map(
......@@ -235,7 +239,12 @@ def node_by_ll(addr):
for a in a:
p = a['prefix_len']
a = a['address']
if a.startswith('2001:db8:'):
if a.startswith('10.'):
if a.startswith('10.42.'):
assert not p % 8
_ll[socket.inet_ntoa(socket.inet_aton(
a)[:p/8].ljust(4, '\0'))] = n, t
elif a.startswith('2001:db8:'):
assert not p % 8
a = socket.inet_ntop(socket.AF_INET6,
socket.inet_pton(socket.AF_INET6,
......@@ -245,17 +254,19 @@ def node_by_ll(addr):
_ll[a] = n, t
return _ll[addr]
def route_svg(z=4):
def route_svg(ipv4, z = 4, default = type('', (), {'short': None})):
graph = {}
for n in nodes:
g = graph[n] = defaultdict(list)
for r in n.get_routes():
if r.prefix and r.prefix.startswith('2001:db8:'):
if (r.prefix and r.prefix.startswith('10.42.') if ipv4 else
r.prefix is None or r.prefix.startswith('2001:db8:')):
try:
g[node_by_ll(r.nexthop)].append(node_by_ll(r.prefix)[0])
g[node_by_ll(r.nexthop)].append(
node_by_ll(r.prefix)[0] if r.prefix else default)
except KeyError:
pass
gv = ["digraph { splines = true; edge[color=grey, labelangle=0, arrowhead=dot];"]
gv = ["digraph { splines = true; edge[color=grey, labelangle=0];"]
N = len(nodes)
a = 2 * math.pi / N
edges = set()
......@@ -268,17 +279,23 @@ def route_svg(z=4):
l.append((min(j, N - j), p, r))
for j, (l, (p, t), r) in enumerate(sorted(l)):
l = []
arrowhead = 'odot'
for r in sorted(r.short for r in r):
if r:
if r == p.short:
r = '<font color="grey">%s</font>' % r
l.append(r)
else:
arrowhead = 'dot'
if (n.name, p.name) in edges:
r = 'penwidth=0'
else:
edges.add((p.name, n.name))
r = 'style=solid' if t else 'style=dashed'
gv.append('%s -> %s [labeldistance=%u, headlabel=<%s>, %s];'
% (p.name, n.name, 1.5 * math.sqrt(j) + 2, ','.join(l), r))
gv.append(
'%s -> %s [labeldistance=%u, headlabel=<%s>, arrowhead=%s, %s];'
% (p.name, n.name, 1.5 * math.sqrt(j) + 2, ','.join(l),
arrowhead, r))
gv.append('}\n')
return subprocess.Popen(('neato', '-Tsvg'),
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
......@@ -288,13 +305,25 @@ if len(sys.argv) > 1:
import SimpleHTTPServer, SocketServer
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
_path_match = re.compile('/(.+)\.html$').match
pages = 'ipv6', 'ipv4', 'tunnels'
def do_GET(self):
svg = None
if self.path == '/route.html':
other = 'tunnel'
svg = route_svg()
elif self.path == '/tunnel.html':
other = 'route'
try:
page = self.pages.index(self._path_match(self.path).group(1))
except AttributeError, ValueError:
if self.path == '/':
self.send_response(302)
self.send_header('Location', self.pages[0] + '.html')
self.end_headers()
else:
self.send_error(404)
return
if page < 2:
svg = route_svg(page)
else:
gv = registry.Popen(('python', '-c', r"""if 1:
import math, json
from re6st.registry import RegistryClient
......@@ -326,21 +355,16 @@ if len(sys.argv) > 1:
if not svg:
self.send_error(500)
return
else:
if self.path == '/':
self.send_response(302)
self.send_header('Location', 'route.html')
self.end_headers()
else:
self.send_error(404)
return
mt = 'text/html'
body = """<html>
<head><meta http-equiv="refresh" content="10"/></head>
<body><a style="position: absolute" href="%s.html">%ss</a>
<body><span style="position: absolute">%s</span>
%s
</body>
</html>""" % (other, other, svg[svg.find('<svg'):])
</html>""" % (' '.join(x if i == page else
'<a href="%s.html">%s</a>' % (x, x)
for i, x in enumerate(self.pages)),
svg[svg.find('<svg'):])
self.send_response(200)
self.send_header('Content-Length', len(body))
self.send_header('Content-type', mt + '; charset=utf-8')
......
# -*- coding: utf-8 -*-
# Copyright 2010, 2011 INRIA
# Copyright 2011 Martín Ferrari <martin.ferrari@gmail.com>
#
# This file is contains patches to Nemu.
#
# Nemu is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License version 2, as published by the Free
# Software Foundation.
#
# Nemu is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# Nemu. If not, see <http://www.gnu.org/licenses/>.
import re
from nemu.iproute import backticks, get_if_data, get_all_route_data, route
def _get_all_route_data():
ipdata = backticks([IP_PATH, "-o", "route", "list"]) # "table", "all"
ipdata += backticks([IP_PATH, "-o", "-f", "inet6", "route", "list"])
ifdata = get_if_data()[1]
ret = []
for line in ipdata.split("\n"):
if line == "":
continue
# PATCH: parse 'from'
# PATCH: 'dev' is missing on 'unreachable' ipv4 routes
match = re.match('(?:(unicast|local|broadcast|multicast|throw|'
r'unreachable|prohibit|blackhole|nat) )?(\S+)(?: from (\S+))?'
r'(?: via (\S+))?(?: dev (\S+))?.*(?: metric (\d+))?', line)
if not match:
raise RuntimeError("Invalid output from `ip route': `%s'" % line)
tipe = match.group(1) or "unicast"
prefix = match.group(2)
#src = match.group(3)
nexthop = match.group(4)
interface = ifdata[match.group(5) or "lo"]
metric = match.group(6)
if prefix == "default" or re.search(r'/0$', prefix):
prefix = None
prefix_len = 0
else:
match = re.match(r'([0-9a-f:.]+)(?:/(\d+))?$', prefix)
prefix = match.group(1)
prefix_len = int(match.group(2) or 32)
ret.append(route(tipe, prefix, prefix_len, nexthop, interface.index,
metric))
return ret
get_all_route_data.func_code = _get_all_route_data.func_code
......@@ -5,5 +5,5 @@ pp 1194 tcp
ca ca.crt
cert m1/cert.crt
key m1/cert.key
table 0
default
neighbour 6/16
......@@ -5,4 +5,4 @@ pp 1194 tcp
ca ca.crt
cert m2/cert.crt
key m2/cert.key
table 0
default
......@@ -5,4 +5,3 @@ pp 1194 tcp
ca ca.crt
cert m3/cert.crt
key m3/cert.key
table 0
......@@ -5,4 +5,4 @@ pp 1194 tcp
ca ca.crt
cert m4/cert.crt
key m4/cert.key
table 0
default
......@@ -4,6 +4,6 @@ state m5/
ca ca.crt
cert m5/cert.crt
key m5/cert.key
table 0
default
client-count 0
max-clients 0
......@@ -5,7 +5,7 @@ pp 1194 tcp
ca ca.crt
cert m6/cert.crt
key m6/cert.key
table 0
default
# TODO: Run a DHCPv4 client on machine9. Unfortunately, isc-dhcp-client 4.2.4
# fails with "Bind socket to interface: No such device"
daemon "exec dnsmasq -d8 - -i $re6stnet_iface -F 192.168.42.2,192.168.42.254,255.255.255.0,infinite -F ${re6stnet_subnet%/*},ra-only,${re6stnet_subnet#*/},1d -O option:router,192.168.42.1 -l m6/dnsmasq.leases"
......@@ -5,4 +5,4 @@ pp 1194 tcp
ca ca.crt
cert m7/cert.crt
key m7/cert.key
table 0
default
......@@ -4,5 +4,5 @@ state m8/
ca ca.crt
cert m8/cert.crt
key m8/cert.key
table 0
default
client 10.0.1.2,1194,tcp;10.0.1.3,1194,tcp
......@@ -6,3 +6,4 @@ run registry/run
hello 4
client-count 2
tunnel-refresh 100
ipv4 10.42.0.0/16 8
......@@ -31,7 +31,7 @@ If you already have IPv6 connectivity by autoconfiguration and still want to
use it for communications that are unrelated to this network, then:
- your kernel must support source address based routing (because you can't
use ``--table 0`` option).
use ``--default`` option).
- you must set ``net.ipv6.conf.<iface>.accept_ra`` sysctl to value 2 and
trigger SLAAC with ``rdisc6 <iface>`` to restore the default route if the
kernel removed while enabling forwarding.
......@@ -70,7 +70,7 @@ Important note about NetworkManager
It is required to configure properly every connection defined in NetworkManager
because default settings are wrong and conflict with re6st:
- If re6st routes all your IPv6 traffic, using ``--table 0`` option, then make
- If re6st routes all your IPv6 traffic, using ``--default`` option, then make
sure to disable IPv6 in NetworkManager.
- Otherwise, the following options must be set in [ipv6] section::
......
......@@ -83,6 +83,9 @@ def main():
_('--anonymous-prefix-length', type=int,
help="Length of allocated anonymous prefixes."
" If 0 or unset, registration by email is required")
_('--ipv4', nargs=2, metavar=("IP/N", "PLEN"),
help="Enable ipv4. Each node is assigned a subnet of length PLEN"
" inside network IP/N.")
_('-l', '--logfile', default='/var/log/re6stnet/registry.log',
help="Path to logging file.")
_('-r', '--run', default='/var/run/re6stnet',
......@@ -122,6 +125,15 @@ def main():
parser.error("--min-protocol: value must between %s and %s (included)"
% (version.min_protocol, version.protocol))
if config.ipv4:
ipv4, plen = config.ipv4
try:
ip, n = ipv4.split('/')
config.ipv4 = "%s/%s" % (socket.inet_ntoa(socket.inet_aton(ip)),
int(n)), int(plen)
except (socket.error, ValueError):
parser.error("invalid argument --ipv4")
utils.setupLog(config.verbose, config.logfile)
if config.max_clients is None:
......
......@@ -27,7 +27,7 @@ class Cache(object):
q("CREATE INDEX volatile.stat_try ON stat(try)")
q("INSERT INTO volatile.stat (peer) SELECT prefix FROM peer")
self._db.commit()
self._loadConfig(q("SELECT * FROM config"))
self._loadConfig(self._selectConfig(q))
try:
cert.verifyVersion(self.version)
except (AttributeError, x509.VerifyError):
......@@ -63,6 +63,11 @@ class Cache(object):
"value")
return db
@staticmethod
def _selectConfig(execute): # BBB: blob
return ((k, str(v) if type(v) is buffer else v)
for k, v in execute("SELECT * FROM config"))
def _loadConfig(self, config):
cls = self.__class__
logging.debug("Loading network parameters:")
......@@ -98,7 +103,7 @@ class Cache(object):
old = {}
with self._db as db:
remove = []
for k, v in db.execute("SELECT * FROM config"):
for k, v in self._selectConfig(db.execute):
if k in config:
old[k] = v
continue
......@@ -109,8 +114,11 @@ class Cache(object):
remove.append(k)
db.execute("DELETE FROM config WHERE name in ('%s')"
% "','".join(remove))
# BBB: Use buffer because of http://bugs.python.org/issue13676
# on Python 2.6
db.executemany("INSERT OR REPLACE INTO config VALUES(?,?)",
config.iteritems())
((k, buffer(v) if k in base64 else v)
for k, v in config.iteritems()))
self._loadConfig(config.iteritems())
return [k for k, v in config.iteritems()
if k not in old or old[k] != v]
......
......@@ -266,6 +266,8 @@ class Babel(object):
a = len(self.network)
for route in routes:
assert route.flags & 1, route # installed
if route.prefix.startswith('\0\0\0\0\0\0\0\0\0\0\xff\xff'):
continue
assert route.neigh_address == route.nexthop, route
address = route.neigh_address, route.ifindex
neigh_routes = n[address]
......
......@@ -59,10 +59,11 @@ def client(iface, address_list, encrypt, *args, **kw):
return openvpn(iface, encrypt, *remote, **kw)
def router(subnet, hello_interval, table, log_path, state_path, pidfile,
tunnel_interfaces, control_socket, default, *args, **kw):
s = utils.ipFromBin(subnet)
n = len(subnet)
def router(ip, ip4, src, hello_interval, log_path, state_path,
pidfile, control_socket, default, *args, **kw):
ip, n = ip
if ip4:
ip4, n4 = ip4
cmd = ['babeld',
'-h', str(hello_interval),
'-H', str(hello_interval),
......@@ -72,16 +73,19 @@ def router(subnet, hello_interval, table, log_path, state_path, pidfile,
'-s',
'-C', 'default ' + default,
'-C', 'redistribute local deny',
'-C', 'redistribute ip %s/%u eq %u' % (s, n, n),
'-C', 'redistribute deny']
if table:
cmd += '-t%u' % table, '-T%u' % table
else:
cmd[-2:-2] = '-C', 'redistribute ip ::/0 eq 0'
'-C', 'redistribute ip %s/%s eq %s' % (ip, n, n)]
if ip4:
cmd += '-C', 'redistribute ip %s/%s eq %s' % (ip4, n4, n4)
if src:
cmd += '-C', 'install ip ::/0 eq 0 src-prefix ' + src
elif src is None:
cmd += '-C', 'redistribute ip ::/0 eq 0'
cmd += ('-C', 'redistribute deny',
'-C', 'install pref-src ' + ip)
if ip4:
cmd += '-C', 'install pref-src ' + ip4
if control_socket:
cmd += '-R', '%s' % control_socket
for iface in tunnel_interfaces:
cmd += '-C', 'interface %s legacy-rxcost 5120' % iface
cmd += args
# WKRD: babeld fails to start if pidfile already exists
try:
......
......@@ -60,7 +60,7 @@ class RegistryServer(object):
"name TEXT PRIMARY KEY NOT NULL",
"value")
self.prefix = self.getConfig("prefix", None)
self.version = self.getConfig("version", "\0")
self.version = str(self.getConfig("version", "\0")) # BBB: blob
utils.sqliteCreateTable(self.db, "token",
"token TEXT PRIMARY KEY NOT NULL",
"email TEXT NOT NULL",
......@@ -119,6 +119,8 @@ class RegistryServer(object):
'protocol': version.protocol,
'registry_prefix': self.prefix,
}
if self.config.ipv4:
kw['ipv4'], kw['ipv4_sublen'] = self.config.ipv4
for x in ('client_count', 'encrypt', 'hello',
'max_clients', 'min_protocol', 'tunnel_refresh'):
kw[x] = getattr(self.config, x)
......@@ -126,7 +128,9 @@ class RegistryServer(object):
if config != self.getConfig('last_config', None):
self.version = self.encodeVersion(
1 + self.decodeVersion(self.version))
self.setConfig('version', self.version)
# BBB: Use buffer because of http://bugs.python.org/issue13676
# on Python 2.6
self.setConfig('version', buffer(self.version))
self.setConfig('last_config', config)
self.sendto(self.prefix, 0)
kw[''] = 'version',
......
......@@ -168,7 +168,8 @@ class BaseTunnelManager(object):
# TODO: To minimize downtime when network parameters change, we should do
# our best to not restart any process. Ideally, this list should be
# empty and the affected subprocesses reloaded.
NEED_RESTART = frozenset(('babel_default', 'encrypt', 'hello'))
NEED_RESTART = frozenset(('babel_default', 'encrypt', 'hello',
'ipv4', 'ipv4_sublen'))
_forward = None
......
#!/usr/bin/python
import atexit, errno, logging, os, shutil, signal
import socket, subprocess, sys, time, threading
import socket, struct, subprocess, sys, time, threading
from collections import deque
from functools import partial
from re6st import plib, tunnel, utils, version, x509
......@@ -58,11 +58,13 @@ def getConfig():
_ = parser.add_argument_group('routing').add_argument
_('-B', dest='babel_args', metavar='ARG', action='append', default=[],
help="Extra arguments to forward to Babel.")
_('--table', type=int, default=42,
help="Use given table id. Set 0 to use the main table, if you want to"
" access internet via this network (in this case, make sure you"
" don't already have a default route). Don't use this option with"
" --gateway (main table is automatically used).")
_('-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.")
_('--table', type=int, choices=(0,),
help="DEPRECATED: Use --default instead of --table=0")
_('--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.")
......@@ -140,9 +142,15 @@ 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 'none' in config.disable_proto:
config.disable_proto = ()
if not config.table:
if config.default:
# Make sure we won't tunnel over re6st.
config.disable_proto = tuple(set(('tcp6', 'udp6')).union(
config.disable_proto))
......@@ -221,6 +229,11 @@ def main():
raise EnvironmentError("%r failed with error %u\n%s"
% (' '.join(cmd), p.returncode, stderr))
return stdout
def ip4(object, *args):
args = ['ip', '-4', object, 'add'] + list(args)
call(args)
args[3] = 'del'
cleanup.append(lambda: subprocess.call(args))
def ip(object, *args):
args = ['ip', '-6', object, 'add'] + list(args)
call(args)
......@@ -236,10 +249,9 @@ def main():
os.environ['re6stnet_iface'] = config.main_interface
os.environ['re6stnet_subnet'] = my_subnet
os.environ['re6stnet_network'] = my_network
my_ip += '/%s' % len(subnet)
# Init db and tunnels
tunnel_interfaces = server_tunnels.keys()
config.babel_args += server_tunnels
timeout = 4 * cache.hello
cleanup = [lambda: cache.cacheMinimize(config.client_count),
lambda: shutil.rmtree(config.run, True)]
......@@ -250,29 +262,48 @@ def main():
cache, cert, config.openvpn_args, timeout,
config.client_count, config.iface_list, address, ip_changed,
remote_gateway, config.disable_proto, config.neighbour)
tunnel_interfaces += tunnel_manager.new_iface_list
config.babel_args += tunnel_manager.new_iface_list
else:
tunnel_manager = tunnel.BaseTunnelManager(cache, cert)
cleanup.append(tunnel_manager.sock.close)
try:
exit.acquire()
# Source address selection is defined by RFC 6724, and in most
# applications, it usually works thanks to rule 5 (prefer outgoing
# interface). But here, it rarely applies because we use several
# interfaces to connect to a re6st network.
# Rule 7 is little strange because it prefers temporary addresses
# over IP with a longer matching prefix (rule 8, which is not even
# mandatory).
# So only rule 6 can make the difference, i.e. prefer same label.
# The value of the label does not matter, except that it must be
# different from ::/0's (normally equal to 1).
# XXX: This does not work with extra interfaces that already have
# an public IP so Babel must be changed to set a source
# address on routes it installs.
ipv4 = getattr(cache, 'ipv4', None)
if ipv4:
serial = int(cert.cert.get_subject().serialNumber)
if cache.ipv4_sublen <= 16 and serial < 1 << cache.ipv4_sublen:
dot4 = lambda x: socket.inet_ntoa(struct.pack('!I', x))
ip4('route', 'unreachable', ipv4, 'proto', 'static')
ipv4, n = ipv4.split('/')
ipv4, = struct.unpack('!I', socket.inet_aton(ipv4))
n = int(n) + cache.ipv4_sublen
x = ipv4 | serial << 32 - n
ipv4 = dot4(x | (n < 31))
config.openvpn_args += '--ifconfig', \
ipv4, dot4((1<<32) - (1<<32-n))
ipv4 = ipv4, n
if not isinstance(tunnel_manager, tunnel.TunnelManager):
ip4('addr', "%s/%s" % ipv4,
'dev', config.main_interface)
if config.main_interface == "lo":
ip4('route', 'unreachable', "%s/%s" % (dot4(x), n),
'proto', 'static')
else:
logging.warning(
"IPv4 payload disabled due to wrong network parameters")
ipv4 = None
if os.uname()[2] < '2.6.40': # BBB
logging.warning("Fallback to ip-addrlabel because Linux < 3.0"
" does not support RTA_PREFSRC for ipv6. Note however that"
" this workaround does not work with extra interfaces that"
" already have a public IP")
ip('addrlabel', 'prefix', my_network, 'label', '99')
# No need to tell babeld not to set a preferred source IP in
# installed routes. The kernel will silently discard the option.
R = {}
# prepare persistent interfaces
if config.client:
address_list = [x for x in utils.parse_address(config.client)
if x[2] not in config.disable_proto]
......@@ -296,7 +327,8 @@ def main():
R[r] = partial(tunnel_manager.handleServerEvent, r)
x.close()
ip('addr', my_ip, 'dev', config.main_interface)
ip('addr', my_ip + '/%s' % len(subnet),
'dev', config.main_interface)
if_rt = ['ip', '-6', 'route', 'del',
'fe80::/64', 'dev', config.main_interface]
if config.main_interface == 'lo':
......@@ -305,30 +337,13 @@ def main():
subprocess.call(if_rt)
if_rt[4] = my_subnet
cleanup.append(lambda: subprocess.call(if_rt))
x = [my_network]
if config.gateway:
config.table = 0
elif config.table:
x += 'table', str(config.table)
try:
ip('rule', 'from', *x)
except EnvironmentError:
logging.error("It seems that your kernel was compiled"
" without support for source address based routing"
" (CONFIG_IPV6_SUBTREES). Consider using --table=0"
" option if you can't change your kernel.")
raise
ip('rule', 'to', *x)
call(if_rt)
if_rt += x[1:]
call(if_rt[:3] + ['add', 'proto', 'static'] + if_rt[4:])
else:
if config.default:
def check_no_default_route():
for route in call(('ip', '-6', 'route', 'show',
'default')).splitlines():
if ' proto 42 ' not in route:
sys.exit("Detected default route (%s)"
" whereas you specified --table=0."
" whereas you specified --default."
" Fix your configuration." % route)
check_no_default_route()
def check_no_default_route_thread():
......@@ -347,14 +362,17 @@ def main():
t = threading.Thread(target=check_no_default_route_thread)
t.daemon = True
t.start()
ip('route', 'unreachable', *x)
ip('route', 'unreachable', my_network)
config.babel_args += config.iface_list
cleanup.append(plib.router(subnet, cache.hello, config.table,
cleanup.append(plib.router((my_ip, len(subnet)), ipv4,
None if config.gateway else
'' if config.default else
my_network, cache.hello,
os.path.join(config.log, 'babeld.log'),
os.path.join(config.state, 'babeld.state'),
os.path.join(config.run, 'babeld.pid'),
tunnel_interfaces, control_socket, cache.babel_default,
control_socket, cache.babel_default,
*config.babel_args).stop)
if config.up:
exit.release()
......
......@@ -8,7 +8,7 @@ Release: %(set %ver; echo ${1#*-})
License: GPLv2+
Group: Applications/Internet
BuildArch: noarch
Requires: babeld = 1.5.1-nxd2
Requires: babeld = 1.6-git0.8950d3b.nxd1
Requires: iproute
Requires: openssl
Requires: openvpn
......
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