94 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Django/Jinja
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
	
		
			3.1 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 %}
 | |
| {% for family in ['ipv4', 'ipv6'] %}
 | |
|   address-family {{ family }} 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
 | |
| 
 | |
| {% endfor %}
 | |
|   address-family l2vpn evpn
 | |
|     neighbor fabric activate
 | |
| {% for iface in interfaces | selectattr('enabled') | selectattr('name', 'in', ifaces_evpn|default([])) %}
 | |
|     neighbor {{ iface.name }} 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 %}
 |