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
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'
...
...
@@ -50,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(
...
...
@@ -237,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,
...
...
@@ -247,12 +254,13 @@ def node_by_ll(addr):
_ll[a] = n, t
return _ll[addr]
def route_svg(z = 4, default = type('', (), {'short': None})):
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 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:
g[node_by_ll(r.nexthop)].append(
node_by_ll(r.prefix)[0] if r.prefix else default)
...
...
@@ -297,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
...
...
@@ -335,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')
...
...
demo/fixnemu.py
View file @
2fb63515
...
...
@@ -29,16 +29,17 @@ def _get_all_route_data():
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)
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)]
interface = ifdata[match.group(5)
or "lo"
]
metric = match.group(6)
if prefix == "default" or re.search(r'
/
0
$
', prefix):
prefix = None
...
...
demo/registry/re6st-registry.conf
View file @
2fb63515
...
...
@@ -6,3 +6,4 @@ run registry/run
hello
4
client
-
count
2
tunnel
-
refresh
100
ipv4
10
.
42
.
0
.
0
/
16
8
re6st-registry
View file @
2fb63515
...
...
@@ -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
:
...
...
re6st/ctl.py
View file @
2fb63515
...
...
@@ -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
]
...
...
re6st/plib.py
View file @
2fb63515
...
...
@@ -59,9 +59,11 @@ def client(iface, address_list, encrypt, *args, **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
):
ip
,
n
=
ip
if
ip4
:
ip4
,
n4
=
ip4
cmd
=
[
'babeld'
,
'-h'
,
str
(
hello_interval
),
'-H'
,
str
(
hello_interval
),
...
...
@@ -72,12 +74,16 @@ def router(ip, src, hello_interval, log_path, state_path,
'-C'
,
'default '
+
default
,
'-C'
,
'redistribute local deny'
,
'-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
cmd
+=
args
...
...
re6st/registry.py
View file @
2fb63515
...
...
@@ -120,6 +120,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
)
...
...
re6st/tunnel.py
View file @
2fb63515
...
...
@@ -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
...
...
re6stnet
View file @
2fb63515
...
...
@@ -229,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
)
...
...
@@ -265,6 +270,31 @@ def main():
try
:
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
logging
.
warning
(
"Fallback to ip-addrlabel because Linux < 3.0"
" does not support RTA_PREFSRC for ipv6. Note however that"
...
...
@@ -335,7 +365,7 @@ def main():
ip
(
'route'
,
'unreachable'
,
my_network
)
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
''
if
config
.
default
else
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