diff options
Diffstat (limited to 'src/conf_mode/interfaces-vxlan.py')
-rwxr-xr-x | src/conf_mode/interfaces-vxlan.py | 81 |
1 files changed, 63 insertions, 18 deletions
diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py index efdc21f89..6639a9b0d 100755 --- a/src/conf_mode/interfaces-vxlan.py +++ b/src/conf_mode/interfaces-vxlan.py @@ -18,11 +18,12 @@ import os from sys import exit from copy import deepcopy +from netifaces import interfaces from vyos.config import Config from vyos.ifconfig import VXLANIf, Interface +from vyos.util import is_bridge_member from vyos import ConfigError -from netifaces import interfaces default_config_data = { 'address': [], @@ -37,7 +38,12 @@ default_config_data = { 'ip_enable_arp_announce': 0, 'ip_enable_arp_ignore': 0, 'ip_proxy_arp': 0, - 'link': '', + 'ipv6_autoconf': 0, + 'ipv6_eui64_prefix': '', + 'ipv6_forwarding': 1, + 'ipv6_dup_addr_detect': 1, + 'source_address': '', + 'source_interface': '', 'mtu': 1450, 'remote': '', 'remote_port': 8472, # The Linux implementation of VXLAN pre-dates @@ -50,10 +56,10 @@ def get_config(): conf = Config() # determine tagNode instance - try: - vxlan['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') + + vxlan['intf'] = os.environ['VYOS_TAGNODE_VALUE'] # Check if interface has been removed if not conf.exists('interfaces vxlan ' + vxlan['intf']): @@ -103,9 +109,29 @@ def get_config(): if conf.exists('ip enable-proxy-arp'): vxlan['ip_proxy_arp'] = 1 + # Enable acquisition of IPv6 address using stateless autoconfig (SLAAC) + if conf.exists('ipv6 address autoconf'): + vxlan['ipv6_autoconf'] = 1 + + # Get prefix for IPv6 addressing based on MAC address (EUI-64) + if conf.exists('ipv6 address eui64'): + vxlan['ipv6_eui64_prefix'] = conf.return_value('ipv6 address eui64') + + # Disable IPv6 forwarding on this interface + if conf.exists('ipv6 disable-forwarding'): + vxlan['ipv6_forwarding'] = 0 + + # IPv6 Duplicate Address Detection (DAD) tries + if conf.exists('ipv6 dup-addr-detect-transmits'): + vxlan['ipv6_dup_addr_detect'] = int(conf.return_value('ipv6 dup-addr-detect-transmits')) + + # VXLAN source address + if conf.exists('source-address'): + vxlan['source_address'] = conf.return_value('source-address') + # VXLAN underlay interface - if conf.exists('link'): - vxlan['link'] = conf.return_value('link') + if conf.exists('source-interface'): + vxlan['source_interface'] = conf.return_value('source-interface') # Maximum Transmission Unit (MTU) if conf.exists('mtu'): @@ -128,25 +154,35 @@ def get_config(): def verify(vxlan): if vxlan['deleted']: - # bail out early + interface = vxlan['intf'] + 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 vxlan['mtu'] < 1500: print('WARNING: RFC7348 recommends VXLAN tunnels preserve a 1500 byte MTU') - if vxlan['group'] and not vxlan['link']: - raise ConfigError('Multicast VXLAN requires an underlaying interface ') + if vxlan['group']: + if not vxlan['source_interface']: + raise ConfigError('Multicast VXLAN requires an underlaying interface ') + + if not vxlan['source_interface'] in interfaces(): + raise ConfigError('VXLAN source interface does not exist') - if not (vxlan['group'] or vxlan['remote']): - raise ConfigError('Group or remote must be configured') + if not (vxlan['group'] or vxlan['remote'] or vxlan['source_address']): + raise ConfigError('Group, remote or source-address must be configured') if not vxlan['vni']: raise ConfigError('Must configure VNI for VXLAN') - if vxlan['link']: + if vxlan['source_interface']: # VXLAN adds a 50 byte overhead - we need to check the underlaying MTU # if our configured MTU is at least 50 bytes less - underlay_mtu = int(Interface(vxlan['link']).get_mtu()) + underlay_mtu = int(Interface(vxlan['source_interface']).get_mtu()) if underlay_mtu < (vxlan['mtu'] + 50): raise ConfigError('VXLAN has a 50 byte overhead, underlaying device ' \ 'MTU is to small ({})'.format(underlay_mtu)) @@ -175,12 +211,13 @@ def apply(vxlan): # Assign VXLAN instance configuration parameters to config dict conf['vni'] = vxlan['vni'] conf['group'] = vxlan['group'] - conf['dev'] = vxlan['link'] + conf['src_address'] = vxlan['source_address'] + conf['src_interface'] = vxlan['source_interface'] conf['remote'] = vxlan['remote'] conf['port'] = vxlan['remote_port'] # Finally create the new interface - v = VXLANIf(vxlan['intf'], config=conf) + v = VXLANIf(vxlan['intf'], **conf) # update interface description used e.g. by SNMP v.set_alias(vxlan['description']) # Maximum Transfer Unit (MTU) @@ -198,6 +235,14 @@ def apply(vxlan): v.set_arp_ignore(vxlan['ip_enable_arp_ignore']) # Enable proxy-arp on this interface v.set_proxy_arp(vxlan['ip_proxy_arp']) + # IPv6 address autoconfiguration + v.set_ipv6_autoconf(vxlan['ipv6_autoconf']) + # IPv6 EUI-based address + v.set_ipv6_eui64_address(vxlan['ipv6_eui64_prefix']) + # IPv6 forwarding + v.set_ipv6_forwarding(vxlan['ipv6_forwarding']) + # IPv6 Duplicate Address Detection (DAD) tries + v.set_ipv6_dad_messages(vxlan['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 @@ -209,7 +254,7 @@ def apply(vxlan): # parameters we will only re-enable the interface if it is not # administratively disabled if not vxlan['disable']: - v.set_state('up') + v.set_admin_state('up') return None |