#
# FFHO Routing Policy
#
{%- set node_roles = salt['pillar.get']('node:roles', []) %}
{%- set node_sites = salt['pillar.get']('node:sites', []) %}
{%- set sites = salt['pillar.get']('sites', {}) %}
{%- set te = salt['pillar.get']('te', {}) %}


################################################################################
#                              Static Filters                                  #
################################################################################

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_CR04   = (65132, 104);
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;


{%- 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 = DRAIN_FULL then
		reject;

{%- if 'batman_gw' in node_roles %}
	tag_site_routes ();
{%- endif %}

	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 %}

}