Skip to content

Commit 862817a

Browse files
authored
Merge pull request #4581 from talmakion/bugfix/T7544/escape-vrfif-nftables
vrf: T7544: Ensure correct quoting for VRF ifnames in nftables
2 parents 22c6a81 + c741a29 commit 862817a

File tree

6 files changed

+29
-25
lines changed

6 files changed

+29
-25
lines changed

data/templates/firewall/nftables-defines.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
flags interval
112112
auto-merge
113113
{% if group_conf.interface is vyos_defined or includes %}
114-
elements = { {{ group_conf.interface | nft_nested_group(includes, group.interface_group, 'interface') | join(",") }} }
114+
elements = { {{ group_conf.interface | nft_nested_group(includes, group.interface_group, 'interface') | quoted_join(",") }} }
115115
{% endif %}
116116
}
117117
{% endfor %}

data/templates/firewall/nftables-zone.j2

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
{% for zone_name, zone_conf in zone.items() %}
1010
{% if 'local_zone' not in zone_conf %}
1111
{% if 'interface' in zone_conf.member %}
12-
oifname { {{ zone_conf.member.interface | join(',') }} } counter jump VZONE_{{ zone_name }}
12+
oifname { {{ zone_conf.member.interface | quoted_join(',') }} } counter jump VZONE_{{ zone_name }}
1313
{% endif %}
1414
{% if 'vrf' in zone_conf.member %}
1515
{% for vrf_name in zone_conf.member.vrf %}
16-
oifname { {{ zone_conf['vrf_interfaces'][vrf_name] }} } counter jump VZONE_{{ zone_name }}
16+
oifname { "{{ zone_conf['vrf_interfaces'][vrf_name] }}" } counter jump VZONE_{{ zone_name }}
1717
{% endfor %}
1818
{% endif %}
1919
{% endif %}
@@ -49,12 +49,12 @@
4949
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %}
5050

5151
{% if 'interface' in zone[from_zone].member %}
52-
iifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
53-
iifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
52+
iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
53+
iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
5454
{% endif %}
5555
{% if 'vrf' in zone[from_zone].member %}
56-
iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
57-
iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter return
56+
iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
57+
iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return
5858
{% endif %}
5959
{% endfor %}
6060
{% endif %}
@@ -65,13 +65,13 @@
6565
{% if zone_conf.from_local is vyos_defined %}
6666
{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall[fw_name] is vyos_defined %}
6767
{% if 'interface' in zone[from_zone].member %}
68-
oifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
69-
oifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
68+
oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
69+
oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
7070
{% endif %}
7171
{% if 'vrf' in zone[from_zone].member %}
7272
{% for vrf_name in zone[from_zone].member.vrf %}
73-
oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
74-
oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] }} } counter return
73+
oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
74+
oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter return
7575
{% endfor %}
7676
{% endif %}
7777
{% endfor %}
@@ -81,29 +81,29 @@
8181
{% else %}
8282
chain VZONE_{{ zone_name }} {
8383
{% if 'interface' in zone_conf.member %}
84-
iifname { {{ zone_conf.member.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
84+
iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
8585
{% endif %}
8686
{% if 'vrf' in zone_conf.member %}
87-
iifname { {{ zone_conf.member.vrf | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
87+
iifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
8888
{% endif %}
8989
{% if zone_conf.intra_zone_filtering is vyos_defined %}
9090
{% if 'interface' in zone_conf.member %}
91-
iifname { {{ zone_conf.member.interface | join(",") }} } counter return
91+
iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter return
9292
{% endif %}
9393
{% if 'vrf' in zone_conf.member %}
94-
iifname { {{ zone_conf.member.vrf | join(",") }} } counter return
94+
iifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter return
9595
{% endif %}
9696
{% endif %}
9797
{% if zone_conf.from is vyos_defined %}
9898
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %}
9999
{% if zone[from_zone].local_zone is not defined %}
100100
{% if 'interface' in zone[from_zone].member %}
101-
iifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
102-
iifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
101+
iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
102+
iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
103103
{% endif %}
104104
{% if 'vrf' in zone[from_zone].member %}
105-
iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
106-
iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter return
105+
iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
106+
iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return
107107
{% endif %}
108108
{% endif %}
109109
{% endfor %}

python/vyos/firewall.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
361361
if iiface[0] == '!':
362362
operator = '!='
363363
iiface = iiface[1:]
364-
output.append(f'iifname {operator} {{{iiface}}}')
364+
output.append(f'iifname {operator} {{"{iiface}"}}')
365365
elif 'group' in rule_conf['inbound_interface']:
366366
iiface = rule_conf['inbound_interface']['group']
367367
if iiface[0] == '!':
@@ -376,7 +376,7 @@ def parse_rule(rule_conf, hook, fw_name, rule_id, ip_name):
376376
if oiface[0] == '!':
377377
operator = '!='
378378
oiface = oiface[1:]
379-
output.append(f'oifname {operator} {{{oiface}}}')
379+
output.append(f'oifname {operator} {{"{oiface}"}}')
380380
elif 'group' in rule_conf['outbound_interface']:
381381
oiface = rule_conf['outbound_interface']['group']
382382
if oiface[0] == '!':

python/vyos/ifconfig/interface.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,11 +423,11 @@ def _nft_check_and_run(self, nft_command):
423423
self._cmd(f'nft {nft_command}')
424424

425425
def _del_interface_from_ct_iface_map(self):
426-
nft_command = f'delete element inet vrf_zones ct_iface_map {{ "{self.ifname}" }}'
426+
nft_command = f'delete element inet vrf_zones ct_iface_map {{ \'"{self.ifname}"\' }}'
427427
self._nft_check_and_run(nft_command)
428428

429429
def _add_interface_to_ct_iface_map(self, vrf_table_id: int):
430-
nft_command = f'add element inet vrf_zones ct_iface_map {{ "{self.ifname}" : {vrf_table_id} }}'
430+
nft_command = f'add element inet vrf_zones ct_iface_map {{ \'"{self.ifname}"\' : {vrf_table_id} }}'
431431
self._nft_check_and_run(nft_command)
432432

433433
def get_ifindex(self):

python/vyos/template.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,10 @@ def snmp_auth_oid(type):
582582
}
583583
return OIDs[type]
584584

585+
@register_filter('quoted_join')
586+
def quoted_join(input_list, join_str, quote='"'):
587+
return str(join_str).join(f'{quote}{elem}{quote}' for elem in input_list)
588+
585589
@register_filter('nft_action')
586590
def nft_action(vyos_action):
587591
if vyos_action == 'accept':

src/conf_mode/vrf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def apply(vrf):
240240
vrf_iface.set_dhcpv6(False)
241241

242242
# Remove nftables conntrack zone map item
243-
nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ "{tmp}" }}'
243+
nft_del_element = f'delete element inet vrf_zones ct_iface_map {{ \'"{tmp}"\' }}'
244244
# Check if deleting is possible first to avoid raising errors
245245
_, err = popen(f'nft --check {nft_del_element}')
246246
if not err:
@@ -320,7 +320,7 @@ def apply(vrf):
320320
state = 'down' if 'disable' in config else 'up'
321321
vrf_if.set_admin_state(state)
322322
# Add nftables conntrack zone map item
323-
nft_add_element = f'add element inet vrf_zones ct_iface_map {{ "{name}" : {table} }}'
323+
nft_add_element = f'add element inet vrf_zones ct_iface_map {{ \'"{name}"\' : {table} }}'
324324
cmd(f'nft {nft_add_element}')
325325

326326
# Only call into nftables as long as there is nothing setup to avoid wasting

0 commit comments

Comments
 (0)