summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-04-09 22:16:54 +0200
committerChristian Poessinger <christian@poessinger.com>2020-04-09 22:16:54 +0200
commit235ccf39efc58fd07a3504dc0add379ba0c5a98a (patch)
treea184cc5e4bb0540d962c8cecb33673d121c5472a
parent5212c3626a715d9af54cea1e236169fdfcee0a60 (diff)
downloadvyos-1x-235ccf39efc58fd07a3504dc0add379ba0c5a98a.tar.gz
vyos-1x-235ccf39efc58fd07a3504dc0add379ba0c5a98a.zip
vxlan: T2172: add source-address option
This is a base requirement for l2vpn evpn. When source-address is configured, the option "local <source-addr> nolearning" is appended when creating the interface as mentioned here: https://vincent.bernat.ch/en/blog/2017-vxlan-bgp-evpn
-rw-r--r--interface-definitions/interfaces-vxlan.xml.in12
-rw-r--r--python/vyos/ifconfig/vxlan.py25
-rwxr-xr-xsrc/conf_mode/interfaces-vxlan.py12
3 files changed, 37 insertions, 12 deletions
diff --git a/interface-definitions/interfaces-vxlan.xml.in b/interface-definitions/interfaces-vxlan.xml.in
index 5dcaf065c..fdde57525 100644
--- a/interface-definitions/interfaces-vxlan.xml.in
+++ b/interface-definitions/interfaces-vxlan.xml.in
@@ -52,6 +52,18 @@
#include <include/ipv6-dup-addr-detect-transmits.xml.i>
</children>
</node>
+ <leafNode name="source-address">
+ <properties>
+ <help>VXLAN source address</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 source-address of VXLAN tunnel</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="source-interface">
<properties>
<help>Physical Interface used for this connection</help>
diff --git a/python/vyos/ifconfig/vxlan.py b/python/vyos/ifconfig/vxlan.py
index 5678ad62e..f47ae17cc 100644
--- a/python/vyos/ifconfig/vxlan.py
+++ b/python/vyos/ifconfig/vxlan.py
@@ -43,12 +43,13 @@ class VXLANIf(Interface):
default = {
'type': 'vxlan',
- 'vni': 0,
- 'dev': '',
'group': '',
- 'remote': '',
'port': 8472, # The Linux implementation of VXLAN pre-dates
# the IANA's selection of a standard destination port
+ 'remote': '',
+ 'src_address': '',
+ 'src_interface': '',
+ 'vni': 0
}
definition = {
**Interface.definition,
@@ -58,24 +59,30 @@ class VXLANIf(Interface):
'bridgeable': True,
}
}
- options = ['group', 'remote', 'dev', 'port', 'vni']
+ options = ['group', 'remote', 'src_interface', 'port', 'vni', 'src_address']
mapping = {
'ifname': 'add',
'vni': 'id',
'port': 'dstport',
+ 'src_address': 'nolearning local',
}
def _create(self):
cmdline = set()
if self.config['remote']:
- cmdline = ('ifname', 'type', 'remote', 'dev', 'vni', 'port')
- elif self.config['group'] and self.config['dev']:
- cmdline = ('ifname', 'type', 'group', 'dev', 'vni', 'port')
+ cmdline = ('ifname', 'type', 'remote', 'src_interface', 'vni', 'port')
+
+ elif self.config['src_address']:
+ cmdline = ('ifname', 'type', 'src_address', 'vni', 'port')
+
+ elif self.config['group'] and self.config['src_interface']:
+ cmdline = ('ifname', 'type', 'group', 'src_interface', 'vni', 'port')
+
else:
- intf = self.config['intf']
+ ifname = self.config['ifname']
raise ConfigError(
- f'VXLAN "{intf}" is missing mandatory underlay interface for a multicast network.')
+ f'VXLAN "{ifname}" is missing mandatory underlay interface for a multicast network.')
cmd = 'ip link'
for key in cmdline:
diff --git a/src/conf_mode/interfaces-vxlan.py b/src/conf_mode/interfaces-vxlan.py
index ba0f9a61a..6639a9b0d 100755
--- a/src/conf_mode/interfaces-vxlan.py
+++ b/src/conf_mode/interfaces-vxlan.py
@@ -42,6 +42,7 @@ default_config_data = {
'ipv6_eui64_prefix': '',
'ipv6_forwarding': 1,
'ipv6_dup_addr_detect': 1,
+ 'source_address': '',
'source_interface': '',
'mtu': 1450,
'remote': '',
@@ -124,6 +125,10 @@ def get_config():
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('source-interface'):
vxlan['source_interface'] = conf.return_value('source-interface')
@@ -168,8 +173,8 @@ def verify(vxlan):
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')
@@ -206,7 +211,8 @@ def apply(vxlan):
# Assign VXLAN instance configuration parameters to config dict
conf['vni'] = vxlan['vni']
conf['group'] = vxlan['group']
- conf['dev'] = vxlan['source_interface']
+ conf['src_address'] = vxlan['source_address']
+ conf['src_interface'] = vxlan['source_interface']
conf['remote'] = vxlan['remote']
conf['port'] = vxlan['remote_port']