summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2021-08-13 21:11:58 +0200
committerChristian Poessinger <christian@poessinger.com>2021-08-13 21:33:09 +0200
commitda94e0a736874d9a6420ec1aa754efcec684b390 (patch)
treed06d7939a2fa58b84e65b4b856f6180bccdf2452
parent595ab70a5d50ef1f9e166959affd96ea1ee8c8c8 (diff)
downloadvyos-1x-da94e0a736874d9a6420ec1aa754efcec684b390.tar.gz
vyos-1x-da94e0a736874d9a6420ec1aa754efcec684b390.zip
vrf: T3734: T3728: vni must be configured with a higher priority then bgpd
When removing bgp (vrf) instances the assigned VRF vni must be deleted from FRR prior the removal of the bgp settings (T3734). This is now done by moving the CLI command "set vrf name red vni 1000" to a dedicated Python script with a priority higher then bgp.
-rw-r--r--data/configd-include.json1
-rw-r--r--data/templates/frr/vrf-vni.frr.tmpl7
-rw-r--r--data/templates/frr/vrf.frr.tmpl9
-rw-r--r--interface-definitions/vrf.xml.in15
-rwxr-xr-xsrc/conf_mode/vrf.py20
-rwxr-xr-xsrc/conf_mode/vrf_vni.py76
6 files changed, 98 insertions, 30 deletions
diff --git a/data/configd-include.json b/data/configd-include.json
index 3b4e2925b..2d7ea149b 100644
--- a/data/configd-include.json
+++ b/data/configd-include.json
@@ -69,5 +69,6 @@
"vpn_pptp.py",
"vpn_sstp.py",
"vrf.py",
+"vrf_vni.py",
"vrrp.py"
]
diff --git a/data/templates/frr/vrf-vni.frr.tmpl b/data/templates/frr/vrf-vni.frr.tmpl
new file mode 100644
index 000000000..51d4ede1b
--- /dev/null
+++ b/data/templates/frr/vrf-vni.frr.tmpl
@@ -0,0 +1,7 @@
+{% if vrf is defined and vrf is not none %}
+vrf {{ vrf }}
+{% if vni is defined and vni is not none %}
+ vni {{ vni }}
+{% endif %}
+ exit-vrf
+{% endif %}
diff --git a/data/templates/frr/vrf.frr.tmpl b/data/templates/frr/vrf.frr.tmpl
deleted file mode 100644
index 299c9719e..000000000
--- a/data/templates/frr/vrf.frr.tmpl
+++ /dev/null
@@ -1,9 +0,0 @@
-{% if name is defined and name is not none %}
-{% for vrf, vrf_config in name.items() %}
-vrf {{ vrf }}
-{% if vrf_config.vni is defined and vrf_config.vni is not none %}
- vni {{ vrf_config.vni }}
-{% endif %}
- exit-vrf
-{% endfor %}
-{% endif %}
diff --git a/interface-definitions/vrf.xml.in b/interface-definitions/vrf.xml.in
index 9d513945c..76d6df386 100644
--- a/interface-definitions/vrf.xml.in
+++ b/interface-definitions/vrf.xml.in
@@ -85,7 +85,20 @@
<constraintErrorMessage>VRF routing table must be in range from 100 to 65535</constraintErrorMessage>
</properties>
</leafNode>
- #include <include/vni.xml.i>
+ <leafNode name="vni" owner="${vyos_conf_scripts_dir}/vrf_vni.py $VAR(../@)">
+ <properties>
+ <help>Virtual Network Identifier</help>
+ <!-- priority must be after BGP -->
+ <priority>822</priority>
+ <valueHelp>
+ <format>0-16777214</format>
+ <description>VXLAN virtual network identifier</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-16777214"/>
+ </constraint>
+ </properties>
+ </leafNode>
</children>
</tagNode>
</children>
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index c1cfc1dcb..919083ac4 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -24,7 +24,6 @@ from vyos.config import Config
from vyos.configdict import node_changed
from vyos.ifconfig import Interface
from vyos.template import render
-from vyos.template import render_to_string
from vyos.util import call
from vyos.util import cmd
from vyos.util import dict_search
@@ -32,12 +31,9 @@ from vyos.util import get_interface_config
from vyos.util import popen
from vyos.util import run
from vyos import ConfigError
-from vyos import frr
from vyos import airbag
airbag.enable()
-frr_daemon = 'zebra'
-
config_file = r'/etc/iproute2/rt_tables.d/vyos-vrf.conf'
def list_rules():
@@ -131,7 +127,6 @@ def verify(vrf):
def generate(vrf):
render(config_file, 'vrf/vrf.conf.tmpl', vrf)
- vrf['new_frr_config'] = render_to_string('frr/vrf.frr.tmpl', vrf)
# Render nftables zones config
vrf['nft_vrf_zones'] = NamedTemporaryFile().name
render(vrf['nft_vrf_zones'], 'firewall/nftables-vrf-zones.tmpl', vrf)
@@ -242,21 +237,6 @@ def apply(vrf):
if tmp == 0:
cmd('nft delete table inet vrf_zones')
- # T3694: Somehow we hit a priority inversion here as we need to remove the
- # VRF assigned VNI before we can remove a BGP bound VRF instance. Maybe
- # move this to an individual helper script that set's up the VNI for the
- # given VRF after any routing protocol.
- #
- # # add configuration to FRR
- # frr_cfg = frr.FRRConfig()
- # frr_cfg.load_configuration(frr_daemon)
- # frr_cfg.modify_section(f'^vrf [a-zA-Z-]*$', '')
- # frr_cfg.add_before(r'(interface .*|line vty)', vrf['new_frr_config'])
- # frr_cfg.commit_configuration(frr_daemon)
- #
- # # Save configuration to /run/frr/config/frr.conf
- # frr.save_configuration()
-
return None
if __name__ == '__main__':
diff --git a/src/conf_mode/vrf_vni.py b/src/conf_mode/vrf_vni.py
new file mode 100755
index 000000000..87ee8f2d1
--- /dev/null
+++ b/src/conf_mode/vrf_vni.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020-2021 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
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+from sys import argv
+from sys import exit
+
+from vyos.config import Config
+from vyos.template import render_to_string
+from vyos import ConfigError
+from vyos import frr
+from vyos import airbag
+airbag.enable()
+
+frr_daemon = 'zebra'
+
+def get_config(config=None):
+ if config:
+ conf = config
+ else:
+ conf = Config()
+
+ # This script only works with a passed VRF name
+ if len(argv) < 1:
+ raise NotImplementedError
+ vrf = argv[1]
+
+ # "assemble" dict - easier here then use a full blown get_config_dict()
+ # on a single leafNode
+ vni = { 'vrf' : vrf }
+ tmp = conf.return_value(['vrf', 'name', vrf, 'vni'])
+ if tmp: vni.update({ 'vni' : tmp })
+
+ return vni
+
+def verify(vni):
+ return None
+
+def generate(vni):
+ vni['new_frr_config'] = render_to_string('frr/vrf-vni.frr.tmpl', vni)
+ return None
+
+def apply(vni):
+ # add configuration to FRR
+ frr_cfg = frr.FRRConfig()
+ frr_cfg.load_configuration(frr_daemon)
+ frr_cfg.modify_section(f'^vrf [a-zA-Z-]*$', '')
+ frr_cfg.add_before(r'(interface .*|line vty)', vni['new_frr_config'])
+ frr_cfg.commit_configuration(frr_daemon)
+
+ # Save configuration to /run/frr/config/frr.conf
+ frr.save_configuration()
+
+ return None
+
+if __name__ == '__main__':
+ try:
+ c = get_config()
+ verify(c)
+ generate(c)
+ apply(c)
+ except ConfigError as e:
+ print(e)
+ exit(1)