diff options
Diffstat (limited to 'src/conf_mode/interfaces-l2tpv3.py')
-rwxr-xr-x | src/conf_mode/interfaces-l2tpv3.py | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/src/conf_mode/interfaces-l2tpv3.py b/src/conf_mode/interfaces-l2tpv3.py index 8312d6f37..cdfc6ea84 100755 --- a/src/conf_mode/interfaces-l2tpv3.py +++ b/src/conf_mode/interfaces-l2tpv3.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2019 VyOS maintainers and contributors +# Copyright (C) 2019-2020 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -24,7 +24,7 @@ from vyos.config import Config from vyos.ifconfig import L2TPv3If, Interface from vyos import ConfigError from vyos.util import call -from vyos.validate import is_bridge_member +from vyos.validate import is_member, is_addr_assigned default_config_data = { 'address': [], @@ -35,8 +35,9 @@ default_config_data = { 'local_address': '', 'local_port': 5000, 'intf': '', + 'ipv6_accept_ra': 1, 'ipv6_autoconf': 0, - 'ipv6_eui64_prefix': '', + 'ipv6_eui64_prefix': [], 'ipv6_forwarding': 1, 'ipv6_dup_addr_detect': 1, 'is_bridge_member': False, @@ -66,12 +67,13 @@ def get_config(): l2tpv3['intf'] = os.environ['VYOS_TAGNODE_VALUE'] + # check if interface is member of a bridge + l2tpv3['is_bridge_member'] = is_member(conf, l2tpv3['intf'], 'bridge') + # Check if interface has been removed if not conf.exists('interfaces l2tpv3 ' + l2tpv3['intf']): l2tpv3['deleted'] = True interface = l2tpv3['intf'] - # check if interface is member if a bridge - l2tpv3['is_bridge_member'] = is_bridge_member(conf, interface) # to delete the l2tpv3 interface we need the current tunnel_id and session_id if conf.exists_effective(f'interfaces l2tpv3 {interface} tunnel-id'): @@ -113,9 +115,15 @@ def get_config(): if conf.exists('ipv6 address autoconf'): l2tpv3['ipv6_autoconf'] = 1 - # Get prefix for IPv6 addressing based on MAC address (EUI-64) + # Get prefixes 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') + l2tpv3['ipv6_eui64_prefix'] = conf.return_values('ipv6 address eui64') + + # Remove the default link-local address if set. + if not ( conf.exists('ipv6 address no-default-link-local') or + l2tpv3['is_bridge_member'] ): + # add the link-local by default to make IPv6 work + l2tpv3['ipv6_eui64_prefix'].append('fe80::/64') # Disable IPv6 forwarding on this interface if conf.exists('ipv6 disable-forwarding'): @@ -125,6 +133,11 @@ def get_config(): if conf.exists('ipv6 dup-addr-detect-transmits'): l2tpv3['ipv6_dup_addr_detect'] = int(conf.return_value('ipv6 dup-addr-detect-transmits')) + # to make IPv6 SLAAC and DHCPv6 work with forwarding=1, + # accept_ra must be 2 + if l2tpv3['ipv6_autoconf'] or 'dhcpv6' in l2tpv3['address']: + l2tpv3['ipv6_accept_ra'] = 2 + # Maximum Transmission Unit (MTU) if conf.exists('mtu'): l2tpv3['mtu'] = int(conf.return_value('mtu')) @@ -161,15 +174,18 @@ def verify(l2tpv3): if l2tpv3['deleted']: if l2tpv3['is_bridge_member']: - interface = l2tpv3['intf'] - bridge = l2tpv3['is_bridge_member'] - raise ConfigError(f'Interface "{interface}" can not be deleted as it belongs to bridge "{bridge}"!') + raise ConfigError(( + f'Interface "{l2tpv3["intf"]}" cannot be deleted as it is a ' + f'member of bridge "{l2tpv3["is_bridge_member"]}"!')) return None if not l2tpv3['local_address']: raise ConfigError(f'Must configure the l2tpv3 local-ip for {interface}') + if not is_addr_assigned(l2tpv3['local_address']): + raise ConfigError(f'Must use a configured IP on l2tpv3 local-ip for {interface}') + if not l2tpv3['remote_address']: raise ConfigError(f'Must configure the l2tpv3 remote-ip for {interface}') @@ -185,6 +201,14 @@ def verify(l2tpv3): if not l2tpv3['peer_session_id']: raise ConfigError(f'Must configure the l2tpv3 peer-session-id for {interface}') + if ( l2tpv3['is_bridge_member'] + and ( l2tpv3['address'] + or l2tpv3['ipv6_eui64_prefix'] + or l2tpv3['ipv6_autoconf'] ) ): + raise ConfigError(( + f'Cannot assign address to interface "{l2tpv3["intf"]}" ' + f'as it is a member of bridge "{l2tpv3["is_bridge_member"]}"!')) + return None @@ -223,10 +247,10 @@ def apply(l2tpv3): l.set_alias(l2tpv3['description']) # Maximum Transfer Unit (MTU) l.set_mtu(l2tpv3['mtu']) + # IPv6 accept RA + l.set_ipv6_accept_ra(l2tpv3['ipv6_accept_ra']) # 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 @@ -238,12 +262,20 @@ def apply(l2tpv3): for addr in l2tpv3['address']: l.add_addr(addr) + # IPv6 EUI-based addresses + for addr in l2tpv3['ipv6_eui64_prefix']: + l.add_ipv6_eui64_address(addr) + # As the interface is always disabled first when changing parameters # we will only re-enable the interface if it is not administratively # disabled if not l2tpv3['disable']: l.set_admin_state('up') + # re-add ourselves to any bridge we might have fallen out of + if l2tpv3['is_bridge_member']: + l.add_to_bridge(l2tpv3['is_bridge_member']) + return None if __name__ == '__main__': |