summaryrefslogtreecommitdiff
path: root/src/conf_mode/interfaces-l2tpv3.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/interfaces-l2tpv3.py')
-rwxr-xr-xsrc/conf_mode/interfaces-l2tpv3.py100
1 files changed, 59 insertions, 41 deletions
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py
index ae49dadad..11ba9acdd 100755
--- a/src/conf_mode/interfaces-l2tpv3.py
+++ b/src/conf_mode/interfaces-l2tpv3.py
@@ -22,6 +22,8 @@ from copy import deepcopy
from vyos.config import Config
from vyos.ifconfig import L2TPv3If, Interface
from vyos import ConfigError
+from vyos.util import call
+from vyos.util import is_bridge_member
from netifaces import interfaces
default_config_data = {
@@ -33,6 +35,10 @@ default_config_data = {
'local_address': '',
'local_port': 5000,
'intf': '',
+ 'ipv6_autoconf': 0,
+ 'ipv6_eui64_prefix': '',
+ 'ipv6_forwarding': 1,
+ 'ipv6_dup_addr_detect': 1,
'mtu': 1488,
'peer_session_id': '',
'peer_tunnel_id': '',
@@ -42,15 +48,22 @@ default_config_data = {
'tunnel_id': ''
}
+def check_kmod():
+ modules = ['l2tp_eth', 'l2tp_netlink', 'l2tp_ip', 'l2tp_ip6']
+ for module in modules:
+ if not os.path.exists(f'/sys/module/{module}'):
+ if call(f'modprobe {module}') != 0:
+ raise ConfigError(f'Loading Kernel module {module} failed')
+
def get_config():
l2tpv3 = deepcopy(default_config_data)
conf = Config()
# determine tagNode instance
- try:
- l2tpv3['intf'] = os.environ['VYOS_TAGNODE_VALUE']
- except KeyError as E:
- print("Interface not specified")
+ if 'VYOS_TAGNODE_VALUE' not in os.environ:
+ raise ConfigError('Interface (VYOS_TAGNODE_VALUE) not specified')
+
+ l2tpv3['intf'] = os.environ['VYOS_TAGNODE_VALUE']
# Check if interface has been removed
if not conf.exists('interfaces l2tpv3 ' + l2tpv3['intf']):
@@ -94,6 +107,22 @@ def get_config():
if conf.exists('local-ip'):
l2tpv3['local_address'] = conf.return_value('local-ip')
+ # Enable acquisition of IPv6 address using stateless autoconfig (SLAAC)
+ if conf.exists('ipv6 address autoconf'):
+ l2tpv3['ipv6_autoconf'] = 1
+
+ # Get prefix for IPv6 addressing based on MAC address (EUI-64)
+ if conf.exists('ipv6 address eui64'):
+ l2tpv3['ipv6_eui64_prefix'] = conf.return_value('ipv6 address eui64')
+
+ # Disable IPv6 forwarding on this interface
+ if conf.exists('ipv6 disable-forwarding'):
+ l2tpv3['ipv6_forwarding'] = 0
+
+ # IPv6 Duplicate Address Detection (DAD) tries
+ if conf.exists('ipv6 dup-addr-detect-transmits'):
+ l2tpv3['ipv6_dup_addr_detect'] = int(conf.return_value('ipv6 dup-addr-detect-transmits'))
+
# Maximum Transmission Unit (MTU)
if conf.exists('mtu'):
l2tpv3['mtu'] = int(conf.return_value('mtu'))
@@ -126,61 +155,41 @@ def get_config():
def verify(l2tpv3):
+ interface = l2tpv3['intf']
+
if l2tpv3['deleted']:
- # bail out early
+ is_member, bridge = is_bridge_member(interface)
+ if is_member:
+ # can not use a f'' formatted-string here as bridge would not get
+ # expanded in the print statement
+ raise ConfigError('Can not delete interface "{0}" as it ' \
+ 'is a member of bridge "{1}"!'.format(interface, bridge))
return None
if not l2tpv3['local_address']:
- raise ConfigError('Must configure the l2tpv3 local-ip for {}'.format(l2tpv3['intf']))
+ raise ConfigError(f'Must configure the l2tpv3 local-ip for {interface}')
if not l2tpv3['remote_address']:
- raise ConfigError('Must configure the l2tpv3 remote-ip for {}'.format(l2tpv3['intf']))
+ raise ConfigError(f'Must configure the l2tpv3 remote-ip for {interface}')
if not l2tpv3['tunnel_id']:
- raise ConfigError('Must configure the l2tpv3 tunnel-id for {}'.format(l2tpv3['intf']))
+ raise ConfigError(f'Must configure the l2tpv3 tunnel-id for {interface}')
if not l2tpv3['peer_tunnel_id']:
- raise ConfigError('Must configure the l2tpv3 peer-tunnel-id for {}'.format(l2tpv3['intf']))
+ raise ConfigError(f'Must configure the l2tpv3 peer-tunnel-id for {interface}')
if not l2tpv3['session_id']:
- raise ConfigError('Must configure the l2tpv3 session-id for {}'.format(l2tpv3['intf']))
+ raise ConfigError(f'Must configure the l2tpv3 session-id for {interface}')
if not l2tpv3['peer_session_id']:
- raise ConfigError('Must configure the l2tpv3 peer-session-id for {}'.format(l2tpv3['intf']))
+ raise ConfigError(f'Must configure the l2tpv3 peer-session-id for {interface}')
return None
def generate(l2tpv3):
- if l2tpv3['deleted']:
- # bail out early
- return None
-
- # initialize kernel module if not loaded
- if not os.path.isdir('/sys/module/l2tp_eth'):
- if os.system('modprobe l2tp_eth') != 0:
- raise ConfigError("failed loading l2tp_eth kernel module")
-
- if not os.path.isdir('/sys/module/l2tp_netlink'):
- if os.system('modprobe l2tp_netlink') != 0:
- raise ConfigError("failed loading l2tp_netlink kernel module")
-
- if not os.path.isdir('/sys/module/l2tp_ip'):
- if os.system('modprobe l2tp_ip') != 0:
- raise ConfigError("failed loading l2tp_ip kernel module")
-
- if l2tpv3['encapsulation'] == 'ip':
- if not os.path.isdir('/sys/module/l2tp_ip'):
- if os.system('modprobe l2tp_ip') != 0:
- raise ConfigError("failed loading l2tp_ip kernel module")
-
- if not os.path.isdir('/sys/module/l2tp_ip6 '):
- if os.system('modprobe l2tp_ip6 ') != 0:
- raise ConfigError("failed loading l2tp_ip6 kernel module")
-
return None
-
def apply(l2tpv3):
# L2TPv3 interface needs to be created/deleted on-block, instead of
# passing a ton of arguments, I just use a dict that is managed by
@@ -193,7 +202,7 @@ def apply(l2tpv3):
# always delete it first.
conf['session_id'] = l2tpv3['session_id']
conf['tunnel_id'] = l2tpv3['tunnel_id']
- l = L2TPv3If(l2tpv3['intf'], config=conf)
+ l = L2TPv3If(l2tpv3['intf'], **conf)
l.remove()
if not l2tpv3['deleted']:
@@ -208,11 +217,19 @@ def apply(l2tpv3):
conf['peer_session_id'] = l2tpv3['peer_session_id']
# Finally create the new interface
- l = L2TPv3If(l2tpv3['intf'], config=conf)
+ l = L2TPv3If(l2tpv3['intf'], **conf)
# update interface description used e.g. by SNMP
l.set_alias(l2tpv3['description'])
# Maximum Transfer Unit (MTU)
l.set_mtu(l2tpv3['mtu'])
+ # IPv6 address autoconfiguration
+ l.set_ipv6_autoconf(l2tpv3['ipv6_autoconf'])
+ # IPv6 EUI-based address
+ l.set_ipv6_eui64_address(l2tpv3['ipv6_eui64_prefix'])
+ # IPv6 forwarding
+ l.set_ipv6_forwarding(l2tpv3['ipv6_forwarding'])
+ # IPv6 Duplicate Address Detection (DAD) tries
+ l.set_ipv6_dad_messages(l2tpv3['ipv6_dup_addr_detect'])
# Configure interface address(es) - no need to implicitly delete the
# old addresses as they have already been removed by deleting the
@@ -224,12 +241,13 @@ def apply(l2tpv3):
# we will only re-enable the interface if it is not administratively
# disabled
if not l2tpv3['disable']:
- l.set_state('up')
+ l.set_admin_state('up')
return None
if __name__ == '__main__':
try:
+ check_kmod()
c = get_config()
verify(c)
generate(c)