Skip to content

Commit f478ad1

Browse files
committed
firewall: T8761: Reintroduce VRF-interface names in generated firewall config, aswell as dependents
1 parent 6fa4967 commit f478ad1

22 files changed

Lines changed: 247 additions & 40 deletions

data/config-mode-dependencies/vyos-1x.json

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,72 @@
99
},
1010
"interfaces_bonding": {
1111
"ethernet": ["interfaces_ethernet"],
12-
"static_arp": ["protocols_static_arp"]
12+
"static_arp": ["protocols_static_arp"],
13+
"firewall": ["firewall"]
1314
},
1415
"interfaces_bridge": {
1516
"vxlan": ["interfaces_vxlan"],
1617
"wlan": ["interfaces_wireless"],
17-
"static_arp": ["protocols_static_arp"]
18+
"static_arp": ["protocols_static_arp"],
19+
"firewall": ["firewall"]
20+
},
21+
"interfaces_dummy": {
22+
"firewall": ["firewall"]
1823
},
1924
"interfaces_ethernet": {
20-
"static_arp": ["protocols_static_arp"]
25+
"static_arp": ["protocols_static_arp"],
26+
"firewall": ["firewall"]
2127
},
2228
"interfaces_geneve": {
23-
"static_arp": ["protocols_static_arp"]
29+
"static_arp": ["protocols_static_arp"],
30+
"firewall": ["firewall"]
2431
},
2532
"interfaces_l2tpv3": {
26-
"static_arp": ["protocols_static_arp"]
33+
"static_arp": ["protocols_static_arp"],
34+
"firewall": ["firewall"]
2735
},
2836
"interfaces_macsec": {
29-
"static_arp": ["protocols_static_arp"]
37+
"static_arp": ["protocols_static_arp"],
38+
"firewall": ["firewall"]
39+
},
40+
"interfaces_openvpn": {
41+
"firewall": ["firewall"]
42+
},
43+
"interfaces_pppoe": {
44+
"firewall": ["firewall"]
3045
},
3146
"interfaces_pseudo_ethernet": {
32-
"static_arp": ["protocols_static_arp"]
47+
"static_arp": ["protocols_static_arp"],
48+
"firewall": ["firewall"]
49+
},
50+
"interfaces_sstpc": {
51+
"firewall": ["firewall"]
52+
},
53+
"interfaces_tunnel": {
54+
"firewall": ["firewall"]
3355
},
3456
"interfaces_virtual_ethernet": {
35-
"static_arp": ["protocols_static_arp"]
57+
"static_arp": ["protocols_static_arp"],
58+
"firewall": ["firewall"]
59+
},
60+
"interfaces_vti": {
61+
"firewall": ["firewall"]
3662
},
3763
"interfaces_vxlan": {
38-
"static_arp": ["protocols_static_arp"]
64+
"static_arp": ["protocols_static_arp"],
65+
"firewall": ["firewall"]
3966
},
4067
"interfaces_wireless": {
41-
"static_arp": ["protocols_static_arp"]
68+
"static_arp": ["protocols_static_arp"],
69+
"firewall": ["firewall"]
4270
},
4371
"interfaces_wwan": {
44-
"static_arp": ["protocols_static_arp"]
72+
"static_arp": ["protocols_static_arp"],
73+
"firewall": ["firewall"]
4574
},
4675
"interfaces_wireguard": {
47-
"vxlan": ["interfaces_vxlan"]
76+
"vxlan": ["interfaces_vxlan"],
77+
"firewall": ["firewall"]
4878
},
4979
"load_balancing_wan": {
5080
"conntrack": ["system_conntrack"]

data/templates/firewall/nftables-zone.j2

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
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 | quoted_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 %}
15+
{% for vrf_name in zone_conf.member.vrf %}
16+
{% if zone_conf['vrf_interfaces'][vrf_name] | length > 0 %}
17+
oifname { {{ zone_conf['vrf_interfaces'][vrf_name] | quoted_join(",") }} } counter jump VZONE_{{ zone_name }}
18+
{% endif %}
19+
{% endfor %}
1520
oifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter jump VZONE_{{ zone_name }}
1621
{% endif %}
1722
{% endif %}
@@ -71,6 +76,12 @@
7176
oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return
7277
{% endif %}
7378
{% if 'vrf' in zone[from_zone].member %}
79+
{% for vrf_name in zone[from_zone].member.vrf %}
80+
{% if zone[from_zone]['vrf_interfaces'][vrf_name] | length > 0 %}
81+
oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
82+
oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] | quoted_join(",") }} } counter return
83+
{% endif %}
84+
{% endfor %}
7485
oifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
7586
oifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return
7687
{% endif %}
@@ -84,9 +95,13 @@
8495
{% endif %}
8596
{% if 'vrf' in zone[from_zone].member %}
8697
{% for vrf_name in zone[from_zone].member.vrf %}
87-
oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter jump NAME{{ suffix }}_{{ from_conf[fw_name] }}
88-
oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter return
98+
{% if zone[from_zone]['vrf_interfaces'][vrf_name] | length > 0 %}
99+
oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf[fw_name] }}
100+
oifname { {{ zone[from_zone]['vrf_interfaces'][vrf_name] | quoted_join(",") }} } counter return
101+
{% endif %}
89102
{% endfor %}
103+
oifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
104+
oifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return
90105
{% endif %}
91106
{% endfor %}
92107
{% endif %}

