network/roles/firewall/templates/frr.conf.j2
Timotej Lazar 65c16dbc63 Drop BGP update-delay option
Dropped from Cumulus manual and advised by seniors.
2024-02-27 13:35:29 +01:00

150 lines
5 KiB
Django/Jinja

{% set addrs = interfaces | selectattr('name', '==', 'lo') |
map(attribute='ip_addresses') | first | selectattr('role') %}
{% set loopback = addrs | selectattr('role.value', '==', 'loopback') | map(attribute='address') -%}
frr defaults datacenter
service integrated-vtysh-config
log syslog
# Without this frr and kernel ECMP routes sometimes get desynced when a link is
# lost and found. Maybe related to https://github.com/FRRouting/frr/issues/12239.
zebra nexthop-group keep 1
router-id {{ loopback | ipv4 | first | ipaddr('address') }}
bfd
profile fast
receive-interval 150
transmit-interval 150
# Default VRF has two connections to each exit, one for inside and one
# for outside networks. The efault route is received from the outside
# peers and distributed back to inside peers. Routes to office
# networks and NAT IPs are distributed to outside peers.
router bgp {{ asn.asn }}
# Allow multipathing through different ASs with equal path length.
bgp bestpath as-path multipath-relax
# NAT IPs are not on any interface so disable checking for it.
no bgp network import-check
{% for group in ['inside', 'outside'] %}
neighbor {{ group }} peer-group
neighbor {{ group }} remote-as external
neighbor {{ group }} capability extended-nexthop
{% endfor %}
{% for iface in interfaces | selectattr('name', 'match', '^lan') %}
neighbor {{ iface.name }}.2 interface peer-group inside
neighbor {{ iface.name }}.2 bfd profile fast
neighbor {{ iface.name }}.4 interface peer-group outside
neighbor {{ iface.name }}.4 bfd profile fast
{% endfor %}
address-family ipv4 unicast
{% for network in nat %}
network {{ network }}
{% endfor %}
redistribute connected route-map loopback
maximum-paths 16
neighbor outside soft-reconfiguration inbound
neighbor outside route-map outside->default in
neighbor outside route-map default->outside out
neighbor inside allowas-in origin
neighbor inside default-originate
neighbor inside soft-reconfiguration inbound
neighbor inside route-map inside->default in
neighbor inside route-map default->inside out
exit-address-family
address-family ipv6 unicast
redistribute connected route-map loopback
maximum-paths 16
neighbor outside activate
neighbor outside soft-reconfiguration inbound
neighbor outside route-map outside->default in
neighbor outside route-map default->outside out
neighbor inside activate
neighbor inside allowas-in origin
neighbor inside default-originate
neighbor inside soft-reconfiguration inbound
neighbor inside route-map inside->default in
neighbor inside route-map default->inside out
exit-address-family
# Prefix lists.
ip prefix-list default permit 0.0.0.0/0
ipv6 prefix-list default permit ::/0
ip prefix-list fabric permit 10.34.0.0/24 ge 32
{% for vlan in vlans | selectattr('role.slug', '==', 'inside') %}
{% for prefix in query('netbox.netbox.nb_lookup', 'prefixes', api_filter='vlan_id='~vlan.id, raw_data=true) %}
{% if prefix.family.value == 4 %}
ip prefix-list office permit {{ prefix.prefix }} ge 24
{% elif prefix.family.value == 6 %}
ipv6 prefix-list office permit {{ prefix.prefix }} ge 64
{% endif %}
{% endfor %}
{% endfor %}
{% if wg_net is defined %}
ip prefix-list vpn permit {{ wg_net | ipaddr('subnet') }}
{% endif %}
{% if wg_net6 is defined %}
ipv6 prefix-list vpn permit {{ wg_net6 | ipaddr('subnet') }}
{% endif %}
{% for network in nat %}
ip prefix-list nat permit {{ network }}
{% endfor %}
{# TODO WG endpoint should probably be in a separate prefix-list. #}
ip prefix-list nat permit {{ wg_ip }}
route-map loopback permit 1
match interface lo
route-map loopback permit 2
match interface wg
# Get routes to offices from inside peers.
route-map inside->default permit 10
match ip address prefix-list fabric
route-map inside->default permit 20
match ip address prefix-list office
route-map inside->default permit 21
match ipv6 address prefix-list office
# Send default route and VPN network to inside peers.
route-map default->inside permit 1
match interface lo
route-map default->inside permit 20
match ip address prefix-list default
route-map default->inside permit 21
match ipv6 address prefix-list default
# I don’t think these /need/ to be announced separately since we are sending the default route anyway.
#route-map default->inside permit 30
# match ip address prefix-list vpn
#route-map default->inside permit 31
# match ipv6 address prefix-list vpn
# Get default route from outside peers.
route-map outside->default permit 10
match ip address prefix-list default
route-map outside->default permit 11
match ipv6 address prefix-list default
# Send IPv6 office addresses and IPv4 NAT addresses to outside peers
# so inbound packets go through the firewall.
route-map default->outside permit 1
match interface lo
route-map default->outside permit 11
match ipv6 address prefix-list office
route-map default->outside permit 20
match ip address prefix-list nat
route-map default->outside permit 31
match ipv6 address prefix-list vpn