summaryrefslogtreecommitdiff
path: root/python/vyos/ifconfig
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2024-07-20 10:35:44 +0200
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2024-07-20 14:21:20 +0000
commit1b3350788ceeace52e2d693a18d92d82464220c0 (patch)
treee090909afd56a9a2e55b37d57dafc563fede1146 /python/vyos/ifconfig
parent5be256235052592dab254f55f5f329feb5e955b0 (diff)
downloadvyos-1x-1b3350788ceeace52e2d693a18d92d82464220c0.tar.gz
vyos-1x-1b3350788ceeace52e2d693a18d92d82464220c0.zip
interfaces: T6592: moving an interface between VRF instances failed
To reproduce: set vrf name mgmt table '150' set vrf name no-mgmt table '151' set interfaces ethernet eth2 vrf 'mgmt' commit set interfaces ethernet eth2 vrf no-mgmt commit This resulted in an error while interacting with nftables: [Errno 1] failed to run command: nft add element inet vrf_zones ct_iface_map { "eth2" : 151 } The reason is that the old mapping entry still exists and was not removed. This commit adds a new utility function get_vrf_tableid() and compares the current and new VRF table IDs assigned to an interface. If the IDs do not match, the nftables ct_iface_map entry is removed before the new entry is added. (cherry picked from commit 452068ce78581bb6fba2df4dba197e95b9aeb33d)
Diffstat (limited to 'python/vyos/ifconfig')
-rw-r--r--python/vyos/ifconfig/interface.py28
1 files changed, 19 insertions, 9 deletions
diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py
index 117479ade..748830004 100644
--- a/python/vyos/ifconfig/interface.py
+++ b/python/vyos/ifconfig/interface.py
@@ -37,6 +37,7 @@ from vyos.utils.network import mac2eui64
from vyos.utils.dict import dict_search
from vyos.utils.network import get_interface_config
from vyos.utils.network import get_interface_namespace
+from vyos.utils.network import get_vrf_tableid
from vyos.utils.network import is_netns_interface
from vyos.utils.process import is_systemd_service_active
from vyos.utils.process import run
@@ -402,7 +403,7 @@ class Interface(Control):
if netns: cmd = f'ip netns exec {netns} {cmd}'
return self._cmd(cmd)
- def _set_vrf_ct_zone(self, vrf):
+ def _set_vrf_ct_zone(self, vrf, old_vrf_tableid=None):
"""
Add/Remove rules in nftables to associate traffic in VRF to an
individual conntack zone
@@ -411,20 +412,27 @@ class Interface(Control):
if 'netns' in self.config:
return None
+ def nft_check_and_run(nft_command):
+ # Check if deleting is possible first to avoid raising errors
+ _, err = self._popen(f'nft --check {nft_command}')
+ if not err:
+ # Remove map element
+ self._cmd(f'nft {nft_command}')
+
if vrf:
# Get routing table ID for VRF
- vrf_table_id = get_interface_config(vrf).get('linkinfo', {}).get(
- 'info_data', {}).get('table')
+ vrf_table_id = get_vrf_tableid(vrf)
# Add map element with interface and zone ID
if vrf_table_id:
+ # delete old table ID from nftables if it has changed, e.g. interface moved to a different VRF
+ if old_vrf_tableid and old_vrf_tableid != int(vrf_table_id):
+ nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}'
+ nft_check_and_run(nft_del_element)
+
self._cmd(f'nft add element inet vrf_zones ct_iface_map {{ "{self.ifname}" : {vrf_table_id} }}')
else:
nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}'
- # Check if deleting is possible first to avoid raising errors
- _, err = self._popen(f'nft --check {nft_del_element}')
- if not err:
- # Remove map element
- self._cmd(f'nft {nft_del_element}')
+ nft_check_and_run(nft_del_element)
def get_min_mtu(self):
"""
@@ -601,8 +609,10 @@ class Interface(Control):
if tmp == vrf:
return False
+ # Get current VRF table ID
+ old_vrf_tableid = get_vrf_tableid(self.ifname)
self.set_interface('vrf', vrf)
- self._set_vrf_ct_zone(vrf)
+ self._set_vrf_ct_zone(vrf, old_vrf_tableid)
return True
def set_arp_cache_tmo(self, tmo):