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
23841d8d
Commit
23841d8d
authored
Jul 26, 2010
by
Martín Ferrari
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
moved internal interface classes to iproute, as they are used mostly for iproute communication
parent
b6d0ee4f
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
252 additions
and
253 deletions
+252
-253
src/netns/interface.py
src/netns/interface.py
+15
-222
src/netns/iproute.py
src/netns/iproute.py
+231
-25
src/netns/protocol.py
src/netns/protocol.py
+6
-6
No files found.
src/netns/interface.py
View file @
23841d8d
...
...
@@ -58,24 +58,24 @@ class NSInterface(Interface):
if
name
[
0
]
==
'_'
:
# forbid anything that doesn't start with a _
super
(
Interface
,
self
).
__setattr__
(
name
,
value
)
return
iface
=
interface
(
index
=
self
.
index
)
iface
=
netns
.
iproute
.
interface
(
index
=
self
.
index
)
setattr
(
iface
,
name
,
value
)
return
self
.
_slave
.
set_if
(
iface
)
def
add_v4_address
(
self
,
address
,
prefix_len
,
broadcast
=
None
):
addr
=
ipv4address
(
address
,
prefix_len
,
broadcast
)
addr
=
netns
.
iproute
.
ipv4address
(
address
,
prefix_len
,
broadcast
)
self
.
_slave
.
add_addr
(
self
.
index
,
addr
)
def
add_v6_address
(
self
,
address
,
prefix_len
):
addr
=
ipv6address
(
address
,
prefix_len
)
addr
=
netns
.
iproute
.
ipv6address
(
address
,
prefix_len
)
self
.
_slave
.
add_addr
(
self
.
index
,
addr
)
def
del_v4_address
(
self
,
address
,
prefix_len
,
broadcast
=
None
):
addr
=
ipv4address
(
address
,
prefix_len
,
broadcast
)
addr
=
netns
.
iproute
.
ipv4address
(
address
,
prefix_len
,
broadcast
)
self
.
_slave
.
del_addr
(
self
.
index
,
addr
)
def
del_v6_address
(
self
,
address
,
prefix_len
):
addr
=
ipv6address
(
address
,
prefix_len
)
addr
=
netns
.
iproute
.
ipv6address
(
address
,
prefix_len
)
self
.
_slave
.
del_addr
(
self
.
index
,
addr
)
def
get_addresses
(
self
):
...
...
@@ -102,8 +102,8 @@ class NodeInterface(NSInterface):
def
__init__
(
self
,
node
):
"""Create a new interface. `node' is the name space in which this
interface should be put."""
if1
=
interface
(
name
=
self
.
_gen_if_name
())
if2
=
interface
(
name
=
self
.
_gen_if_name
())
if1
=
netns
.
iproute
.
interface
(
name
=
self
.
_gen_if_name
())
if2
=
netns
.
iproute
.
interface
(
name
=
self
.
_gen_if_name
())
ctl
,
ns
=
netns
.
iproute
.
create_if_pair
(
if1
,
if2
)
try
:
netns
.
iproute
.
change_netns
(
ns
,
node
.
pid
)
...
...
@@ -136,8 +136,8 @@ class P2PInterface(NSInterface):
def
create_pair
(
node1
,
node2
):
"""Create and return a pair of connected P2PInterface objects, assigned
to name spaces represented by `node1' and `node2'."""
if1
=
interface
(
name
=
P2PInterface
.
_gen_if_name
())
if2
=
interface
(
name
=
P2PInterface
.
_gen_if_name
())
if1
=
netns
.
iproute
.
interface
(
name
=
P2PInterface
.
_gen_if_name
())
if2
=
netns
.
iproute
.
interface
(
name
=
P2PInterface
.
_gen_if_name
())
pair
=
netns
.
iproute
.
create_if_pair
(
if1
,
if2
)
try
:
netns
.
iproute
.
change_netns
(
pair
[
0
],
node1
.
pid
)
...
...
@@ -198,24 +198,24 @@ class ExternalInterface(Interface):
if
name
[
0
]
==
'_'
:
# forbid anything that doesn't start with a _
super
(
ExternalInterface
,
self
).
__setattr__
(
name
,
value
)
return
iface
=
interface
(
index
=
self
.
index
)
iface
=
netns
.
iproute
.
interface
(
index
=
self
.
index
)
setattr
(
iface
,
name
,
value
)
return
netns
.
iproute
.
set_if
(
iface
)
def
add_v4_address
(
self
,
address
,
prefix_len
,
broadcast
=
None
):
addr
=
ipv4address
(
address
,
prefix_len
,
broadcast
)
addr
=
netns
.
iproute
.
ipv4address
(
address
,
prefix_len
,
broadcast
)
netns
.
iproute
.
add_addr
(
self
.
index
,
addr
)
def
add_v6_address
(
self
,
address
,
prefix_len
):
addr
=
ipv6address
(
address
,
prefix_len
)
addr
=
netns
.
iproute
.
ipv6address
(
address
,
prefix_len
)
netns
.
iproute
.
add_addr
(
self
.
index
,
addr
)
def
del_v4_address
(
self
,
address
,
prefix_len
,
broadcast
=
None
):
addr
=
ipv4address
(
address
,
prefix_len
,
broadcast
)
addr
=
netns
.
iproute
.
ipv4address
(
address
,
prefix_len
,
broadcast
)
netns
.
iproute
.
del_addr
(
self
.
index
,
addr
)
def
del_v6_address
(
self
,
address
,
prefix_len
):
addr
=
ipv6address
(
address
,
prefix_len
)
addr
=
netns
.
iproute
.
ipv6address
(
address
,
prefix_len
)
netns
.
iproute
.
del_addr
(
self
.
index
,
addr
)
def
get_addresses
(
self
):
...
...
@@ -301,7 +301,7 @@ class Link(ExternalInterface):
if
name
[
0
]
==
'_'
:
# forbid anything that doesn't start with a _
super
(
ExternalInterface
,
self
).
__setattr__
(
name
,
value
)
return
iface
=
bridge
(
index
=
self
.
index
)
iface
=
netns
.
iproute
.
bridge
(
index
=
self
.
index
)
setattr
(
iface
,
name
,
value
)
return
netns
.
iproute
.
set_bridge
(
iface
)
...
...
@@ -332,210 +332,3 @@ class Link(ExternalInterface):
# don't look after this :-)
# helpers
def
_any_to_bool
(
any
):
if
isinstance
(
any
,
bool
):
return
any
if
isinstance
(
any
,
int
):
return
any
!=
0
if
isinstance
(
any
,
str
):
if
any
.
isdigit
():
return
int
(
any
)
!=
0
if
any
.
lower
()
==
"true"
:
return
True
if
any
.
lower
()
==
"false"
:
return
False
return
any
!=
""
return
bool
(
any
)
def
_positive
(
val
):
v
=
int
(
val
)
if
v
<=
0
:
raise
ValueError
(
"Invalid value: %d"
%
v
)
return
v
def
_fix_lladdr
(
addr
):
foo
=
addr
.
lower
()
if
':'
in
addr
:
# Verify sanity and split
m
=
re
.
search
(
'^'
+
':'
.
join
([
'([0-9a-f]{1,2})'
]
*
6
)
+
'$'
,
foo
)
if
m
is
None
:
raise
ValueError
(
"Invalid address: `%s'."
%
addr
)
# Fill missing zeros and glue again
return
':'
.
join
((
'0'
*
(
2
-
len
(
x
))
+
x
for
x
in
m
.
groups
()))
# Fill missing zeros
foo
=
'0'
*
(
12
-
len
(
foo
))
+
foo
# Verify sanity and split
m
=
re
.
search
(
'^'
+
'([0-9a-f]{2})'
*
6
+
'$'
,
foo
)
if
m
is
None
:
raise
ValueError
(
"Invalid address: `%s'."
%
addr
)
# Glue
return
":"
.
join
(
m
.
groups
())
def
_make_getter
(
attr
,
conv
=
lambda
x
:
x
):
def
getter
(
self
):
return
conv
(
getattr
(
self
,
attr
))
return
getter
def
_make_setter
(
attr
,
conv
=
lambda
x
:
x
):
def
setter
(
self
,
value
):
if
value
==
None
:
setattr
(
self
,
attr
,
None
)
else
:
setattr
(
self
,
attr
,
conv
(
value
))
return
setter
# classes for internal use
class
interface
(
object
):
"""Class for internal use. It is mostly a data container used to easily
pass information around; with some convenience methods."""
# information for other parts of the code
changeable_attributes
=
[
"name"
,
"mtu"
,
"lladdr"
,
"broadcast"
,
"up"
,
"multicast"
,
"arp"
]
# Index should be read-only
index
=
property
(
_make_getter
(
"_index"
))
up
=
property
(
_make_getter
(
"_up"
),
_make_setter
(
"_up"
,
_any_to_bool
))
mtu
=
property
(
_make_getter
(
"_mtu"
),
_make_setter
(
"_mtu"
,
_positive
))
lladdr
=
property
(
_make_getter
(
"_lladdr"
),
_make_setter
(
"_lladdr"
,
_fix_lladdr
))
arp
=
property
(
_make_getter
(
"_arp"
),
_make_setter
(
"_arp"
,
_any_to_bool
))
multicast
=
property
(
_make_getter
(
"_mc"
),
_make_setter
(
"_mc"
,
_any_to_bool
))
def
__init__
(
self
,
index
=
None
,
name
=
None
,
up
=
None
,
mtu
=
None
,
lladdr
=
None
,
broadcast
=
None
,
multicast
=
None
,
arp
=
None
):
self
.
_index
=
_positive
(
index
)
if
index
is
not
None
else
None
self
.
name
=
name
self
.
up
=
up
self
.
mtu
=
mtu
self
.
lladdr
=
lladdr
self
.
broadcast
=
broadcast
self
.
multicast
=
multicast
self
.
arp
=
arp
def
__repr__
(
self
):
s
=
"%s.%s(index = %s, name = %s, up = %s, mtu = %s, lladdr = %s, "
s
+=
"broadcast = %s, multicast = %s, arp = %s)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
index
.
__repr__
(),
self
.
name
.
__repr__
(),
self
.
up
.
__repr__
(),
self
.
mtu
.
__repr__
(),
self
.
lladdr
.
__repr__
(),
self
.
broadcast
.
__repr__
(),
self
.
multicast
.
__repr__
(),
self
.
arp
.
__repr__
())
def
__sub__
(
self
,
o
):
"""Compare attributes and return a new object with just the attributes
that differ set (with the value they have in the first operand). The
index remains equal to the first operand."""
name
=
None
if
self
.
name
==
o
.
name
else
self
.
name
up
=
None
if
self
.
up
==
o
.
up
else
self
.
up
mtu
=
None
if
self
.
mtu
==
o
.
mtu
else
self
.
mtu
lladdr
=
None
if
self
.
lladdr
==
o
.
lladdr
else
self
.
lladdr
broadcast
=
None
if
self
.
broadcast
==
o
.
broadcast
else
self
.
broadcast
multicast
=
None
if
self
.
multicast
==
o
.
multicast
else
self
.
multicast
arp
=
None
if
self
.
arp
==
o
.
arp
else
self
.
arp
return
self
.
__class__
(
self
.
index
,
name
,
up
,
mtu
,
lladdr
,
broadcast
,
multicast
,
arp
)
class
bridge
(
interface
):
changeable_attributes
=
interface
.
changeable_attributes
+
[
"stp"
,
"forward_delay"
,
"hello_time"
,
"ageing_time"
,
"max_age"
]
# Index should be read-only
stp
=
property
(
_make_getter
(
"_stp"
),
_make_setter
(
"_stp"
,
_any_to_bool
))
forward_delay
=
property
(
_make_getter
(
"_forward_delay"
),
_make_setter
(
"_forward_delay"
,
float
))
hello_time
=
property
(
_make_getter
(
"_hello_time"
),
_make_setter
(
"_hello_time"
,
float
))
ageing_time
=
property
(
_make_getter
(
"_ageing_time"
),
_make_setter
(
"_ageing_time"
,
float
))
max_age
=
property
(
_make_getter
(
"_max_age"
),
_make_setter
(
"_max_age"
,
float
))
@
classmethod
def
upgrade
(
cls
,
iface
,
*
kargs
,
**
kwargs
):
"""Upgrade a interface to a bridge."""
return
cls
(
iface
.
index
,
iface
.
name
,
iface
.
up
,
iface
.
mtu
,
iface
.
lladdr
,
iface
.
broadcast
,
iface
.
multicast
,
iface
.
arp
,
*
kargs
,
**
kwargs
)
def
__init__
(
self
,
index
=
None
,
name
=
None
,
up
=
None
,
mtu
=
None
,
lladdr
=
None
,
broadcast
=
None
,
multicast
=
None
,
arp
=
None
,
stp
=
None
,
forward_delay
=
None
,
hello_time
=
None
,
ageing_time
=
None
,
max_age
=
None
):
super
(
bridge
,
self
).
__init__
(
index
,
name
,
up
,
mtu
,
lladdr
,
broadcast
,
multicast
,
arp
)
self
.
stp
=
stp
self
.
forward_delay
=
forward_delay
self
.
hello_time
=
hello_time
self
.
ageing_time
=
ageing_time
self
.
max_age
=
max_age
def
__repr__
(
self
):
s
=
"%s.%s(index = %s, name = %s, up = %s, mtu = %s, lladdr = %s, "
s
+=
"broadcast = %s, multicast = %s, arp = %s, stp = %s, "
s
+=
"forward_delay = %s, hello_time = %s, ageing_time = %s, "
s
+=
"max_age = %s)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
index
.
__repr__
(),
self
.
name
.
__repr__
(),
self
.
up
.
__repr__
(),
self
.
mtu
.
__repr__
(),
self
.
lladdr
.
__repr__
(),
self
.
broadcast
.
__repr__
(),
self
.
multicast
.
__repr__
(),
self
.
arp
.
__repr__
(),
self
.
stp
.
__repr__
(),
self
.
forward_delay
.
__repr__
(),
self
.
hello_time
.
__repr__
(),
self
.
ageing_time
.
__repr__
(),
self
.
max_age
.
__repr__
())
def
__sub__
(
self
,
o
):
r
=
super
(
bridge
,
self
).
__sub__
(
o
)
if
type
(
o
)
==
interface
:
return
r
r
.
stp
=
None
if
self
.
stp
==
o
.
stp
else
self
.
stp
r
.
hello_time
=
None
if
self
.
hello_time
==
o
.
hello_time
else
\
self
.
hello_time
r
.
forward_delay
=
None
if
self
.
forward_delay
==
o
.
forward_delay
else
\
self
.
forward_delay
r
.
ageing_time
=
None
if
self
.
ageing_time
==
o
.
ageing_time
else
\
self
.
ageing_time
r
.
max_age
=
None
if
self
.
max_age
==
o
.
max_age
else
self
.
max_age
return
r
class
address
(
object
):
"""Class for internal use. It is mostly a data container used to easily
pass information around; with some convenience methods. __eq__ and __hash__
are defined just to be able to easily find duplicated addresses."""
# broadcast is not taken into account for differentiating addresses
def
__eq__
(
self
,
o
):
if
not
isinstance
(
o
,
address
):
return
False
return
(
self
.
family
==
o
.
family
and
self
.
address
==
o
.
address
and
self
.
prefix_len
==
o
.
prefix_len
)
def
__hash__
(
self
):
h
=
(
self
.
address
.
__hash__
()
^
self
.
prefix_len
.
__hash__
()
^
self
.
family
.
__hash__
())
return
h
class
ipv4address
(
address
):
def
__init__
(
self
,
address
,
prefix_len
,
broadcast
):
self
.
address
=
address
self
.
prefix_len
=
int
(
prefix_len
)
self
.
broadcast
=
broadcast
self
.
family
=
socket
.
AF_INET
def
__repr__
(
self
):
s
=
"%s.%s(address = %s, prefix_len = %d, broadcast = %s)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
address
.
__repr__
(),
self
.
prefix_len
,
self
.
broadcast
.
__repr__
())
class
ipv6address
(
address
):
def
__init__
(
self
,
address
,
prefix_len
):
self
.
address
=
address
self
.
prefix_len
=
int
(
prefix_len
)
self
.
family
=
socket
.
AF_INET6
def
__repr__
(
self
):
s
=
"%s.%s(address = %s, prefix_len = %d)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
address
.
__repr__
(),
self
.
prefix_len
)
src/netns/iproute.py
View file @
23841d8d
# vim:ts=4:sw=4:et:ai:sts=4
import
os
,
re
,
subprocess
,
sys
import
netns.interface
# helpers
def
_any_to_bool
(
any
):
if
isinstance
(
any
,
bool
):
return
any
if
isinstance
(
any
,
int
):
return
any
!=
0
if
isinstance
(
any
,
str
):
if
any
.
isdigit
():
return
int
(
any
)
!=
0
if
any
.
lower
()
==
"true"
:
return
True
if
any
.
lower
()
==
"false"
:
return
False
return
any
!=
""
return
bool
(
any
)
def
_positive
(
val
):
v
=
int
(
val
)
if
v
<=
0
:
raise
ValueError
(
"Invalid value: %d"
%
v
)
return
v
def
_fix_lladdr
(
addr
):
foo
=
addr
.
lower
()
if
':'
in
addr
:
# Verify sanity and split
m
=
re
.
search
(
'^'
+
':'
.
join
([
'([0-9a-f]{1,2})'
]
*
6
)
+
'$'
,
foo
)
if
m
is
None
:
raise
ValueError
(
"Invalid address: `%s'."
%
addr
)
# Fill missing zeros and glue again
return
':'
.
join
((
'0'
*
(
2
-
len
(
x
))
+
x
for
x
in
m
.
groups
()))
# Fill missing zeros
foo
=
'0'
*
(
12
-
len
(
foo
))
+
foo
# Verify sanity and split
m
=
re
.
search
(
'^'
+
'([0-9a-f]{2})'
*
6
+
'$'
,
foo
)
if
m
is
None
:
raise
ValueError
(
"Invalid address: `%s'."
%
addr
)
# Glue
return
":"
.
join
(
m
.
groups
())
def
_make_getter
(
attr
,
conv
=
lambda
x
:
x
):
def
getter
(
self
):
return
conv
(
getattr
(
self
,
attr
))
return
getter
def
_make_setter
(
attr
,
conv
=
lambda
x
:
x
):
def
setter
(
self
,
value
):
if
value
==
None
:
setattr
(
self
,
attr
,
None
)
else
:
setattr
(
self
,
attr
,
conv
(
value
))
return
setter
# classes for internal use
class
interface
(
object
):
"""Class for internal use. It is mostly a data container used to easily
pass information around; with some convenience methods."""
# information for other parts of the code
changeable_attributes
=
[
"name"
,
"mtu"
,
"lladdr"
,
"broadcast"
,
"up"
,
"multicast"
,
"arp"
]
# Index should be read-only
index
=
property
(
_make_getter
(
"_index"
))
up
=
property
(
_make_getter
(
"_up"
),
_make_setter
(
"_up"
,
_any_to_bool
))
mtu
=
property
(
_make_getter
(
"_mtu"
),
_make_setter
(
"_mtu"
,
_positive
))
lladdr
=
property
(
_make_getter
(
"_lladdr"
),
_make_setter
(
"_lladdr"
,
_fix_lladdr
))
arp
=
property
(
_make_getter
(
"_arp"
),
_make_setter
(
"_arp"
,
_any_to_bool
))
multicast
=
property
(
_make_getter
(
"_mc"
),
_make_setter
(
"_mc"
,
_any_to_bool
))
def
__init__
(
self
,
index
=
None
,
name
=
None
,
up
=
None
,
mtu
=
None
,
lladdr
=
None
,
broadcast
=
None
,
multicast
=
None
,
arp
=
None
):
self
.
_index
=
_positive
(
index
)
if
index
is
not
None
else
None
self
.
name
=
name
self
.
up
=
up
self
.
mtu
=
mtu
self
.
lladdr
=
lladdr
self
.
broadcast
=
broadcast
self
.
multicast
=
multicast
self
.
arp
=
arp
def
__repr__
(
self
):
s
=
"%s.%s(index = %s, name = %s, up = %s, mtu = %s, lladdr = %s, "
s
+=
"broadcast = %s, multicast = %s, arp = %s)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
index
.
__repr__
(),
self
.
name
.
__repr__
(),
self
.
up
.
__repr__
(),
self
.
mtu
.
__repr__
(),
self
.
lladdr
.
__repr__
(),
self
.
broadcast
.
__repr__
(),
self
.
multicast
.
__repr__
(),
self
.
arp
.
__repr__
())
def
__sub__
(
self
,
o
):
"""Compare attributes and return a new object with just the attributes
that differ set (with the value they have in the first operand). The
index remains equal to the first operand."""
name
=
None
if
self
.
name
==
o
.
name
else
self
.
name
up
=
None
if
self
.
up
==
o
.
up
else
self
.
up
mtu
=
None
if
self
.
mtu
==
o
.
mtu
else
self
.
mtu
lladdr
=
None
if
self
.
lladdr
==
o
.
lladdr
else
self
.
lladdr
broadcast
=
None
if
self
.
broadcast
==
o
.
broadcast
else
self
.
broadcast
multicast
=
None
if
self
.
multicast
==
o
.
multicast
else
self
.
multicast
arp
=
None
if
self
.
arp
==
o
.
arp
else
self
.
arp
return
self
.
__class__
(
self
.
index
,
name
,
up
,
mtu
,
lladdr
,
broadcast
,
multicast
,
arp
)
class
bridge
(
interface
):
changeable_attributes
=
interface
.
changeable_attributes
+
[
"stp"
,
"forward_delay"
,
"hello_time"
,
"ageing_time"
,
"max_age"
]
# Index should be read-only
stp
=
property
(
_make_getter
(
"_stp"
),
_make_setter
(
"_stp"
,
_any_to_bool
))
forward_delay
=
property
(
_make_getter
(
"_forward_delay"
),
_make_setter
(
"_forward_delay"
,
float
))
hello_time
=
property
(
_make_getter
(
"_hello_time"
),
_make_setter
(
"_hello_time"
,
float
))
ageing_time
=
property
(
_make_getter
(
"_ageing_time"
),
_make_setter
(
"_ageing_time"
,
float
))
max_age
=
property
(
_make_getter
(
"_max_age"
),
_make_setter
(
"_max_age"
,
float
))
@
classmethod
def
upgrade
(
cls
,
iface
,
*
kargs
,
**
kwargs
):
"""Upgrade a interface to a bridge."""
return
cls
(
iface
.
index
,
iface
.
name
,
iface
.
up
,
iface
.
mtu
,
iface
.
lladdr
,
iface
.
broadcast
,
iface
.
multicast
,
iface
.
arp
,
*
kargs
,
**
kwargs
)
def
__init__
(
self
,
index
=
None
,
name
=
None
,
up
=
None
,
mtu
=
None
,
lladdr
=
None
,
broadcast
=
None
,
multicast
=
None
,
arp
=
None
,
stp
=
None
,
forward_delay
=
None
,
hello_time
=
None
,
ageing_time
=
None
,
max_age
=
None
):
super
(
bridge
,
self
).
__init__
(
index
,
name
,
up
,
mtu
,
lladdr
,
broadcast
,
multicast
,
arp
)
self
.
stp
=
stp
self
.
forward_delay
=
forward_delay
self
.
hello_time
=
hello_time
self
.
ageing_time
=
ageing_time
self
.
max_age
=
max_age
def
__repr__
(
self
):
s
=
"%s.%s(index = %s, name = %s, up = %s, mtu = %s, lladdr = %s, "
s
+=
"broadcast = %s, multicast = %s, arp = %s, stp = %s, "
s
+=
"forward_delay = %s, hello_time = %s, ageing_time = %s, "
s
+=
"max_age = %s)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
index
.
__repr__
(),
self
.
name
.
__repr__
(),
self
.
up
.
__repr__
(),
self
.
mtu
.
__repr__
(),
self
.
lladdr
.
__repr__
(),
self
.
broadcast
.
__repr__
(),
self
.
multicast
.
__repr__
(),
self
.
arp
.
__repr__
(),
self
.
stp
.
__repr__
(),
self
.
forward_delay
.
__repr__
(),
self
.
hello_time
.
__repr__
(),
self
.
ageing_time
.
__repr__
(),
self
.
max_age
.
__repr__
())
def
__sub__
(
self
,
o
):
r
=
super
(
bridge
,
self
).
__sub__
(
o
)
if
type
(
o
)
==
interface
:
return
r
r
.
stp
=
None
if
self
.
stp
==
o
.
stp
else
self
.
stp
r
.
hello_time
=
None
if
self
.
hello_time
==
o
.
hello_time
else
\
self
.
hello_time
r
.
forward_delay
=
None
if
self
.
forward_delay
==
o
.
forward_delay
else
\
self
.
forward_delay
r
.
ageing_time
=
None
if
self
.
ageing_time
==
o
.
ageing_time
else
\
self
.
ageing_time
r
.
max_age
=
None
if
self
.
max_age
==
o
.
max_age
else
self
.
max_age
return
r
class
address
(
object
):
"""Class for internal use. It is mostly a data container used to easily
pass information around; with some convenience methods. __eq__ and __hash__
are defined just to be able to easily find duplicated addresses."""
# broadcast is not taken into account for differentiating addresses
def
__eq__
(
self
,
o
):
if
not
isinstance
(
o
,
address
):
return
False
return
(
self
.
family
==
o
.
family
and
self
.
address
==
o
.
address
and
self
.
prefix_len
==
o
.
prefix_len
)
def
__hash__
(
self
):
h
=
(
self
.
address
.
__hash__
()
^
self
.
prefix_len
.
__hash__
()
^
self
.
family
.
__hash__
())
return
h
class
ipv4address
(
address
):
def
__init__
(
self
,
address
,
prefix_len
,
broadcast
):
self
.
address
=
address
self
.
prefix_len
=
int
(
prefix_len
)
self
.
broadcast
=
broadcast
self
.
family
=
socket
.
AF_INET
def
__repr__
(
self
):
s
=
"%s.%s(address = %s, prefix_len = %d, broadcast = %s)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
address
.
__repr__
(),
self
.
prefix_len
,
self
.
broadcast
.
__repr__
())
class
ipv6address
(
address
):
def
__init__
(
self
,
address
,
prefix_len
):
self
.
address
=
address
self
.
prefix_len
=
int
(
prefix_len
)
self
.
family
=
socket
.
AF_INET6
def
__repr__
(
self
):
s
=
"%s.%s(address = %s, prefix_len = %d)"
return
s
%
(
self
.
__module__
,
self
.
__class__
.
__name__
,
self
.
address
.
__repr__
(),
self
.
prefix_len
)
# XXX: ideally this should be replaced by netlink communication
# helpers
def
_execute
(
cmd
):
#print " ".join(cmd)#; return
null
=
open
(
'/dev/null'
,
'r+'
)
p
=
subprocess
.
Popen
(
cmd
,
stdout
=
null
,
stderr
=
subprocess
.
PIPE
)
out
,
err
=
p
.
communicate
()
if
p
.
returncode
!=
0
:
raise
RuntimeError
(
"Error executing `%s': %s"
%
(
" "
.
join
(
cmd
),
err
))
def
_get_if_name
(
iface
):
if
isinstance
(
iface
,
interface
):
if
iface
.
name
!=
None
:
return
iface
.
name
if
isinstance
(
iface
,
str
):
return
iface
return
get_if
(
iface
).
name
# Interface handling
def
get_if_data
():
"""Gets current interface information. Returns a tuple (byidx, bynam) in
...
...
@@ -28,7 +251,7 @@ def get_if_data():
match
=
re
.
search
(
r'^(\
d+): (
\S+): <(\
S+)> m
tu (\
d+) qdisc
\S+'
+
r'.*link/\
S+ ([
0-9a-f:]+) brd ([0-9a-f:]+)'
,
line
)
flags
=
match
.
group
(
3
).
split
(
","
)
i
=
netns
.
interface
.
interface
(
i
=
interface
(
index
=
match
.
group
(
1
),
name
=
match
.
group
(
2
),
up
=
"UP"
in
flags
,
...
...
@@ -42,7 +265,7 @@ def get_if_data():
def
get_if
(
iface
):
ifdata
=
get_if_data
()
if
isinstance
(
iface
,
netns
.
interface
.
interface
):
if
isinstance
(
iface
,
interface
):
if
iface
.
index
!=
None
:
return
ifdata
[
0
][
iface
.
index
]
else
:
...
...
@@ -163,14 +386,14 @@ def get_addr_data():
def
_parse_ip_addr
(
line
):
match
=
re
.
search
(
r'^inet ([0-9.]+)/(\
d+)(?:
brd ([0-9.]+))?'
,
line
)
if
match
!=
None
:
return
netns
.
interface
.
ipv4address
(
return
ipv4address
(
address
=
match
.
group
(
1
),
prefix_len
=
match
.
group
(
2
),
broadcast
=
match
.
group
(
3
))
match
=
re
.
search
(
r'^inet6 ([0-9a-f:]+)/(\
d+)
', line)
if match != None:
return
netns.interface.
ipv6address(
return ipv6address(
address = match.group(1),
prefix_len = match.group(2))
...
...
@@ -252,7 +475,7 @@ def get_bridge_data():
ports[iface.index] = [ifdata[1][x].index for x in brdata['
ports
']]
del brdata['
ports
']
bynam[iface.name] = byidx[iface.index] =
\
netns.interface.
bridge.upgrade(iface, **brdata)
bridge.upgrade(iface, **brdata)
return byidx, bynam, ports
def get_bridge(br):
...
...
@@ -260,11 +483,11 @@ def get_bridge(br):
brdata = _sysfs_read_br(iface.name)
#ports = [ifdata[1][x].index for x in brdata['
ports
']]
del brdata['
ports
']
return
netns.interface.
bridge.upgrade(iface, **brdata)
return bridge.upgrade(iface, **brdata)
def create_bridge(br):
if isinstance(br, str):
br =
netns.interface.
interface(name = br)
br = interface(name = br)
assert br.name
_execute(['
brctl
', '
addbr
', br.name])
try:
...
...
@@ -326,20 +549,3 @@ def del_bridge_port(br, iface):
brname
=
_get_if_name
(
br
)
_execute
([
'brctl'
,
'delif'
,
brname
,
ifname
])
# Useful stuff
def
_execute
(
cmd
):
#print " ".join(cmd)#; return
null
=
open
(
'/dev/null'
,
'r+'
)
p
=
subprocess
.
Popen
(
cmd
,
stdout
=
null
,
stderr
=
subprocess
.
PIPE
)
out
,
err
=
p
.
communicate
()
if
p
.
returncode
!=
0
:
raise
RuntimeError
(
"Error executing `%s': %s"
%
(
" "
.
join
(
cmd
),
err
))
def
_get_if_name
(
iface
):
if
isinstance
(
iface
,
netns
.
interface
.
interface
):
if
iface
.
name
!=
None
:
return
iface
.
name
if
isinstance
(
iface
,
str
):
return
iface
return
get_if
(
iface
).
name
src/netns/protocol.py
View file @
23841d8d
...
...
@@ -8,7 +8,7 @@ except ImportError:
from
yaml
import
Loader
,
Dumper
import
base64
,
os
,
passfd
,
re
,
signal
,
sys
,
traceback
,
unshare
,
yaml
import
netns.subprocess_
,
netns
.
iproute
,
netns
.
interface
import
netns.subprocess_
,
netns
.
iproute
# ============================================================================
# Server-side protocol implementation
...
...
@@ -339,7 +339,7 @@ class Server(object):
for
i
in
range
(
len
(
args
)
/
2
):
d
[
str
(
args
[
i
*
2
])]
=
args
[
i
*
2
+
1
]
iface
=
netns
.
i
nterfac
e
.
interface
(
**
d
)
iface
=
netns
.
i
prout
e
.
interface
(
**
d
)
netns
.
iproute
.
set_if
(
iface
)
self
.
reply
(
200
,
"Done."
)
...
...
@@ -360,17 +360,17 @@ class Server(object):
def
do_ADDR_ADD
(
self
,
cmdname
,
ifnr
,
address
,
prefixlen
,
broadcast
=
None
):
if
address
.
find
(
":"
)
<
0
:
# crude, I know
a
=
netns
.
i
nterfac
e
.
ipv4address
(
address
,
prefixlen
,
broadcast
)
a
=
netns
.
i
prout
e
.
ipv4address
(
address
,
prefixlen
,
broadcast
)
else
:
a
=
netns
.
i
nterfac
e
.
ipv6address
(
address
,
prefixlen
)
a
=
netns
.
i
prout
e
.
ipv6address
(
address
,
prefixlen
)
netns
.
iproute
.
add_addr
(
ifnr
,
a
)
self
.
reply
(
200
,
"Done."
)
def
do_ADDR_DEL
(
self
,
cmdname
,
ifnr
,
address
,
prefixlen
):
if
address
.
find
(
":"
)
<
0
:
# crude, I know
a
=
netns
.
i
nterfac
e
.
ipv4address
(
address
,
prefixlen
,
None
)
a
=
netns
.
i
prout
e
.
ipv4address
(
address
,
prefixlen
,
None
)
else
:
a
=
netns
.
i
nterfac
e
.
ipv6address
(
address
,
prefixlen
)
a
=
netns
.
i
prout
e
.
ipv6address
(
address
,
prefixlen
)
netns
.
iproute
.
del_addr
(
ifnr
,
a
)
self
.
reply
(
200
,
"Done."
)
...
...
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