Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
slapos.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
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
Léo-Paul Géneau
slapos.core
Commits
a5667e05
Commit
a5667e05
authored
Nov 24, 2022
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slapformat: Add IPv6 to tun
parent
8d2794d0
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
24 deletions
+66
-24
slapos/format.py
slapos/format.py
+58
-24
slapos/util.py
slapos/util.py
+8
-0
No files found.
slapos/format.py
View file @
a5667e05
...
...
@@ -58,7 +58,11 @@ import six
import
lxml.etree
import
xml_marshaller.xml_marshaller
from
slapos.util
import
dumps
,
mkdir_p
,
ipv6FromBin
,
binFromIpv6
,
lenNetmaskIpv6
,
getPartitionIpv6Addr
,
getPartitionIpv6Range
,
getTapIpv6Range
,
netmaskFromLenIPv6
from
slapos.util
import
(
dumps
,
mkdir_p
,
ipv6FromBin
,
binFromIpv6
,
lenNetmaskIpv6
,
getPartitionIpv6Addr
,
getPartitionIpv6Range
,
getTapIpv6Range
,
getTunIpv6Range
,
netmaskFromLenIPv6
,
getIpv6RangeFirstAddr
)
import
slapos.slap
as
slap
from
slapos
import
version
from
slapos
import
manager
as
slapmanager
...
...
@@ -462,11 +466,25 @@ class Computer(object):
else
:
tap
=
Tap
(
partition_dict
[
'reference'
])
if
partition_dict
.
get
(
'tun'
)
is
not
None
and
partition_dict
[
'tun'
].
get
(
'ipv4_addr'
)
is
not
None
:
tun
=
Tun
(
partition_dict
[
'tun'
][
'name'
],
partition_index
,
partition_amount
)
tun
.
ipv4_addr
=
partition_dict
[
'tun'
][
'ipv4_addr'
]
tun_dict
=
partition_dict
.
get
(
'tun'
)
if
tun_dict
is
None
:
if
config
.
create_tun
:
tun
=
Tun
(
"slaptun"
+
str
(
partition_index
),
partition_index
,
partition_amount
,
config
.
tun_ipv6
)
else
:
tun
=
Tun
(
"slaptun"
+
str
(
partition_index
),
partition_index
,
partition_amount
)
tun
=
None
else
:
ipv4_addr
=
tun_dict
.
get
(
'ipv4_addr'
)
ipv6_addr
=
tun_dict
.
get
(
'ipv6_addr'
)
needs_ipv6
=
not
ipv6_addr
and
config
.
tun_ipv6
tun
=
Tun
(
tun_dict
[
'name'
],
partition_index
,
partition_amount
,
needs_ipv6
)
if
ipv4_addr
:
tun
.
ipv4_addr
=
ipv4_addr
tun
.
ipv4_netmask
=
tun_dict
[
'ipv4_netmask'
]
tun
.
ipv4_network
=
tun_dict
[
'ipv4_network'
]
if
ipv6_addr
:
tun
.
ipv6_addr
=
ipv6_addr
tun
.
ipv6_netmask
=
tun_dict
[
'ipv6_netmask'
]
tun
.
ipv6_network
=
tun_dict
[
'ipv6_network'
]
address_list
=
partition_dict
[
'address_list'
]
ipv6_range
=
partition_dict
.
get
(
'ipv6_range'
,
{})
...
...
@@ -479,7 +497,7 @@ class Computer(object):
address_list
=
address_list
,
ipv6_range
=
ipv6_range
,
tap
=
tap
,
tun
=
tun
if
config
.
create_tun
else
None
,
tun
=
tun
,
external_storage_list
=
external_storage_list
,
)
...
...
@@ -633,12 +651,10 @@ class Computer(object):
tap
=
partition
.
tap
)
# construct ipv6_network (16 bit more than the computer network)
netmask_len
=
lenNetmaskIpv6
(
self
.
interface
.
getGlobalScopeAddressList
()[
0
][
'netmask'
])
+
16
prefix
=
binFromIpv6
(
partition
.
tap
.
ipv6_addr
)[:
netmask_len
]
network_addr
=
ipv6FromBin
(
prefix
)
partition
.
tap
.
ipv6_gateway
=
"{}1"
.
format
(
network_addr
)
# address network::1 will be inside the VM
partition
.
tap
.
ipv6_gateway
=
ipv6FromBin
(
binFromIpv6
(
partition
.
tap
.
ipv6_gateway
))
# correctly format the IPv6
partition
.
tap
.
ipv6_network
=
"{}/{}"
.
format
(
network_addr
,
netmask_len
)
prefixlen
=
lenNetmaskIpv6
(
self
.
interface
.
getGlobalScopeAddressList
()[
0
][
'netmask'
])
+
16
gateway_addr
=
getIpv6RangeFirstAddr
(
partition
.
tap
.
ipv6_addr
,
prefixlen
)
partition
.
tap
.
ipv6_gateway
=
gateway_addr
partition
.
tap
.
ipv6_network
=
"{}/{}"
.
format
(
gateway_addr
,
prefixlen
)
else
:
partition
.
tap
.
ipv6_addr
=
''
partition
.
tap
.
ipv6_netmask
=
''
...
...
@@ -651,6 +667,13 @@ class Computer(object):
if
partition
.
tun
is
not
None
:
# create TUN interface per partition as well
partition
.
tun
.
createWithOwner
(
owner
)
if
partition
.
tun
.
_needs_ipv6
:
ipv6_dict
=
self
.
interface
.
generateIPv6Range
(
partition_index
,
tun
=
True
)
prefixlen
=
ipv6_dict
[
'prefixlen'
]
ipv6_addr
=
getIpv6RangeFirstAddr
(
ipv6_dict
[
'addr'
],
prefixlen
)
partition
.
tun
.
ipv6_addr
=
ipv6_addr
partition
.
tun
.
ipv6_netmask
=
ipv6_dict
[
'netmask'
]
partition
.
tun
.
ipv6_network
=
"%s/%d"
%
(
ipv6_addr
,
prefixlen
)
partition
.
tun
.
createRoutes
()
# Reconstructing partition's address
...
...
@@ -954,13 +977,14 @@ class Tun(Tap):
BASE_MASK
=
12
BASE_NETWORK
=
"172.16.0.0"
def
__init__
(
self
,
name
,
sequence
=
None
,
partitions
=
None
):
def
__init__
(
self
,
name
,
sequence
=
None
,
partitions
=
None
,
needs_ipv6
=
False
):
"""Create TUN interface with subnet according to the optional ``sequence`` number.
:param name: name which will appear in ``ip list`` afterwards
:param sequence: {int} position of this TUN among all ``partitions``
"""
super
(
Tun
,
self
).
__init__
(
name
)
self
.
_needs_ipv6
=
needs_ipv6
if
sequence
is
not
None
:
assert
0
<=
sequence
<
partitions
,
"0 <= {} < {}"
.
format
(
sequence
,
partitions
)
# create base IPNetwork
...
...
@@ -980,14 +1004,20 @@ class Tun(Tap):
"""Extend for physical addition of network address because TAP let this on external class."""
if
self
.
ipv4_network
:
# add an address
code
,
_
=
callAndRead
([
'ip'
,
'addr'
,
'add'
,
self
.
ipv4_network
,
'dev'
,
self
.
name
],
code
,
_
=
callAndRead
(
[
'ip'
,
'addr'
,
'add'
,
self
.
ipv4_network
,
'dev'
,
self
.
name
],
raise_on_error
=
False
)
if
code
==
0
:
# address added to the interface - wait
time
.
sleep
(
1
)
if
self
.
ipv6_network
:
# add an address
code
,
_
=
callAndRead
(
[
'ip'
,
'addr'
,
'add'
,
self
.
ipv6_network
,
'dev'
,
self
.
name
],
raise_on_error
=
False
)
if
code
==
0
:
# address added to the interface - wait
time
.
sleep
(
1
)
else
:
raise
RuntimeError
(
"Cannot setup address on interface {}. "
"Address is missing."
.
format
(
self
.
name
))
class
Interface
(
object
):
...
...
@@ -1291,7 +1321,7 @@ class Interface(object):
raise
AddressGenerationError
(
addr
)
def
generateIPv6Range
(
self
,
i
):
def
generateIPv6Range
(
self
,
i
,
tun
=
False
):
"""
Generate an IPv6 range included in the IPv6 range of the interface. The IPv6 range depends on the partition index i.
...
...
@@ -1312,6 +1342,9 @@ class Interface(object):
interface_addr_list
=
self
.
getGlobalScopeAddressList
()
address_dict
=
interface_addr_list
[
0
]
address_dict
[
'prefixlen'
]
=
lenNetmaskIpv6
(
address_dict
[
'netmask'
])
if
tun
:
ipv6_range
=
getTunIpv6Range
(
address_dict
,
i
)
else
:
ipv6_range
=
getPartitionIpv6Range
(
address_dict
,
i
)
ipv6_range
[
'netmask'
]
=
netmaskFromLenIPv6
(
ipv6_range
[
'prefixlen'
])
ipv6_range
[
'network'
]
=
'%(addr)s/%(prefixlen)d'
%
ipv6_range
...
...
@@ -1389,7 +1422,7 @@ def parse_computer_definition(conf, definition_path):
tap
=
Tap
(
computer_definition
.
get
(
section
,
'network_interface'
))
tun
=
Tun
(
"slaptun"
+
str
(
partition_number
),
partition_number
,
int
(
conf
.
partition_amount
))
if
conf
.
create_tun
else
None
int
(
conf
.
partition_amount
,
conf
.
tun_ipv6
))
if
conf
.
create_tun
else
None
partition
=
Partition
(
reference
=
computer_definition
.
get
(
section
,
'pathname'
),
path
=
os
.
path
.
join
(
conf
.
instance_root
,
computer_definition
.
get
(
section
,
'pathname'
)),
...
...
@@ -1461,7 +1494,7 @@ def parse_computer_xml(conf, xml_path):
address_list
=
None
,
ipv6_range
=
None
,
tap
=
Tap
(
'%s%s'
%
(
conf
.
tap_base_name
,
i
)),
tun
=
Tun
(
'slaptun'
+
str
(
i
),
i
,
partition_amount
)
if
conf
.
create_tun
else
None
tun
=
Tun
(
'slaptun'
+
str
(
i
),
i
,
partition_amount
,
conf
.
tun_ipv6
)
if
conf
.
create_tun
else
None
)
computer
.
partition_list
.
append
(
partition
)
...
...
@@ -1549,11 +1582,12 @@ class FormatConfig(object):
ipv6_interface
=
None
partition_has_ipv6_range
=
True
create_tap
=
True
create_tun
=
False
tap_base_name
=
None
tap_ipv6
=
True
tap_gateway_interface
=
''
ipv4_local_network
=
None
create_tun
=
False
tun_ipv6
=
True
# User options
alter_user
=
'True'
# modifiable by cmdline
...
...
@@ -1612,7 +1646,7 @@ class FormatConfig(object):
raise
UsageError
(
message
)
# Convert strings to booleans
for
option
in
[
'alter_network'
,
'alter_user'
,
'partition_has_ipv6_range'
,
'create_tap'
,
'create_tun'
,
'tap_ipv6'
]:
for
option
in
[
'alter_network'
,
'alter_user'
,
'partition_has_ipv6_range'
,
'create_tap'
,
'create_tun'
,
'tap_ipv6'
,
'tun_ipv6'
]:
attr
=
getattr
(
self
,
option
)
if
isinstance
(
attr
,
str
):
if
attr
.
lower
()
==
'true'
:
...
...
slapos/util.py
View file @
a5667e05
...
...
@@ -250,6 +250,14 @@ getPartitionIpv6Range = getIpv6RangeFactory(1, '0')
getTapIpv6Range
=
getIpv6RangeFactory
(
2
,
'1'
)
getTunIpv6Range
=
getIpv6RangeFactory
(
3
,
'0'
)
def
getIpv6RangeFirstAddr
(
addr
,
prefixlen
):
addr_1
=
"%s1"
%
ipv6FromBin
(
binFromIpv6
(
addr
)[:
prefixlen
])
return
ipv6FromBin
(
binFromIpv6
(
addr_1
))
# correctly format the IPv6
def
lenNetmaskIpv6
(
netmask
):
"""Convert string represented netmask to its integer prefix"""
# Since version 0.10.7 of netifaces, the netmask is something like "ffff::/16",
...
...
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