# # FFHO Routing Policy # {%- set node_roles = salt['pillar.get']('nodes:' ~ grains['id'] ~ ':roles', []) %} {%- set node_sites = salt['pillar.get']('nodes:' ~ grains['id'] ~ ':sites', []) %} {%- set sites = salt['pillar.get']('sites', {}) %} {%- set te = salt['pillar.get']('te', {}) %} ################################################################################ # Static Filters # ################################################################################ filter external_IPs_to_learn { if net ~ [ {%- if proto == 'v4' %} 80.70.181.59/32, # mail.ffho.net 80.70.181.61/32 # fe01.ffho.net {%- else %} 2a02:450:1:0::/64 # Vega VM Subnet {%- endif %} ] then accept; reject; }; filter own_prefixes { if net ~ [ {%- if proto == 'v4' %} 10.132.0.0/16, 172.30.0.0/16{24,24} {%- else %} fdca:ffee:ff12::/48, 2a03:2260:2342::/48 {%- endif %} ] then accept; reject; }; ################################################################################ # iBGP routing policy (Communities + Filter) + TE # ################################################################################ {%- for site in node_sites %} {%- set site_config = sites.get (site) %} {%- set community = 'SITE_' ~ site|upper|replace('-', '') ~ '_ROUTE' %} {%- set community_id = site_config.get ('site_no')|int + 100 %} define {{ community }} = (65132,{{ community_id }}); {%- endfor %} # Prefixes longer that site prefix leaving a gateway as TE prefixes. # They are for TE core -> gateway only and must not be imported on other gateways. define GATEWAY_TE_ROUTE = (65132,300); # All our prefixes learned in the external VRF and redistributed into the # internal network define EXTERNAL_ROUTE = (65132,1023); # TE routes only to be exported by specific border routers define EXPORT_RESTRICT = (65132, 100); define EXPORT_ONLY_AT_CR01 = (65132, 101); define EXPORT_ONLY_AT_CR02 = (65132, 102); define EXPORT_ONLY_AT_CR03 = (65132, 103); define EXPORT_ONLY_AT_BBR_KT = (65132, 197); # Anycasted prefix define ANYCAST_PREFIX = (65132,999); # To be placed in /etc/bird/ff_killswitch.conf define SITE_LEGACY_ONLINE = 1; define SITE_PADCTY_ONLINE = 1; define SITE_PADUML_ONLINE = 1; define DRAINED = 0; {%- if 'batman_gw' in node_roles %} function tag_site_routes () { {%- for site in node_sites %} {%- set site_config = sites.get (site) %} {%- set prefix = site_config.get ('prefix_' ~ proto) %} {%- set prefix_mask_te = prefix.split ('/')[1]|int + 1 %} {%- set community = 'SITE_' ~ site|upper|replace('-', '') ~ '_ROUTE' %} # {{ site_config.get ('name', site) }} if net ~ [ {{ prefix }}+ ] then { bgp_community.add ({{ community }}); } {#- # Tag all routes for prefixes longer than site prefix leaving a gateway # as TE prefixes. They are for TE core -> gateway only and must not be # imported on other gateways. #} {%- if proto == 'v4' %} if net ~ [ {{ prefix ~ '{' ~ prefix_mask_te ~ ',32}' }} ] then { bgp_community.add (GATEWAY_TE_ROUTE); } {%- endif %} {% endfor %} } {%- endif %} filter ibgp_in { {#- Don't import other gateways TE prefixes here #} {%- if 'batman_gw' in node_roles %} if (GATEWAY_TE_ROUTE ~ bgp_community) then { reject; } {%- endif %} accept; } filter ibgp_out { # Don't redistribute OSPF into iBGP if "IGP" = proto then reject; # Don't redistribute v6 LO IP if "lo_v6" = proto then reject; # Don't redistribute null routes for bogon prefixes if "bogon_unreach" = proto then reject; # Don't redistribute TE prefixes for FFRL if "ffrl_te" = proto then reject; # Don't redistribute anything IF we are drained if 1 = DRAINED then reject; {%- if 'batman_gw' in node_roles %} tag_site_routes (); {%- endif %} bgp_next_hop = LO_IP; accept; } # Traffic engineering routes protocol static ffho_te { preference 23; {% set prefixes = salt['ffho_net.get_te_prefixes'](te, grains['id'], proto) %} {% for prefix in prefixes|sort %} {%- set config = prefixes.get (prefix) %} {%- if 'desc' in config %} # {{ config.get ('desc') }} {%- endif %} route {{ prefix }} unreachable { {%- for community in config.get ('communities', []) %} bgp_community.add ({{ community }}); {%- endfor %} }; {%- endfor %} }