summaryrefslogtreecommitdiff
path: root/python/vyos/utils
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2024-07-20 10:35:44 +0200
committerChristian Breunig <christian@breunig.cc>2024-07-20 11:46:28 +0200
commit452068ce78581bb6fba2df4dba197e95b9aeb33d (patch)
treed6446320a87996d1b2cd1a54e92a162f960b5c20 /python/vyos/utils
parent35644bc5a166c86596272c8b020679aa92034a9f (diff)
downloadvyos-1x-452068ce78581bb6fba2df4dba197e95b9aeb33d.tar.gz
vyos-1x-452068ce78581bb6fba2df4dba197e95b9aeb33d.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.
Diffstat (limited to 'python/vyos/utils')
-rw-r--r--python/vyos/utils/network.py23
1 files changed, 18 insertions, 5 deletions
diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py
index 829124b57..8406a5638 100644
--- a/python/vyos/utils/network.py
+++ b/python/vyos/utils/network.py
@@ -83,6 +83,19 @@ def get_interface_vrf(interface):
return tmp['master']
return 'default'
+def get_vrf_tableid(interface: str):
+ """ Return VRF table ID for given interface name or None """
+ from vyos.utils.dict import dict_search
+ table = None
+ tmp = get_interface_config(interface)
+ # Check if we are "the" VRF interface
+ if dict_search('linkinfo.info_kind', tmp) == 'vrf':
+ table = tmp['linkinfo']['info_data']['table']
+ # or an interface bound to a VRF
+ elif dict_search('linkinfo.info_slave_kind', tmp) == 'vrf':
+ table = tmp['linkinfo']['info_slave_data']['table']
+ return table
+
def get_interface_config(interface):
""" Returns the used encapsulation protocol for given interface.
If interface does not exist, None is returned.
@@ -537,21 +550,21 @@ def ipv6_prefix_length(low, high):
return None
xor = bytearray(a ^ b for a, b in zip(lo, hi))
-
+
plen = 0
while plen < 128 and xor[plen // 8] == 0:
plen += 8
-
+
if plen == 128:
return plen
-
+
for i in range((plen // 8) + 1, 16):
if xor[i] != 0:
return None
-
+
for i in range(8):
msk = ~xor[plen // 8] & 0xff
-
+
if msk == bytemasks[i]:
return plen + i + 1