Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nemu3
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
nemu3
Commits
ca244b1c
Commit
ca244b1c
authored
Aug 18, 2010
by
Alina Quereilhac
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added TapNodeInterface and test to test_core. This test is not working.
parent
2cd9d91a
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
145 additions
and
39 deletions
+145
-39
benchmarks/linear-raw-throughput.py
benchmarks/linear-raw-throughput.py
+13
-13
sample-api.py
sample-api.py
+11
-11
src/netns/interface.py
src/netns/interface.py
+26
-2
src/netns/iproute.py
src/netns/iproute.py
+18
-1
src/netns/node.py
src/netns/node.py
+6
-0
test/test_core.py
test/test_core.py
+63
-4
test/test_interfaces.py
test/test_interfaces.py
+1
-1
test/test_node.py
test/test_node.py
+3
-3
test/test_switch.py
test/test_switch.py
+4
-4
No files found.
benchmarks/linear-raw-throughput.py
View file @
ca244b1c
...
...
@@ -14,10 +14,10 @@ def usage(f):
f
.
write
(
" -s, --pktsize=BYTES Size of packet payload
\
n
\
n
"
)
f
.
write
(
"Topology configuration:
\
n
"
)
f
.
write
(
" --use-p2p Use P2P
link
s, to avoid bridging
\
n
"
)
f
.
write
(
" --delay=SECS Add delay emulation in
link
s
\
n
"
)
f
.
write
(
" --jitter=PERCENT Add jitter emulation in
link
s
\
n
"
)
f
.
write
(
" --bandwidth=BPS Maximum bandwidth of
link
s
\
n
\
n
"
)
f
.
write
(
" --use-p2p Use P2P
switch
s, to avoid bridging
\
n
"
)
f
.
write
(
" --delay=SECS Add delay emulation in
switch
s
\
n
"
)
f
.
write
(
" --jitter=PERCENT Add jitter emulation in
switch
s
\
n
"
)
f
.
write
(
" --bandwidth=BPS Maximum bandwidth of
switch
s
\
n
\
n
"
)
f
.
write
(
"How long should the benchmark run (defaults to -t 10):
\
n
"
)
f
.
write
(
" -t, --time=SECS Stop after SECS seconds
\
n
"
)
...
...
@@ -89,7 +89,7 @@ def main():
elif
not
pktsize
:
error
=
"Missing mandatory --pktsize argument"
elif
use_p2p
and
(
delay
or
jitter
or
bandwidth
):
error
=
"Cannot use
link emulation with P2P link
s"
error
=
"Cannot use
switch emulation with P2P switch
s"
if
error
:
sys
.
stderr
.
write
(
"%s: %s
\
n
"
%
(
os
.
path
.
basename
(
sys
.
argv
[
0
]),
error
))
...
...
@@ -106,7 +106,7 @@ def main():
if
not
udp_perf
:
raise
RuntimeError
(
"Cannot find `udp-perf'"
)
nodes
,
interfaces
,
link
s
=
create_topo
(
nr
,
use_p2p
,
delay
,
jitter
,
nodes
,
interfaces
,
switch
s
=
create_topo
(
nr
,
use_p2p
,
delay
,
jitter
,
bandwidth
)
cmdline
=
[
udp_perf
,
"--server"
]
...
...
@@ -174,7 +174,7 @@ def dec2ip(dec):
def create_topo(n, p2p, delay, jitter, bw):
nodes = []
interfaces = []
link
s = []
switch
s = []
for i in range(n):
nodes.append(netns.Node())
if p2p:
...
...
@@ -197,12 +197,12 @@ def create_topo(n, p2p, delay, jitter, bw):
right = None
interfaces.append((left, right))
for i in range(n - 1):
link = netns.Link
(bandwidth = bw, delay = delay,
switch = netns.Switch
(bandwidth = bw, delay = delay,
delay_jitter = jitter)
link
.up = True
link
.connect(interfaces[i][1])
link
.connect(interfaces[i + 1][0])
links.append(link
)
switch
.up = True
switch
.connect(interfaces[i][1])
switch
.connect(interfaces[i + 1][0])
switchs.append(switch
)
for i in range(n):
for j in (0, 1):
...
...
@@ -222,7 +222,7 @@ def create_topo(n, p2p, delay, jitter, bw):
nexthop = dec2ip(ipbase + 4 * i + 2))
nodes[n - 1 - i].add_route(prefix = "10.0.0.0", prefix_len = 30,
nexthop = dec2ip(ipbase + (n - 2 - i) * 4 + 1))
return nodes, interfaces,
link
s
return nodes, interfaces,
switch
s
if __name__ == "__main__":
main()
sample-api.py
View file @
ca244b1c
...
...
@@ -29,9 +29,9 @@ if1 = b.add_if(mtu = 1492)
# for using with a tun device, to connect to the outside world
if2
=
b
.
import_if
(
'tun0'
)
# each
Link
is a linux bridge, all the parameters are applied to the associated
# each
Switch
is a linux bridge, all the parameters are applied to the associated
# interfaces as tc qdiscs.
link0
=
netns
.
Link
(
bandwidth
=
100
*
1024
*
1024
,
switch0
=
netns
.
Switch
(
bandwidth
=
100
*
1024
*
1024
,
delay
=
0.01
,
delay_jitter
=
0.001
,
delay_correlation
=
0.25
,
delay_distribution
=
'normal'
,
loss
=
0.005
,
loss_correlation
=
0.20
,
...
...
@@ -39,13 +39,13 @@ link0 = netns.Link(bandwidth = 100 * 1024 * 1024,
corrupt
=
0.005
,
corrupt_correlation
=
0.25
)
# connect to the bridge
link
0
.
connect
(
if0
)
link
0
.
connect
(
if1
)
switch
0
.
connect
(
if0
)
switch
0
.
connect
(
if1
)
# Should be experimented with Tom Geoff's patch to see if the bridge could be
# avoided; but for that the API would be slightly different, as these would be
# point-to-point interfaces and links.
# ppp0 = netns.PPP
Link
(a, b, bandwidth = ....)
# ppp0 = netns.PPP
Switch
(a, b, bandwidth = ....)
# if0 = ppp0.interface(a)
# For now, we have simple P2P interfaces:
...
...
@@ -54,9 +54,9 @@ link0.connect(if1)
# Add and connect a tap device (as if a external router were plugged into a
# switch)
if2
=
netns
.
ImportedInterface
(
'tap0'
)
link
0
.
connect
(
if2
)
switch
0
.
connect
(
if2
)
link
0
.
up
=
True
switch
0
.
up
=
True
if0
.
up
=
True
if1
.
up
=
True
...
...
@@ -79,7 +79,7 @@ stats = if0.get_stats()
routes
=
a
.
get_routes
()
ifaces
=
a
.
get_interfaces
()
nodes
=
netns
.
get_nodes
()
links
=
netns
.
get_link
s
()
switches
=
netns
.
get_switche
s
()
stats
=
link0
.
get_stats
()
# Run a process in background
...
...
@@ -108,9 +108,9 @@ def setup_linear_topology(n, bd, delay):
if2
=
nodes
[
i
+
1
].
add_if
()
if1
.
add_v4_address
(
addr
=
(
'10.0.%d.2'
%
i
),
prefix_len
=
24
)
if2
.
add_v4_address
(
addr
=
(
'10.0.%d.1'
%
i
),
prefix_len
=
24
)
link
=
netns
.
Link
(
bandwidth
=
bd
,
delay
=
delay
)
link
.
connect
(
if1
)
link
.
connect
(
if2
)
switch
=
netns
.
Switch
(
bandwidth
=
bd
,
delay
=
delay
)
switch
.
connect
(
if1
)
switch
.
connect
(
if2
)
for
i
in
range
(
n
):
for
j
in
range
(
n
):
...
...
src/netns/interface.py
View file @
ca244b1c
...
...
@@ -169,7 +169,7 @@ class P2PInterface(NSInterface):
self
.
_slave
=
None
class
ImportedNodeInterface
(
NSInterface
):
"""Class to handle already existing interfaces inside a name spac:
"""Class to handle already existing interfaces inside a name spac
e
:
real devices, tun devices, etc.
The flag 'migrate' in the constructor indicates that the interface was migrated
inside the name space.
...
...
@@ -203,6 +203,30 @@ class ImportedNodeInterface(NSInterface):
netns
.
iproute
.
set_if
(
self
.
_original_state
)
self
.
_slave
=
None
class
TapNodeInterface
(
NSInterface
):
"""Class to create a tap interface inside a name space, it
can be connected to a Switch object with emulation of link
characteristics."""
def
__init__
(
self
,
node
):
"""Create a new tap interface. 'node' is the name space in which this
interface should be put."""
iface
=
netns
.
iproute
.
interface
(
name
=
self
.
_gen_if_name
())
self
.
_fd
=
netns
.
iproute
.
create_tap
(
iface
)
netns
.
iproute
.
change_netns
(
iface
.
name
,
node
.
pid
)
iface
=
node
.
get_interface
(
iface
.
name
)
super
(
TapNodeInterface
,
self
).
__init__
(
node
,
iface
.
index
)
@
property
def
fd
(
self
):
return
self
.
_fd
def
destroy
(
self
):
if
self
.
_fd
:
try
:
os
.
close
(
self
.
_fd
)
except
:
pass
class
ExternalInterface
(
Interface
):
"""Add user-facing methods for interfaces that run in the main namespace."""
@
property
...
...
@@ -257,7 +281,7 @@ class ExternalInterface(Interface):
return
ret
class
SlaveInterface
(
ExternalInterface
):
"""Class to handle the main-name-space-facing
couples of Nodei
nterface.
"""Class to handle the main-name-space-facing
half of NodeI
nterface.
Does nothing, just avoids any destroy code."""
def
destroy
(
self
):
pass
...
...
src/netns/iproute.py
View file @
ca244b1c
# vim:ts=4:sw=4:et:ai:sts=4
import
copy
,
os
,
re
,
socket
,
subprocess
,
sys
import
copy
,
os
,
re
,
socket
,
subprocess
,
sys
,
struct
from
fcntl
import
ioctl
from
netns.environ
import
*
# helpers
...
...
@@ -895,3 +896,19 @@ def set_tc(iface, bandwidth = None, delay = None, delay_jitter = None,
for c in commands:
execute(c)
def create_tap(iface):
"""Creates a tap device and returns the associated file descriptor"""
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000
TUNSETIFF = 0x400454ca
mode = IFF_TAP | IFF_NO_PI
fd = os.open("/dev/net/tun", os.O_RDWR)
if fd == -1:
raise RuntimeError("Could not open /dev/net/tun")
err = ioctl(fd, TUNSETIFF, struct.pack("16sH", iface.name, mode))
if err < 0:
os.close(fd)
raise RuntimeError("Could not configure device %s" % iface.name)
return fd
src/netns/node.py
View file @
ca244b1c
...
...
@@ -96,6 +96,12 @@ class Node(object):
setattr
(
i
,
k
,
v
)
return
i
def
add_tap
(
self
,
**
kwargs
):
i
=
netns
.
interface
.
TapNodeInterface
(
self
)
for
k
,
v
in
kwargs
.
items
():
setattr
(
i
,
k
,
v
)
return
i
def
import_if
(
self
,
interface
):
return
netns
.
interface
.
ImportedNodeInterface
(
self
,
interface
)
...
...
test/test_core.py
View file @
ca244b1c
#!/usr/bin/env python
# vim:ts=4:sw=4:et:ai:sts=4
import
grp
,
os
,
pwd
,
time
,
unittest
import
grp
,
os
,
pwd
,
time
,
threading
,
unittest
import
netns
,
test_util
class
TestConfigure
(
unittest
.
TestCase
):
...
...
@@ -51,7 +51,7 @@ class TestGlobal(unittest.TestCase):
i1
=
n1
.
add_if
()
i2
=
n2
.
add_if
()
i1
.
up
=
i2
.
up
=
True
l
=
netns
.
Link
()
l
=
netns
.
Switch
()
l
.
connect
(
i1
)
l
.
connect
(
i2
)
l
.
up
=
True
...
...
@@ -74,8 +74,8 @@ class TestGlobal(unittest.TestCase):
i2b
=
n2
.
add_if
()
i3
=
n3
.
add_if
()
i1
.
up
=
i2a
.
up
=
i2b
.
up
=
i3
.
up
=
True
l1
=
netns
.
Link
()
l2
=
netns
.
Link
()
l1
=
netns
.
Switch
()
l2
=
netns
.
Switch
()
l1
.
connect
(
i1
)
l1
.
connect
(
i2a
)
l2
.
connect
(
i2b
)
...
...
@@ -95,5 +95,64 @@ class TestGlobal(unittest.TestCase):
self
.
assertEquals
(
a1
.
wait
(),
0
)
self
.
assertEquals
(
a2
.
wait
(),
0
)
@
test_util
.
skipUnless
(
os
.
getuid
()
==
0
,
"Test requires root privileges"
)
def
test_run_ping_tap
(
self
):
"""This test simulates a point to point connection between two hosts using two tap devices"""
class
ChannelThread
:
def
__init__
(
self
):
self
.
stop
=
False
self
.
thread
=
None
def
_run
(
self
,
fd1
,
fd2
):
while
not
self
.
stop
:
s
=
os
.
read
(
fd1
,
65536
)
os
.
write
(
fd2
,
s
)
def
start
(
self
,
fd1
,
fd2
):
self
.
thread
=
threading
.
Thread
(
target
=
self
.
_run
,
args
=
[
fd1
,
fd2
])
self
.
thread
.
start
()
n1
=
netns
.
Node
()
n2
=
netns
.
Node
()
i1
=
n1
.
add_if
()
tap1
=
n1
.
add_tap
()
tap2
=
n2
.
add_tap
()
i2
=
n2
.
add_if
()
i1
.
up
=
tap1
.
up
=
tap2
.
up
=
i2
.
up
=
True
i1
.
add_v4_address
(
'10.0.0.1'
,
24
)
tap1
.
add_v4_address
(
'10.0.1.1'
,
24
)
tap2
.
add_v4_address
(
'10.0.1.2'
,
24
)
i2
.
add_v4_address
(
'10.0.2.2'
,
24
)
n2
.
add_route
(
prefix
=
'10.0.0.0'
,
prefix_len
=
24
,
nexthop
=
'10.0.1.2'
)
n1
.
add_route
(
prefix
=
'10.0.2.0'
,
prefix_len
=
24
,
nexthop
=
'10.0.1.1'
)
# communication forth between the two taps
thread1
=
ChannelThread
()
thread1
.
start
(
tap1
.
fd
,
tap2
.
fd
)
# communication back between the two taps
thread2
=
ChannelThread
()
thread2
.
start
(
tap2
.
fd
,
tap1
.
fd
)
null
=
file
(
'/dev/null'
,
'wb'
)
a
=
n1
.
Popen
([
'ping'
,
'-qc1'
,
'10.0.2.1'
],
stdout
=
null
)
self
.
assertEquals
(
a
.
wait
(),
0
)
print
'jhola'
thread1
.
stop
=
True
thread2
.
stop
=
True
os
.
write
(
tap1
.
fd
,
"0"
)
os
.
write
(
tap2
.
fd
,
"0"
)
thread1
.
thread
.
join
()
thread2
.
thread
.
join
()
print
'lalala'
if
__name__
==
'__main__'
:
unittest
.
main
()
test/test_interfaces.py
View file @
ca244b1c
...
...
@@ -29,7 +29,7 @@ class TestInterfaces(unittest.TestCase):
devs
=
get_devs_netns
(
node0
)
for
i
in
range
(
5
):
self
.
assert
Fals
e
(
devs
[
'lo'
][
'up'
])
self
.
assert
Tru
e
(
devs
[
'lo'
][
'up'
])
self
.
assertTrue
(
ifaces
[
i
].
name
in
devs
)
node_devs
=
set
(
node0
.
get_interfaces
())
...
...
test/test_node.py
View file @
ca244b1c
...
...
@@ -37,9 +37,9 @@ class TestNode(unittest.TestCase):
b
=
netns
.
Node
()
ifa
=
a
.
add_if
()
ifb
=
b
.
add_if
()
link
=
netns
.
Link
()
link
.
connect
(
ifa
)
link
.
connect
(
ifb
)
switch
=
netns
.
Switch
()
switch
.
connect
(
ifa
)
switch
.
connect
(
ifb
)
# Test automatic destruction
orig_devs
=
len
(
test_util
.
get_devs
())
...
...
test/test_
link
.py
→
test/test_
switch
.py
View file @
ca244b1c
...
...
@@ -4,20 +4,20 @@
import
os
,
unittest
import
netns
,
test_util
,
netns
.
environ
class
Test
Link
(
unittest
.
TestCase
):
class
Test
Switch
(
unittest
.
TestCase
):
@
test_util
.
skipUnless
(
os
.
getuid
()
==
0
,
"Test requires root privileges"
)
def
setUp
(
self
):
n1
=
netns
.
Node
()
n2
=
netns
.
Node
()
i1
=
n1
.
add_if
()
i2
=
n2
.
add_if
()
l
=
netns
.
Link
()
l
=
netns
.
Switch
()
l
.
connect
(
i1
)
l
.
connect
(
i2
)
self
.
stuff
=
(
n1
,
n2
,
i1
,
i2
,
l
)
@
test_util
.
skipUnless
(
os
.
getuid
()
==
0
,
"Test requires root privileges"
)
def
test_
link
_base
(
self
):
def
test_
switch
_base
(
self
):
(
n1
,
n2
,
i1
,
i2
,
l
)
=
self
.
stuff
l
.
mtu
=
3000
ifdata
=
netns
.
iproute
.
get_if_data
()[
0
]
...
...
@@ -40,7 +40,7 @@ class TestLink(unittest.TestCase):
self
.
assertEquals
(
tcdata
[
i2
.
control
.
index
],
{
"qdiscs"
:
{}})
@
test_util
.
skipUnless
(
os
.
getuid
()
==
0
,
"Test requires root privileges"
)
def
test_
link
_changes
(
self
):
def
test_
switch
_changes
(
self
):
(
n1
,
n2
,
i1
,
i2
,
l
)
=
self
.
stuff
# Test strange rules handling
...
...
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