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
Xavier Thompson
slapos.core
Commits
b496108c
Commit
b496108c
authored
Nov 04, 2022
by
Xavier Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP remember to add tap to interface
parent
d89dafbd
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
110 additions
and
21 deletions
+110
-21
slapos/format.py
slapos/format.py
+110
-21
No files found.
slapos/format.py
View file @
b496108c
...
...
@@ -373,7 +373,7 @@ class Partition(object):
if
ipv6_range
:
self
.
ipv6_range
=
ipaddress
.
IPv6Network
(
ipv6_range
,
strict
=
False
)
elif
conf
.
ipv6_range
:
self
.
ipv6_range
=
interface
.
get
Partition
IPv6Range
(
index
)
self
.
ipv6_range
=
interface
.
getIPv6Range
(
index
)
# Tap
tap
=
options
[
'network_interface'
]
if
tap
or
conf
.
create_tap
:
...
...
@@ -468,7 +468,7 @@ class Tap(object):
interface
=
computer
.
interface
options
=
definition
[
name
]
self
.
name
=
name
#
Tap IPv4: tap-to-host gateway and host-to-tap address
#
IPv4 (gateway=host and address=application)
ipv4_gateway
=
options
[
'ipv4_gateway'
]
ipv4_address
=
options
[
'ipv4_address'
]
if
bool
(
ipv4_gateway
)
!=
bool
(
ipv4_address
):
...
...
@@ -482,23 +482,21 @@ class Tap(object):
elif
interface
.
tap_ipv4_network
:
self
.
ipv4_gateway
=
interface
.
getTapIPv4Gateway
(
index
)
self
.
ipv4_address
=
interface
.
getTapIPv4Range
(
index
)
#
Tap IPv6: host-to-tap gateway and tap-to-host address
#
IPv6 (gateway=application and address=host)
ipv6_gateway
=
options
[
'ipv6_gateway'
]
ipv6_address
=
options
[
'ipv6_address'
]
if
not
ipv6_gateway
and
ipv6_address
:
if
bool
(
ipv6_gateway
)
!=
bool
(
ipv6_address
)
:
conf
.
wrong
(
"Options %r
for tap %s must not be provided without option %
r"
,
"Options %r
and %r for tap %s must either both be provided or neithe
r"
,
'ipv6_address'
,
'ipv6_gateway'
,
name
)
if
ipv6_gateway
:
self
.
ipv6_gateway
=
ipv6_gateway
=
ipaddress
.
IPv6Interface
(
ipv6_gateway
)
if
ipv6_address
:
self
.
ipv6_gateway
=
ipaddress
.
IPv6Interface
(
ipv6_gateway
)
self
.
ipv6_address
=
ipaddress
.
IPv6Interface
(
ipv6_address
)
else
:
self
.
ipv6_address
=
addressFromNetwork
(
ipv6_gateway
.
network
,
-
1
)
elif
conf
.
tap_ipv6
:
self
.
ipv6_gateway
=
ipv6_gateway
=
interface
.
getTapIPv6Range
(
index
)
self
.
ipv6_address
=
addressFromNetwork
(
ipv6_gateway
.
network
,
-
1
)
ipv6_network
=
interface
.
getIPv6Range
(
index
,
'tap'
)
self
.
ipv6_gateway
=
addressFromNetwork
(
ipv6_network
,
1
)
self
.
ipv6_address
=
addressFromNetwork
(
ipv6_network
,
-
1
)
def
format
(
self
,
interface
,
user
):
conf
=
interface
.
conf
...
...
@@ -506,6 +504,9 @@ class Tap(object):
self
.
ensureTap
(
user
,
conf
)
# Create/ensure IPv4 routes
self
.
ensureIPv4Routes
(
conf
)
# Add host IPV6 address to interface
if
self
.
ipv6_address
:
interface
.
addIPv6
(
self
.
ipv6_address
)
# Create/ensure IPv6 routes
self
.
ensureIPv6Routes
(
conf
)
...
...
@@ -570,6 +571,100 @@ class Tap(object):
call
([
'ip'
,
'-6'
,
'route'
,
'add'
,
network
,
'dev'
,
tap
,
'via'
,
cidr
])
class
Tun
(
object
):
name
:
str
ipv4_address
:
ipaddress
.
IPv4Interface
=
None
ipv6_address
:
ipaddress
.
IPv6Interface
=
None
def
__init__
(
self
,
name
,
index
,
computer
,
definition
):
conf
=
computer
.
conf
interface
=
computer
.
interface
options
=
definition
[
name
]
self
.
name
=
name
# IPv4
ipv4_address
=
options
[
'ipv4_address'
]
if
ipv4_address
:
self
.
ipv4_address
=
ipaddress
.
IPv4Interface
(
ipv4_address
)
else
:
self
.
ipv4_address
=
interface
.
getTunIPv4Range
(
index
)
# IPv6
ipv6_address
=
options
[
'ipv6_address'
]
if
ipv6_address
:
self
.
ipv6_address
=
ipaddress
.
IPv6Interface
(
ipv6_address
)
elif
conf
.
tap_ipv6
:
ipv6_network
=
interface
.
getIPv6Range
(
index
,
'tun'
)
self
.
ipv6_address
=
addressFromNetwork
(
ipv6_network
,
-
1
)
def
format
(
self
,
interface
,
user
):
conf
=
interface
.
conf
# Create/ensure tun interface
self
.
ensureTun
(
user
,
conf
)
# Create/ensure IPv4 routes
self
.
ensureIPv4Routes
(
conf
)
# Create/ensure IPv6 routes
self
.
ensureIPv6Routes
(
conf
)
def
ensureTun
(
self
,
user
,
conf
):
tun
=
self
.
name
user
=
user
.
name
check_file
=
'/sys/devices/virtual/net/%s/owner'
%
tun
if
os
.
path
.
exists
(
check_file
):
with
open
(
check_file
)
as
f
:
owner_id
=
f
.
read
().
strip
()
try
:
owner_id
=
int
(
owner_id
)
except
ValueError
:
owner_id
=
pwd
.
getpwnam
(
owner_id
).
pw_uid
user_id
=
pwd
.
getpwnam
(
user
).
pw_uid
if
owner_id
!=
user_id
:
conf
.
abort
(
"Wrong owner of tun %s, expected %s (%s) got %s"
,
tun
,
user_id
,
user
,
owner_id
)
else
:
call
([
'ip'
,
'tuntap'
,
'add'
,
'dev'
,
tun
,
'mode'
,
'tun'
,
'user'
,
user
])
call
([
'ip'
,
'link'
,
'set'
,
tun
,
'up'
])
def
ensureIPv4Routes
(
self
,
conf
):
tun
=
self
.
name
ipv4
=
self
.
ipv4_address
if
ipv4
:
cidr
=
str
(
ipv4
)
code
,
out
=
call
([
'ip'
,
'route'
,
'show'
,
cidr
],
throw
=
False
)
if
code
!=
0
or
cidr
not
in
out
or
tun
not
in
out
:
call
([
'ip'
,
'route'
,
'add'
,
cidr
,
'dev'
,
tun
])
if
ipv4
.
network
.
prefixlen
<
32
:
network
=
str
(
ipv4
.
network
)
code
,
out
=
call
([
'ip'
,
'route'
,
'show'
,
network
],
throw
=
False
)
if
code
!=
0
or
'dev '
+
tun
not
in
out
:
call
([
'ip'
,
'route'
,
'add'
,
network
,
'dev'
,
tun
,
'via'
,
cidr
])
elif
'via '
+
cidr
not
in
out
:
conf
.
abort
(
"Route to network %s (%s) exists but is not via %s"
,
network
,
tap
,
cidr
)
def
ensureIPv6Routes
(
self
,
conf
):
tap
=
self
.
name
ipv6
=
self
.
ipv6_gateway
if
ipv6
:
cidr
=
str
(
ipv6
)
code
,
out
=
call
([
'ip'
,
'-6'
,
'route'
,
'show'
,
cidr
],
throw
=
False
)
if
code
!=
0
or
cidr
not
in
out
or
tap
not
in
out
:
call
([
'ip'
,
'-6'
,
'route'
,
'add'
,
cidr
,
'dev'
,
tap
])
network
=
str
(
ipv6
.
network
)
code
,
out
=
call
([
'ip'
,
'-6'
,
'route'
,
'show'
,
network
],
throw
=
False
)
if
code
!=
0
or
'dev '
+
tap
not
in
out
:
call
([
'ip'
,
'-6'
,
'route'
,
'add'
,
network
,
'dev'
,
tap
,
'via'
,
cidr
])
elif
'via '
+
cidr
not
in
out
:
conf
.
warn
(
"Route to network %s (%s) exists but is not via %s, fixing it"
,
network
,
tap
,
cidr
)
call
([
'ip'
,
'-6'
,
'route'
,
'del'
,
network
,
'dev'
,
tap
])
call
([
'ip'
,
'-6'
,
'route'
,
'add'
,
network
,
'dev'
,
tap
,
'via'
,
cidr
])
class
Interface
(
object
):
ipv4_interface
:
str
ipv6_interface
:
str
...
...
@@ -674,20 +769,14 @@ class Interface(object):
def
getPartitionIPv6Addr
(
self
,
index
):
return
addressFromNetwork
(
self
.
ipv6_network
,
index
+
2
)
def
getPartitionIPv6Range
(
self
,
index
):
def
getIPv6Range
(
self
,
index
,
mode
=
'partition'
):
k
=
(
'partition'
,
'tap'
,
'tun'
).
index
(
mode
)
+
1
network
=
self
.
ipv6_network
prefixlen
=
network
.
prefixlen
+
16
bits
=
128
-
network
.
prefixlen
addr
=
network
[(
1
<<
(
bits
-
2
))
+
(
index
<<
(
128
-
prefixlen
))]
addr
=
network
[(
k
<<
(
bits
-
2
))
+
(
index
<<
(
128
-
prefixlen
))]
return
ipaddress
.
IPv6Network
((
addr
,
prefixlen
))
def
getTapIPv6Range
(
self
,
index
):
network
=
self
.
ipv6_network
prefixlen
=
network
.
prefixlen
+
16
bits
=
128
-
network
.
prefixlen
addr
=
network
[(
2
<<
(
bits
-
2
))
+
(
index
<<
(
128
-
prefixlen
))
+
1
]
return
ipaddress
.
IPv6Interface
((
addr
,
prefixlen
))
def
enableIPv6NonLocalBind
(
self
):
call
([
'sysctl'
,
'net.ipv6.ip_nonlocal_bind=1'
])
network
=
str
(
self
.
ipv6_network
)
...
...
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