diff options
author | Andrew Topp <andrewt@telekinetica.net> | 2025-06-27 00:23:13 +1000 |
---|---|---|
committer | Andrew Topp <andrewt@telekinetica.net> | 2025-06-27 00:23:13 +1000 |
commit | c741a290261eb53d5f9ca4849109f19ced8fda9f (patch) | |
tree | ba9d8a5d034e91006630c79dd737864eb3ccef90 /python | |
parent | 5c2f70ffd82047740a91be949af5098a6ee39c2c (diff) | |
download | vyos-1x-c741a290261eb53d5f9ca4849109f19ced8fda9f.tar.gz vyos-1x-c741a290261eb53d5f9ca4849109f19ced8fda9f.zip |
vrf: T7544: Ensure correct quoting for VRF ifnames in nftables
* For VRF create/delete:
* Simple dquoting, as before, was parsed away by the shell
* Just escaping the double quotes could cause issues with the shell mangling
VRF names (however unlikely)
* Wrapping original quotes in shell-escaped single quotes is a quick & easy
way to guard against both improper shell parsing and string names being
taken as nft keywords.
* Firewall configuration:
* Firewall "interface name" rules support VRF ifnames and used them unquoted,
fixed for nft_rule template tags (parse_rule)
* Went through and quoted all iif/oifname usage by zones and interface
groups. VRF ifnames weren't available for all cases, but there is
no harm in completeness.
* For this, also created a simple quoted_join template filter to replace
any use of |join(',')
* PBR calls nft but doesn't mind the "vni" name - table IDs used instead
I may have missed some niche nft use-cases that would be exposed to this problem.
Diffstat (limited to 'python')
-rwxr-xr-x | python/vyos/firewall.py | 4 | ||||
-rw-r--r-- | python/vyos/ifconfig/interface.py | 4 | ||||
-rwxr-xr-x | python/vyos/template.py | 4 |
3 files changed, 8 insertions, 4 deletions
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py index 64022db84..0643107a9 100755 --- a/python/vyos/firewall.py +++ b/python/vyos/firewall.py @@ -361,7 +361,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): if iiface[0] == '!': operator = '!=' iiface = iiface[1:] - output.append(f'iifname {operator} {{{iiface}}}') + output.append(f'iifname {operator} {{"{iiface}"}}') elif 'group' in rule_conf['inbound_interface']: iiface = rule_conf['inbound_interface']['group'] if iiface[0] == '!': @@ -376,7 +376,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name): if oiface[0] == '!': operator = '!=' oiface = oiface[1:] - output.append(f'oifname {operator} {{{oiface}}}') + output.append(f'oifname {operator} {{"{oiface}"}}') elif 'group' in rule_conf['outbound_interface']: oiface = rule_conf['outbound_interface']['group'] if oiface[0] == '!': diff --git a/python/vyos/ifconfig/interface.py b/python/vyos/ifconfig/interface.py index 91b3a0c28..33c6830bc 100644 --- a/python/vyos/ifconfig/interface.py +++ b/python/vyos/ifconfig/interface.py @@ -423,11 +423,11 @@ class Interface(Control): self._cmd(f'nft {nft_command}') def _del_interface_from_ct_iface_map(self): - nft_command = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}' + nft_command = f'delete element inet vrf_zones ct_iface_map {{ \'"{self.ifname}"\' }}' self._nft_check_and_run(nft_command) def _add_interface_to_ct_iface_map(self, vrf_table_id: int): - nft_command = f'add element inet vrf_zones ct_iface_map {{ "{self.ifname}" : {vrf_table_id} }}' + nft_command = f'add element inet vrf_zones ct_iface_map {{ \'"{self.ifname}"\' : {vrf_table_id} }}' self._nft_check_and_run(nft_command) def get_ifindex(self): diff --git a/python/vyos/template.py b/python/vyos/template.py index bf2f13183..c6e35e9c7 100755 --- a/python/vyos/template.py +++ b/python/vyos/template.py @@ -582,6 +582,10 @@ def snmp_auth_oid(type): } return OIDs[type] +@register_filter('quoted_join') +def quoted_join(input_list, join_str, quote='"'): + return str(join_str).join(f'{quote}{elem}{quote}' for elem in input_list) + @register_filter('nft_action') def nft_action(vyos_action): if vyos_action == 'accept': |