network/roles/leaf/templates/frr.conf.j2
Timotej Lazar 457ab7d3b7 Query prefixes once for all hosts
And group them into vrf_prefixes for VLAN networks and bgp_prefixes for
servers plugged directly into fabric.

This should reduce the number of queries to NetBox when configuring
firewalls and exit switches. Not sure but I think set_fact helps to
avoid queries (as opposed to setting group_vars).
2024-04-28 12:14:05 +02:00

103 lines
3.3 KiB
Django/Jinja

{% set lo_address = interfaces
| selectattr('name', '==', 'lo')
| map(attribute='ip_addresses') | first
| selectattr('role') | selectattr('role.value', '==', 'loopback')
| map(attribute='address') %}
{% set iface_bgp = interfaces
| selectattr('enabled')
| rejectattr('type.value', 'in', ('bridge', 'lag'))
| rejectattr('mgmt_only') | rejectattr('bridge') | rejectattr('lag') %}
{% set iface_server = iface_bgp | selectattr('custom_fields.tenant') %}
{% set iface_fabric = iface_bgp | difference(iface_server) | rejectattr('ip_addresses') %}
{% set my_tenants = iface_server | map(attribute='custom_fields.tenant.slug') | unique -%}
frr defaults datacenter
log syslog informational
service integrated-vtysh-config
# Route installation into kernels fails (rarely) without this option.
# It is not documented anywhere and appears to be a Cumulus extension.
zebra nexthop proto only
router-id {{ lo_address | ipv4 | first | ipaddr('address') }}
router bgp {{ asn.asn }}
bgp bestpath as-path multipath-relax
neighbor fabric peer-group
neighbor fabric remote-as external
{% for interface in iface_fabric %}
neighbor {{ interface.name }} interface peer-group fabric
neighbor {{ interface.name }} bfd 3 150 150
{% endfor %}
{% for tenant in my_tenants %}
neighbor dc-{{ tenant }} peer-group
neighbor dc-{{ tenant }} remote-as external
{% for interface in iface_server | selectattr('custom_fields.tenant.slug', '==', tenant) %}
neighbor {{ interface.name }} interface peer-group dc-{{ tenant }}
neighbor {{ interface.name }} bfd
{% endfor %}
{% endfor %}
address-family ipv4 unicast
redistribute connected route-map loopbacks
neighbor fabric activate
{% for tenant in my_tenants %}
neighbor dc-{{ tenant }} activate
neighbor dc-{{ tenant }} route-map dc-{{ tenant }}->default in
neighbor dc-{{ tenant }} route-map default->dc out
{% endfor %}
exit-address-family
address-family ipv6 unicast
redistribute connected route-map loopbacks
neighbor fabric activate
{% for tenant in my_tenants %}
neighbor dc-{{ tenant }} activate
neighbor dc-{{ tenant }} route-map dc-{{ tenant }}->default in
neighbor dc-{{ tenant }} route-map default->dc out
{% endfor %}
exit-address-family
address-family l2vpn evpn
neighbor fabric activate
{% for iface in ifaces_evpn|default([]) %}
neighbor {{ iface }} activate
{% endfor %}
{% if peer is defined and interfaces | selectattr('mode') %}
advertise-all-vni
{% endif %}
exit-address-family
route-map loopbacks permit 10
match interface lo
{% if my_tenants %}
ip prefix-list default permit 0.0.0.0/0
ipv6 prefix-list default permit ::/0
{% for prefix in bgp_prefixes | selectattr('tenant.slug', 'in', my_tenants) %}
{% if prefix.family.value == 4 %}
ip prefix-list dc-{{ prefix.tenant.slug }} permit {{ prefix.prefix }} ge 32
{% else %}
ipv6 prefix-list dc-{{ prefix.tenant.slug }} permit {{ prefix.prefix }} ge 64
{% endif %}
{% endfor %}
# We only announce the default route to DC servers.
route-map default->dc permit 10
match ip address prefix-list default
route-map default->dc permit 11
match ipv6 address prefix-list default
{% for tenant in my_tenants %}
route-map dc-{{ tenant }}->default permit 10
match ip address prefix-list dc-{{ tenant }}
route-map dc-{{ tenant }}->default permit 11
match ipv6 address prefix-list dc-{{ tenant }}
{% endfor %}
{% endif %}