smoketest/scripts/cli/test_firewall.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,8 +1143,10 @@ def test_zone_with_vrf(self):
11431143
self.cli_set(['vrf', 'name', 'VRF-1', 'table', '101'])
11441144
self.cli_set(['vrf', 'name', 'VRF-2', 'table', '102'])
11451145
self.cli_set(['interfaces', 'ethernet', 'eth0', 'vrf', 'VRF-1'])
1146-
self.cli_set(['interfaces', 'vti', 'vti1', 'vrf', 'VRF-2'])
1146+
self.cli_set(['interfaces', 'vti', 'vti1', 'vrf', 'VRF-1'])
1147+
self.cli_set(['interfaces', 'vti', 'vti2', 'vrf', 'VRF-2'])
11471148

1149+
# commit the config
11481150
self.cli_commit()
11491151

11501152
nftables_search = [
@@ -1155,8 +1157,10 @@ def test_zone_with_vrf(self):
11551157
['chain VYOS_ZONE_FORWARD'],
11561158
['type filter hook forward priority filter + 1'],
11571159
['oifname { "eth1", "eth2" }', 'counter packets', 'jump VZONE_ZONE1'],
1160+
['oifname { "eth0", "vti1" }', 'counter packets', 'jump VZONE_ZONE1'],
11581161
['oifname "VRF-1"', 'counter packets', 'jump VZONE_ZONE1'],
11591162
['oifname "vtun66"', 'counter packets', 'jump VZONE_ZONE2'],
1163+
['oifname "vti2"', 'counter packets', 'jump VZONE_ZONE2'],
11601164
['oifname "VRF-2"', 'counter packets', 'jump VZONE_ZONE2'],
11611165
['chain VYOS_ZONE_LOCAL'],
11621166
['type filter hook input priority filter + 1'],
@@ -1190,8 +1194,10 @@ def test_zone_with_vrf(self):
11901194
['chain VYOS_ZONE_FORWARD'],
11911195
['type filter hook forward priority filter + 1'],
11921196
['oifname { "eth1", "eth2" }', 'counter packets', 'jump VZONE_ZONE1'],
1197+
['oifname { "eth0", "vti1" }', 'counter packets', 'jump VZONE_ZONE1'],
11931198
['oifname "VRF-1"', 'counter packets', 'jump VZONE_ZONE1'],
11941199
['oifname "vtun66"', 'counter packets', 'jump VZONE_ZONE2'],
1200+
['oifname "vti2"', 'counter packets', 'jump VZONE_ZONE2'],
11951201
['oifname "VRF-2"', 'counter packets', 'jump VZONE_ZONE2'],
11961202
['chain VYOS_ZONE_LOCAL'],
11971203
['type filter hook input priority filter + 1'],
@@ -1203,6 +1209,7 @@ def test_zone_with_vrf(self):
12031209
['counter packets', 'drop', 'comment "zone_LOCAL default-action drop"'],
12041210
['chain VZONE_LOCAL_OUT'],
12051211
['oifname "vtun66"', 'counter packets', 'jump NAME6_LOCAL_to_ZONE2_v6'],
1212+
['oifname "vti2"', 'counter packets', 'jump NAME6_LOCAL_to_ZONE2_v6'],
12061213
['oifname "VRF-2"', 'counter packets', 'jump NAME6_LOCAL_to_ZONE2_v6'],
12071214
['counter packets', 'drop', 'comment "zone_LOCAL default-action drop"'],
12081215
['chain VZONE_ZONE1'],
@@ -1218,6 +1225,23 @@ def test_zone_with_vrf(self):
12181225
self.verify_nftables(nftables_search, 'ip vyos_filter')
12191226
self.verify_nftables(nftables_search_v6, 'ip6 vyos_filter')
12201227

1228+
# change memberships in vrf
1229+
self.cli_set(['interfaces', 'vti', 'vti1', 'vrf', 'VRF-2'])
1230+
self.cli_commit()
1231+
1232+
# make som verifications to ensure the interface swapped vrf
1233+
nftables_search = [
1234+
['oifname "eth0"', 'counter packets', 'jump VZONE_ZONE1'],
1235+
['oifname { "vti1", "vti2" }', 'counter packets', 'jump VZONE_ZONE2'],
1236+
]
1237+
1238+
nftables_search_v6 = [
1239+
['oifname "eth0"', 'counter packets', 'jump VZONE_ZONE1'],
1240+
['oifname { "vti1", "vti2" }', 'counter packets', 'jump VZONE_ZONE2'],
1241+
]
1242+
self.verify_nftables(nftables_search, 'ip vyos_filter')
1243+
self.verify_nftables(nftables_search_v6, 'ip6 vyos_filter')
1244+
12211245
def test_zone_without_member(self):
12221246
self.cli_set(['firewall', 'zone', 'wan', 'default-action', 'drop'])
12231247
error_message = 'Zone "wan" has no interfaces and is not the local zone'

src/conf_mode/firewall.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ def get_config(config=None):
138138
if 'vrf' in local_zone_member:
139139
local_zone_conf['vrf_interfaces'] = {}
140140
for vrf_name in local_zone_member['vrf']:
141-
local_zone_conf['vrf_interfaces'][vrf_name] = ','.join(get_vrf_members(vrf_name))
141+
local_zone_conf['vrf_interfaces'][vrf_name] = get_vrf_members(
142+
vrf_name
143+
)
142144
continue
143145

144146
local_zone_conf['from_local'] = {}

src/conf_mode/interfaces_bonding.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ def get_config(config=None):
171171
if 'static_arp' in bond:
172172
set_dependents('static_arp', conf)
173173

174+
# Check vrf membership, to ensure firewall is updated
175+
if is_node_changed(conf, base + [ifname, 'vrf']):
176+
bond.update({'vrf_changed': {}})
177+
set_dependents('firewall', conf)
178+
174179
bond['vpp_ifaces'] = cli_ifaces_list(conf)
175180

176181
return bond
@@ -298,7 +303,11 @@ def apply(bond):
298303
else:
299304
b.update(bond)
300305

301-
if dict_search('member.interface_remove', bond) or 'static_arp' in bond:
306+
if (
307+
dict_search('member.interface_remove', bond)
308+
or 'static_arp' in bond
309+
or 'vrf_changed' in bond
310+
):
302311
try:
303312
call_dependents()
304313
except ConfigError:

src/conf_mode/interfaces_bridge.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from vyos.config import Config
2020
from vyos.configdict import get_interface_dict
21+
from vyos.configdict import is_node_changed
2122
from vyos.configdict import node_changed
2223
from vyos.configdict import is_member
2324
from vyos.configdict import is_source_interface
@@ -129,6 +130,11 @@ def get_config(config=None):
129130
if 'static_arp' in bridge:
130131
set_dependents('static_arp', conf)
131132

133+
# Check vrf membership, to ensure firewall is updated
134+
if is_node_changed(conf, base + [ifname, 'vrf']):
135+
bridge.update({'vrf_changed': {}})
136+
set_dependents('firewall', conf)
137+
132138
bridge['vpp_ifaces'] = cli_ifaces_list(conf)
133139

134140
return bridge
@@ -233,7 +239,7 @@ def apply(bridge):
233239
if iface.startswith(('vxlan', 'wlan')) and interface_exists(iface)
234240
]
235241

236-
if interfaces_need_update or 'static_arp' in bridge:
242+
if interfaces_need_update or 'static_arp' in bridge or 'vrf_changed' in bridge:
237243
try:
238244
call_dependents()
239245
except ConfigError:

src/conf_mode/interfaces_dummy.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
from vyos.config import Config
2020
from vyos.configdict import get_interface_dict
21+
from vyos.configdict import is_node_changed
22+
from vyos.configdep import set_dependents
23+
from vyos.configdep import call_dependents
2124
from vyos.configverify import verify_vrf
2225
from vyos.configverify import verify_address
2326
from vyos.configverify import verify_bridge_delete
@@ -37,7 +40,12 @@ def get_config(config=None):
3740
else:
3841
conf = Config()
3942
base = ['interfaces', 'dummy']
40-
_, dummy = get_interface_dict(conf, base)
43+
ifname, dummy = get_interface_dict(conf, base)
44+
45+
# Check vrf membership, to ensure firewall is updated
46+
if is_node_changed(conf, base + [ifname, 'vrf']):
47+
set_dependents('firewall', conf)
48+
4149
return dummy
4250

4351
def verify(dummy):
@@ -63,6 +71,9 @@ def apply(dummy):
6371
else:
6472
d.update(dummy)
6573

74+
# run the dependents
75+
call_dependents()
76+
6677
return None
6778

6879
if __name__ == '__main__':

src/conf_mode/interfaces_ethernet.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ def get_config(config=None):
195195
if 'static_arp' in ethernet:
196196
set_dependents('static_arp', conf)
197197

198+
# Check vrf membership, to ensure firewall is updated
199+
if is_node_changed(conf, base + [ifname, 'vrf']):
200+
set_dependents('firewall', conf)
201+
198202
return ethernet
199203

200204
def verify_speed_duplex(ethernet: dict, ethtool: Ethtool):
@@ -441,8 +445,9 @@ def apply(ethernet):
441445
e.remove()
442446
else:
443447
e.update(ethernet)
444-
if 'static_arp' in ethernet:
445-
call_dependents()
448+
449+
# run the dependents
450+
call_dependents()
446451

447452
vpp_iface_config = dict_search(f'vpp.settings.interface.{ifname}', ethernet)
448453
if vpp_iface_config is not None and is_systemd_service_running('vpp.service'):

src/conf_mode/interfaces_geneve.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ def get_config(config=None):
5757
if 'static_arp' in geneve:
5858
set_dependents('static_arp', conf)
5959

60+
# Check vrf membership, to ensure firewall is updated
61+
if is_node_changed(conf, base + [ifname, 'vrf']):
62+
set_dependents('firewall', conf)
63+
6064
return geneve
6165

6266
def verify(geneve):
@@ -96,8 +100,8 @@ def apply(geneve):
96100
g = GeneveIf(**geneve)
97101
g.update(geneve)
98102

99-
if 'static_arp' in geneve:
100-
call_dependents()
103+
# run the dependents
104+
call_dependents()
101105

102106
return None
103107

src/conf_mode/interfaces_l2tpv3.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from vyos.configdep import set_dependents
2121
from vyos.configdep import call_dependents
2222
from vyos.configdict import get_interface_dict
23+
from vyos.configdict import is_node_changed
2324
from vyos.configdict import leaf_node_changed
2425
from vyos.configverify import verify_address
2526
from vyos.configverify import verify_bridge_delete
@@ -62,6 +63,10 @@ def get_config(config=None):
6263
if 'static_arp' in l2tpv3:
6364
set_dependents('static_arp', conf)
6465

66+
# Check vrf membership, to ensure firewall is updated
67+
if is_node_changed(conf, base + [ifname, 'vrf']):
68+
set_dependents('firewall', conf)
69+
6570
return l2tpv3
6671

6772
def verify(l2tpv3):
@@ -106,8 +111,8 @@ def apply(l2tpv3):
106111
l = L2TPv3If(**l2tpv3)
107112
l.update(l2tpv3)
108113

109-
if 'static_arp' in l2tpv3:
110-
call_dependents()
114+
# run the dependents
115+
call_dependents()
111116

112117
return None
113118

0 commit comments

Comments
 (0)