summaryrefslogtreecommitdiff
path: root/src/conf_mode/vrf.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_mode/vrf.py')
-rwxr-xr-xsrc/conf_mode/vrf.py58
1 files changed, 42 insertions, 16 deletions
diff --git a/src/conf_mode/vrf.py b/src/conf_mode/vrf.py
index 936561edc..c1cfc1dcb 100755
--- a/src/conf_mode/vrf.py
+++ b/src/conf_mode/vrf.py
@@ -18,6 +18,7 @@ import os
from sys import exit
from json import loads
+from tempfile import NamedTemporaryFile
from vyos.config import Config
from vyos.configdict import node_changed
@@ -28,6 +29,8 @@ from vyos.util import call
from vyos.util import cmd
from vyos.util import dict_search
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
@@ -125,11 +128,17 @@ def verify(vrf):
return None
+
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)
+
return None
+
def apply(vrf):
# Documentation
#
@@ -151,8 +160,19 @@ def apply(vrf):
call(f'ip -4 route del vrf {tmp} unreachable default metric 4278198272')
call(f'ip -6 route del vrf {tmp} unreachable default metric 4278198272')
call(f'ip link delete dev {tmp}')
+ # Remove nftables conntrack zone map item
+ nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{tmp}" }}'
+ cmd(f'nft {nft_del_element}')
if 'name' in vrf:
+ # Separate VRFs in conntrack table
+ # check if table already exists
+ _, err = popen('nft list table inet vrf_zones')
+ # If not, create a table
+ if err:
+ cmd(f'nft -f {vrf["nft_vrf_zones"]}')
+ os.unlink(vrf['nft_vrf_zones'])
+
for name, config in vrf['name'].items():
table = config['table']
@@ -182,6 +202,9 @@ def apply(vrf):
# reconfiguration.
state = 'down' if 'disable' in config else 'up'
vrf_if.set_admin_state(state)
+ # Add nftables conntrack zone map item
+ nft_add_element = f'add element inet vrf_zones ct_iface_map {{ "{name}" : {table} }}'
+ cmd(f'nft {nft_add_element}')
# Linux routing uses rules to find tables - routing targets are then
# looked up in those tables. If the lookup got a matching route, the
@@ -214,22 +237,25 @@ def apply(vrf):
# clean out l3mdev-table rule if present
if 1000 in [r.get('priority') for r in list_rules() if r.get('priority') == 1000]:
call(f'ip {af} rule del pref 1000')
-
- # 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)
-
- # If FRR config is blank, rerun the blank commit x times due to frr-reload
- # behavior/bug not properly clearing out on one commit.
- if vrf['new_frr_config'] == '':
- for a in range(5):
- frr_cfg.commit_configuration(frr_daemon)
-
- # Save configuration to /run/frr/config/frr.conf
- frr.save_configuration()
+ # Remove VRF zones table from nftables
+ tmp = run('nft list table inet vrf_zones')
+ 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