Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
re6stnet
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2
Issues
2
List
Boards
Labels
Milestones
Merge Requests
4
Merge Requests
4
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
re6stnet
Commits
2fb63515
Commit
2fb63515
authored
Apr 07, 2015
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for ipv4 payload
There is no plan for a default ipv4 route.
parent
f128ba9d
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
94 additions
and
24 deletions
+94
-24
demo/demo
demo/demo
+34
-19
demo/fixnemu.py
demo/fixnemu.py
+3
-2
demo/registry/re6st-registry.conf
demo/registry/re6st-registry.conf
+1
-0
re6st-registry
re6st-registry
+12
-0
re6st/ctl.py
re6st/ctl.py
+2
-0
re6st/plib.py
re6st/plib.py
+7
-1
re6st/registry.py
re6st/registry.py
+2
-0
re6st/tunnel.py
re6st/tunnel.py
+2
-1
re6stnet
re6stnet
+31
-1
No files found.
demo/demo
View file @
2fb63515
#!/usr/bin/python
#!/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
from collections import defaultdict
IPTABLES = 'iptables'
IPTABLES = 'iptables'
SCREEN = 'screen'
SCREEN = 'screen'
...
@@ -50,6 +50,8 @@ for name in """internet=I registry=R
...
@@ -50,6 +50,8 @@ for name in """internet=I registry=R
globals()[name] = node = nemu.Node()
globals()[name] = node = nemu.Node()
node.name = name
node.name = name
node.short = short
node.short = short
node.Popen(('sysctl', '-q',
'net.ipv4.icmp_echo_ignore_broadcasts=0')).wait()
node._screen = node.Popen((SCREEN, '-DmS', name))
node._screen = node.Popen((SCREEN, '-DmS', name))
node.screen = (lambda name: lambda *cmd:
node.screen = (lambda name: lambda *cmd:
subprocess.call([SCREEN, '-r', name, '-X', 'eval'] + map(
subprocess.call([SCREEN, '-r', name, '-X', 'eval'] + map(
...
@@ -237,7 +239,12 @@ def node_by_ll(addr):
...
@@ -237,7 +239,12 @@ def node_by_ll(addr):
for a in a:
for a in a:
p = a['prefix_len']
p = a['prefix_len']
a = a['address']
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
assert not p % 8
a = socket.inet_ntop(socket.AF_INET6,
a = socket.inet_ntop(socket.AF_INET6,
socket.inet_pton(socket.AF_INET6,
socket.inet_pton(socket.AF_INET6,
...
@@ -247,12 +254,13 @@ def node_by_ll(addr):
...
@@ -247,12 +254,13 @@ def node_by_ll(addr):
_ll[a] = n, t
_ll[a] = n, t
return _ll[addr]
return _ll[addr]
def route_svg(z = 4, default = type('', (), {'short': None})):
def route_svg(
ipv4,
z = 4, default = type('', (), {'short': None})):
graph = {}
graph = {}
for n in nodes:
for n in nodes:
g = graph[n] = defaultdict(list)
g = graph[n] = defaultdict(list)
for r in n.get_routes():
for r in n.get_routes():
if r.prefix is None or 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:
try:
g[node_by_ll(r.nexthop)].append(
g[node_by_ll(r.nexthop)].append(
node_by_ll(r.prefix)[0] if r.prefix else default)
node_by_ll(r.prefix)[0] if r.prefix else default)
...
@@ -297,13 +305,25 @@ if len(sys.argv) > 1:
...
@@ -297,13 +305,25 @@ if len(sys.argv) > 1:
import SimpleHTTPServer, SocketServer
import SimpleHTTPServer, SocketServer
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
_path_match = re.compile('/(.+)\.html$').match
pages = 'ipv6', 'ipv4', 'tunnels'
def do_GET(self):
def do_GET(self):
svg = None
svg = None
if self.path == '/route.html':
try:
other = 'tunnel'
page = self.pages.index(self._path_match(self.path).group(1))
svg = route_svg()
except AttributeError, ValueError:
elif self.path == '/tunnel.html':
if self.path == '/':
other = 'route'
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:
gv =
registry.Popen(('python',
'
-c
',
r
"""
if
1:
import
math
,
json
import
math
,
json
from
re6st
.
registry
import
RegistryClient
from
re6st
.
registry
import
RegistryClient
...
@@ -335,21 +355,16 @@ if len(sys.argv) > 1:
...
@@ -335,21 +355,16 @@ if len(sys.argv) > 1:
if not svg:
if not svg:
self.send_error(500)
self.send_error(500)
return
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'
mt = 'text/html'
body = """
<html>
body = """
<html>
<head><meta
http-equiv=
"refresh"
content=
"10"
/></head>
<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
%s
</body>
</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_response
(
200
)
self
.
send_header
('
Content-Length
',
len
(
body
))
self
.
send_header
('
Content-Length
',
len
(
body
))
self
.
send_header
('
Content-type
',
mt
+
';
charset=
utf-8')
self
.
send_header
('
Content-type
',
mt
+
';
charset=
utf-8')
...
...
demo/fixnemu.py
View file @
2fb63515
...
@@ -29,16 +29,17 @@ def _get_all_route_data():
...
@@ -29,16 +29,17 @@ def _get_all_route_data():
if
line
==
""
:
if
line
==
""
:
continue
continue
# PATCH: parse 'from'
# PATCH: parse 'from'
# PATCH: 'dev' is missing on 'unreachable' ipv4 routes
match
=
re
.
match
(
'(?:(unicast|local|broadcast|multicast|throw|'
match
=
re
.
match
(
'(?:(unicast|local|broadcast|multicast|throw|'
r'unreachable|prohibit|blackhole|nat) )?(\
S+)(?:
from (\
S+))?
'
r'unreachable|prohibit|blackhole|nat) )?(\
S+)(?:
from (\
S+))?
'
r'
(
?
:
via
(
\
S
+
))
?
dev
(
\
S
+
)
.
*
(
?
:
metric
(
\
d
+
))
?
', line)
r'
(
?
:
via
(
\
S
+
))
?
(
?
:
dev
(
\
S
+
))
?
.
*
(
?
:
metric
(
\
d
+
))
?
', line)
if not match:
if not match:
raise RuntimeError("Invalid output from `ip route'
:
`
%
s
'" % line)
raise RuntimeError("Invalid output from `ip route'
:
`
%
s
'" % line)
tipe = match.group(1) or "unicast"
tipe = match.group(1) or "unicast"
prefix = match.group(2)
prefix = match.group(2)
#src = match.group(3)
#src = match.group(3)
nexthop = match.group(4)
nexthop = match.group(4)
interface = ifdata[match.group(5)]
interface = ifdata[match.group(5)
or "lo"
]
metric = match.group(6)
metric = match.group(6)
if prefix == "default" or re.search(r'
/
0
$
', prefix):
if prefix == "default" or re.search(r'
/
0
$
', prefix):
prefix = None
prefix = None
...
...
demo/registry/re6st-registry.conf
View file @
2fb63515
...
@@ -6,3 +6,4 @@ run registry/run
...
@@ -6,3 +6,4 @@ run registry/run
hello
4
hello
4
client
-
count
2
client
-
count
2
tunnel
-
refresh
100
tunnel
-
refresh
100
ipv4
10
.
42
.
0
.
0
/
16
8
re6st-registry
View file @
2fb63515
...
@@ -83,6 +83,9 @@ def main():
...
@@ -83,6 +83,9 @@ def main():
_
(
'--anonymous-prefix-length'
,
type
=
int
,
_
(
'--anonymous-prefix-length'
,
type
=
int
,
help
=
"Length of allocated anonymous prefixes."
help
=
"Length of allocated anonymous prefixes."
" If 0 or unset, registration by email is required"
)
" 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'
,
_
(
'-l'
,
'--logfile'
,
default
=
'/var/log/re6stnet/registry.log'
,
help
=
"Path to logging file."
)
help
=
"Path to logging file."
)
_
(
'-r'
,
'--run'
,
default
=
'/var/run/re6stnet'
,
_
(
'-r'
,
'--run'
,
default
=
'/var/run/re6stnet'
,
...
@@ -122,6 +125,15 @@ def main():
...
@@ -122,6 +125,15 @@ def main():
parser
.
error
(
"--min-protocol: value must between %s and %s (included)"
parser
.
error
(
"--min-protocol: value must between %s and %s (included)"
%
(
version
.
min_protocol
,
version
.
protocol
))
%
(
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
)
utils
.
setupLog
(
config
.
verbose
,
config
.
logfile
)
if
config
.
max_clients
is
None
:
if
config
.
max_clients
is
None
:
...
...
re6st/ctl.py
View file @
2fb63515
...
@@ -266,6 +266,8 @@ class Babel(object):
...
@@ -266,6 +266,8 @@ class Babel(object):
a
=
len
(
self
.
network
)
a
=
len
(
self
.
network
)
for
route
in
routes
:
for
route
in
routes
:
assert
route
.
flags
&
1
,
route
# installed
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
assert
route
.
neigh_address
==
route
.
nexthop
,
route
address
=
route
.
neigh_address
,
route
.
ifindex
address
=
route
.
neigh_address
,
route
.
ifindex
neigh_routes
=
n
[
address
]
neigh_routes
=
n
[
address
]
...
...
re6st/plib.py
View file @
2fb63515
...
@@ -59,9 +59,11 @@ def client(iface, address_list, encrypt, *args, **kw):
...
@@ -59,9 +59,11 @@ def client(iface, address_list, encrypt, *args, **kw):
return
openvpn
(
iface
,
encrypt
,
*
remote
,
**
kw
)
return
openvpn
(
iface
,
encrypt
,
*
remote
,
**
kw
)
def
router
(
ip
,
src
,
hello_interval
,
log_path
,
state_path
,
def
router
(
ip
,
ip4
,
src
,
hello_interval
,
log_path
,
state_path
,
pidfile
,
control_socket
,
default
,
*
args
,
**
kw
):
pidfile
,
control_socket
,
default
,
*
args
,
**
kw
):
ip
,
n
=
ip
ip
,
n
=
ip
if
ip4
:
ip4
,
n4
=
ip4
cmd
=
[
'babeld'
,
cmd
=
[
'babeld'
,
'-h'
,
str
(
hello_interval
),
'-h'
,
str
(
hello_interval
),
'-H'
,
str
(
hello_interval
),
'-H'
,
str
(
hello_interval
),
...
@@ -72,12 +74,16 @@ def router(ip, src, hello_interval, log_path, state_path,
...
@@ -72,12 +74,16 @@ def router(ip, src, hello_interval, log_path, state_path,
'-C'
,
'default '
+
default
,
'-C'
,
'default '
+
default
,
'-C'
,
'redistribute local deny'
,
'-C'
,
'redistribute local deny'
,
'-C'
,
'redistribute ip %s/%s eq %s'
%
(
ip
,
n
,
n
)]
'-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
:
if
src
:
cmd
+=
'-C'
,
'install ip ::/0 eq 0 src-prefix '
+
src
cmd
+=
'-C'
,
'install ip ::/0 eq 0 src-prefix '
+
src
elif
src
is
None
:
elif
src
is
None
:
cmd
+=
'-C'
,
'redistribute ip ::/0 eq 0'
cmd
+=
'-C'
,
'redistribute ip ::/0 eq 0'
cmd
+=
(
'-C'
,
'redistribute deny'
,
cmd
+=
(
'-C'
,
'redistribute deny'
,
'-C'
,
'install pref-src '
+
ip
)
'-C'
,
'install pref-src '
+
ip
)
if
ip4
:
cmd
+=
'-C'
,
'install pref-src '
+
ip4
if
control_socket
:
if
control_socket
:
cmd
+=
'-R'
,
'%s'
%
control_socket
cmd
+=
'-R'
,
'%s'
%
control_socket
cmd
+=
args
cmd
+=
args
...
...
re6st/registry.py
View file @
2fb63515
...
@@ -120,6 +120,8 @@ class RegistryServer(object):
...
@@ -120,6 +120,8 @@ class RegistryServer(object):
'protocol'
:
version
.
protocol
,
'protocol'
:
version
.
protocol
,
'registry_prefix'
:
self
.
prefix
,
'registry_prefix'
:
self
.
prefix
,
}
}
if
self
.
config
.
ipv4
:
kw
[
'ipv4'
],
kw
[
'ipv4_sublen'
]
=
self
.
config
.
ipv4
for
x
in
(
'client_count'
,
'encrypt'
,
'hello'
,
for
x
in
(
'client_count'
,
'encrypt'
,
'hello'
,
'max_clients'
,
'min_protocol'
,
'tunnel_refresh'
):
'max_clients'
,
'min_protocol'
,
'tunnel_refresh'
):
kw
[
x
]
=
getattr
(
self
.
config
,
x
)
kw
[
x
]
=
getattr
(
self
.
config
,
x
)
...
...
re6st/tunnel.py
View file @
2fb63515
...
@@ -168,7 +168,8 @@ class BaseTunnelManager(object):
...
@@ -168,7 +168,8 @@ class BaseTunnelManager(object):
# TODO: To minimize downtime when network parameters change, we should do
# TODO: To minimize downtime when network parameters change, we should do
# our best to not restart any process. Ideally, this list should be
# our best to not restart any process. Ideally, this list should be
# empty and the affected subprocesses reloaded.
# 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
_forward
=
None
...
...
re6stnet
View file @
2fb63515
...
@@ -229,6 +229,11 @@ def main():
...
@@ -229,6 +229,11 @@ def main():
raise
EnvironmentError
(
"%r failed with error %u
\
n
%s"
raise
EnvironmentError
(
"%r failed with error %u
\
n
%s"
%
(
' '
.
join
(
cmd
),
p
.
returncode
,
stderr
))
%
(
' '
.
join
(
cmd
),
p
.
returncode
,
stderr
))
return
stdout
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
):
def
ip
(
object
,
*
args
):
args
=
[
'ip'
,
'-6'
,
object
,
'add'
]
+
list
(
args
)
args
=
[
'ip'
,
'-6'
,
object
,
'add'
]
+
list
(
args
)
call
(
args
)
call
(
args
)
...
@@ -265,6 +270,31 @@ def main():
...
@@ -265,6 +270,31 @@ def main():
try
:
try
:
exit
.
acquire
()
exit
.
acquire
()
ipv4
=
getattr
(
cache
,
'ipv4'
,
None
)
if
ipv4
:
serial
=
int
(
cert
.
cert
.
get_subject
().
serialNumber
)
if
serial
.
bit_length
()
<=
cache
.
ipv4_sublen
<=
16
:
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
if
os
.
uname
()[
2
]
<
'2.6.40'
:
# BBB
logging
.
warning
(
"Fallback to ip-addrlabel because Linux < 3.0"
logging
.
warning
(
"Fallback to ip-addrlabel because Linux < 3.0"
" does not support RTA_PREFSRC for ipv6. Note however that"
" does not support RTA_PREFSRC for ipv6. Note however that"
...
@@ -335,7 +365,7 @@ def main():
...
@@ -335,7 +365,7 @@ def main():
ip
(
'route'
,
'unreachable'
,
my_network
)
ip
(
'route'
,
'unreachable'
,
my_network
)
config
.
babel_args
+=
config
.
iface_list
config
.
babel_args
+=
config
.
iface_list
cleanup
.
append
(
plib
.
router
((
my_ip
,
len
(
subnet
)),
cleanup
.
append
(
plib
.
router
((
my_ip
,
len
(
subnet
)),
ipv4
,
None
if
config
.
gateway
else
None
if
config
.
gateway
else
''
if
config
.
default
else
''
if
config
.
default
else
my_network
,
cache
.
hello
,
my_network
,
cache
.
hello
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment