From 9b03b002f78bf05feaa3794e0494824f5259edc1 Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Fri, 18 Jul 2025 15:11:11 +0200 Subject: [PATCH] =?UTF-8?q?exit:=20import=20firewalls=E2=80=99=20addresses?= =?UTF-8?q?=20into=20inside=20VRFs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mostly so that the backup firewall is reachable from inside. Without this, such traffic would be routed towards the active firewall and dropped there. --- filter_plugins/netbox.py | 8 ++++++++ roles/exit/templates/frr.conf.j2 | 15 +++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/filter_plugins/netbox.py b/filter_plugins/netbox.py index 23a4f86..0932c41 100644 --- a/filter_plugins/netbox.py +++ b/filter_plugins/netbox.py @@ -8,6 +8,7 @@ class FilterModule(object): def filters(self): return { 'compact_numlist': self.compact_numlist, + 'device_address': self.device_address, 'iface_real': self.iface_real, 'iface_peer': self.iface_peer, 'iface_vlans': self.iface_vlans @@ -27,6 +28,13 @@ class FilterModule(object): i = j return delimiter.join(spans) + def device_address(self, device): + '''Return loopback IP addresses for an L3 attached device''' + for iface in device['interfaces']: + for addr in iface['ip_addresses']: + if addr.get('role') and addr['role'].get('value') == 'loopback': + yield addr + def iface_real(self, interfaces): '''Return only non-virtual interfaces''' for iface in interfaces: diff --git a/roles/exit/templates/frr.conf.j2 b/roles/exit/templates/frr.conf.j2 index 39c35e1..aaa2b61 100644 --- a/roles/exit/templates/frr.conf.j2 +++ b/roles/exit/templates/frr.conf.j2 @@ -199,6 +199,17 @@ ipv6 prefix-list default permit ::/0 ip prefix-list fabric permit 10.34.0.0/24 ge 32 ipv6 prefix-list fabric permit 2001:1470:fffd:3400::/64 ge 128 +# prefix list for firewalls’ own addresses +{% for firewall in interfaces | selectattr('name', 'in', ifaces_firewall) | iface_peer %} +{% for address in hostvars[firewall] | device_address %} +{% if address.family.value == 4 %} +ip prefix-list firewall permit {{ address.address }} +{% else %} +ipv6 prefix-list firewall permit {{ address.address }} +{% endif %} +{% endfor %} +{% endfor %} + # prefix list for outside networks {% for prefix in vrf_prefixes | selectattr('vrf.name', '==', 'outside') | sort(attribute='family.value') | sort(attribute='vlan.vid') %} @@ -286,6 +297,10 @@ route-map office-import permit 10 match ip address prefix-list default route-map office-import permit 11 match ipv6 address prefix-list default +route-map office-import permit 20 + match ip address prefix-list firewall +route-map office-import permit 21 + match ipv6 address prefix-list firewall route-map inside-import permit 20 match ip address prefix-list office