# # FFHO IGP / OSPF configuration (Salt managed) # {%- set node_config = salt['pillar.get']('nodes:' ~ grains['id'], {}) %} {%- set roles = node_config.get ('roles', []) %} {%- set ospf_node_config = node_config.get('ospf', {}) %} {%- if 'stub_router' in ospf_node_config and ospf_node_config['stub_router'] in [ True, 'yes'] %} {%- do ospf_node_config.update ({'stub_router': 'yes'}) %} {%- endif %} {%- set ospf_config = salt['ffho_net.get_ospf_config'](node_config, grains['id']) %} {%- if AF == 6 %} # Bloody workaround for bird6's unwillingness to read !LL IPv6 addresses from lo protocol direct lo_v6 { interface "lo"; } {%- endif %} protocol ospf IGP { import all; {%- if AF == 4 %} {%- if grains['id'].startswith ('cr') %} export filter { if net = 0.0.0.0/0 then { ospf_metric1 = 100; accept; } reject; }; {%- else %} export none; {%- endif %} {%- elif AF == 6 %} export filter { {%- if grains['id'].startswith ('cr') %} if net = ::/0 then { ospf_metric1 = 100; accept; } {%- endif %} if proto = "lo_v6" then { ospf_metric1 = 100; accept; } reject; }; {%- endif %} area 0.0.0.0 { stub {{ ospf_node_config.get ('stub_router', 'no') }} ; interface "lo" { stub yes; }; {%- for iface in ospf_config.get(0, {})|sort %} {%- set config = ospf_config[0][iface] %} {%- if config.get('AF', AF) != AF %} {%- continue %} {%- endif %} {#- Interface description? #} {%- set desc = salt['pillar.get']('nodes:' ~ grains['id'] ~ ':ifaces:' ~ iface ~ ':desc', "") %} # {{ desc }} interface "{{ iface }}" { {%- if 'desc' in config %} # {{ config.get ('desc') }} {%- endif %} {%- for attr in config|sort if attr not in ['desc', 'AF'] %} {%- set value = config.get (attr) %} {#- 'is bool' only introduced in Jinja 2.11 #} {%- if salt['ffho.is_bool'](value) %} {%- set value = 'yes' if value else 'no' %} {%- endif %} {{ attr }} {{ value }}; {%- endfor %} }; {%- endfor %} {#- # Backbone OpenVPNs #} {%- set interfaces = {} %} {%- for vpn, vpn_config in salt['pillar.get']('ovpn', {}).items () %} {%- if grains['id'] in vpn_config %} {%- set host_config = vpn_config.get (grains['id'], {}).get ('config', {}) %} {%- set interface = host_config.get ('interface', vpn_config.get ('interface', '')) %} {%- if interface.startswith ('ovpn-') %} {%- do interfaces.update({interface: { 'cost': vpn_config.get (grains['id'], {}).get ('config', {}).get ('cost', False) }}) %} {%- endif %} {%- endif %} {%- endfor %} {%- for interface, iface_config in interfaces.items()|sort %} interface "{{ interface }}" { {%- if interface.startswith ('ovpn-er-') and not 'yni' in interface and AF == 6 %} type broadcast; {%- else %} type pointopoint; {%- endif %} {%- if iface_config.cost %} cost {{ iface_config.cost }}; {%- elif interface.startswith ('ovpn-cr') %} cost 5000; {%- else %} cost 10000; {%- endif %} }; {% endfor %} {%- if 'veth_int2ext' in node_config.get ('ifaces', {}) %} # Learn transfer prefix to external VRF for BGP recursive lookup. interface "veth_int2ext" { stub yes; }; {%- endif %} {%- if 'ops-vpn' in roles %} interface "tun-ops" { stub yes; }; {%- endif %} }; {#- Interfaces for non-backbone areas (OOBM e.g.) #} {%- for area in ospf_config if area != 0 %} # Area {{ area }} {%- set area_ifaces = ospf_config[area] %} area {{ area }} { {%- for iface in area_ifaces|sort %} {%- set iface_config = area_ifaces[iface] %} {%- if iface_config.get('AF', AF) != AF %} {%- continue %} {%- endif %} interface "{{ iface }}" { {%- if 'desc' in iface_config %} # {{ iface_config.get ('desc') }} {%- endif %} {%- for attr in iface_config|sort if attr not in ['desc', 'AF'] %} {%- set value = iface_config.get (attr) %} {#- 'is bool' only introduced in Jinja 2.11 #} {%- if salt['ffho.is_bool'](value) %} {%- set value = 'yes' if value else 'no' %} {%- endif %} {{ attr }} {{ value }}; {%- endfor %} }; {%- endfor %} }; {%- endfor %} }