summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorAndrew Topp <atopp@aus-it.com.au>2024-07-30 13:48:18 +1000
committerAndrew Topp <atopp@aus-it.com.au>2024-07-30 13:48:18 +1000
commitadeac78ed6585b16102bd82581b54c75819714b2 (patch)
tree7111af3bb9bb6047db620f09d64fb261933efe72 /python
parentad0acad65051a449432f882edb60246cdfeeb8e5 (diff)
downloadvyos-1x-adeac78ed6585b16102bd82581b54c75819714b2.tar.gz
vyos-1x-adeac78ed6585b16102bd82581b54c75819714b2.zip
pbr: T6430: Allow forwarding into VRFs by name as well as route table IDs
* PBR can only target table IDs up to 200 and the previous PR to extend the range was rejected * PBR with this PR can now also target VRFs directly by name, working around targeting problems for VRF table IDs outside the overlapping 100-200 range * Validation ensures rules can't target both a table ID and a VRF name (internally they are handled the same) * Added a simple accessor (get_vrf_table_id) for runtime mapping a VRF name to table ID, based on vyos.ifconfig.interface._set_vrf_ct_zone(). It does not replace that usage, as it deliberately does not handle non-VRF interface lookups (would fail with a KeyError). * Added route table ID lookup dict, global route table and VRF table defs to vyos.defaults. Table ID references have been updated in code touched by this PR. * Added a simple smoketest to validate 'set vrf' usage in PBR rules
Diffstat (limited to 'python')
-rw-r--r--python/vyos/defaults.py10
-rw-r--r--python/vyos/firewall.py14
-rw-r--r--python/vyos/utils/network.py3
3 files changed, 26 insertions, 1 deletions
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index 9ccd925ce..25ee45391 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -50,3 +50,13 @@ commit_lock = os.path.join(directories['vyos_configdir'], '.lock')
component_version_json = os.path.join(directories['data'], 'component-versions.json')
config_default = os.path.join(directories['data'], 'config.boot.default')
+
+rt_symbolic_names = {
+ # Standard routing tables for Linux & reserved IDs for VyOS
+ 'default': 253, # Confusingly, a final fallthru, not the default.
+ 'main': 254, # The actual global table used by iproute2 unless told otherwise.
+ 'local': 255, # Special kernel loopback table.
+}
+
+rt_global_vrf = rt_symbolic_names['main']
+rt_global_table = rt_symbolic_names['main']
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 40399f481..89cd68183 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -30,6 +30,9 @@ from vyos.utils.dict import dict_search_args
from vyos.utils.dict import dict_search_recursive
from vyos.utils.process import cmd
from vyos.utils.process import run
+from vyos.utils.network import get_vrf_table_id
+from vyos.defaults import rt_global_table
+from vyos.defaults import rt_global_vrf
# Conntrack
def conntrack_required(conf):
@@ -473,11 +476,20 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
if 'mark' in rule_conf['set']:
mark = rule_conf['set']['mark']
output.append(f'meta mark set {mark}')
+ if 'vrf' in rule_conf['set']:
+ set_table = True
+ vrf_name = rule_conf['set']['vrf']
+ if vrf_name == 'default':
+ table = rt_global_vrf
+ else:
+ # NOTE: VRF->table ID lookup depends on the VRF iface already existing.
+ table = get_vrf_table_id(vrf_name)
if 'table' in rule_conf['set']:
set_table = True
table = rule_conf['set']['table']
if table == 'main':
- table = '254'
+ table = rt_global_table
+ if set_table:
mark = 0x7FFFFFFF - int(table)
output.append(f'meta mark set {mark}')
if 'tcp_mss' in rule_conf['set']:
diff --git a/python/vyos/utils/network.py b/python/vyos/utils/network.py
index 8fce08de0..d297a1ddb 100644
--- a/python/vyos/utils/network.py
+++ b/python/vyos/utils/network.py
@@ -74,6 +74,9 @@ def get_vrf_members(vrf: str) -> list:
pass
return interfaces
+def get_vrf_table_id(vrf: str):
+ return get_interface_config(vrf)['linkinfo']['info_data']['table']
+
def get_interface_vrf(interface):
""" Returns VRF of given interface """
from vyos.utils.dict import dict_search