{{ ansible_managed | comment }} log syslog all; router id {{ bird__router_id }}; protocol device { scan time 10; } {% for name, kernel in bird__kernel.items() %} {% for version in ["ipv4", "ipv6"] %} {% set ipv4 = version == "ipv4" %} protocol kernel {{ name | bird_name(ipv4) }} { {% if kernel.kernel is defined %} kernel table {{ kernel.kernel }}; {% endif %} {% if kernel.learn | default(False) %} learn; {% endif %} {% if kernel.persist | default(False) %} persist; {% endif %} {{ version }} { {{ kernel.import | default([]) | bird_import(ipv4) | indent(8) }} {% if kernel.limits.import is defined %} import limit {{ kernel.limits.import }}; {% endif %} {{ kernel.export | default([]) | bird_export(ipv4) | indent(8) }} {% if kernel.limits.export is defined %} export limit {{ kernel.limits.export }}; {% endif %} }; } {% endfor %} {% endfor %} {% if bird__ospf is defined %} {% for version in ["ipv4", "ipv6"] %} {% set ipv4 = version == "ipv4" %} {% set ospf_version = "v2" if ipv4 else "v3" %} protocol ospf {{ ospf_version }} {{ "ospf" | bird_name(ipv4) }} { {{ version }} { {{ bird__ospf.import | default([]) | bird_import(ipv4) | indent(8) }} {% if bird__ospf.limits.import is defined %} import limit {{ bird__ospf.limits.import }}; {% endif %} {{ bird__ospf.export | default([]) | bird_export(ipv4) | indent(8) }} {% if bird__ospf.limits.export is defined %} export limit {{ bird__ospf.limits.export }}; {% endif %} }; {% for id, area in bird__ospf.areas.items() %} area {{ id }} { {% for iface in area.broadcast | default([]) %} interface {{ iface | enquote }} { type broadcast; hello 2; retransmit 5; wait 10; dead 20; }; {% endfor %} {% for iface in area.stub | default([]) %} interface {{ iface | enquote }} { stub; }; {% endfor %} }; {% endfor %} } {% endfor %} {% endif %} {% for name, bgp in bird__bgp.items() %} {% for version in ["ipv4", "ipv6"] %} {% set ipv4 = version == "ipv4" %} protocol bgp {{ name | bird_name(ipv4) }} { local {{ bgp.local.address | ansible.utils.ipaddr(version) | first }} as {{ bgp.local.as }}; neighbor {{ bgp.neighbor.address | ansible.utils.ipaddr(version) | first }} as {{ bgp.neighbor.as }}; {{ version }} { {{ bgp.import | default([]) | bird_import(ipv4) | indent(8) }} {% if bgp.limits.import is defined %} import limit {{ bgp.limits.import }}; {% endif %} {{ bgp.export | default([]) | bird_export(ipv4) | indent(8) }} {% if bgp.limits.export is defined %} export limit {{ bgp.limits.export }}; {% endif %} }; } {% endfor %} {% endfor %} {# {% if bird__static_unreachable | ansible.utils.ipv4 %} protocol static unreachable4 { ipv4 { import all; }; {% for route in bird__static_unreachable | ansible.utils.ipv4 %} route {{ route }} unreachable; {% endfor %} } {% endif %} {% if bird__static_unreachable | ansible.utils.ipv6 %} protocol static unreachable6 { ipv6 { import all; }; {% for route in bird__static_unreachable | ansible.utils.ipv6 %} route {{ route }} unreachable; {% endfor %} } {% endif %} #} {# {% macro bird_filter(filter, last) %} {% if filter.as_prepend is defined %} {% for _ in range(filter.as_prepend.size) %} bgp_path.prepend({{ filter.as_prepend.asn }}); {% endfor %} {% endif %} {% if filter.local_pref is defined %} bgp_local_pref = {{ filter.local_pref }}; {% endif %} {% if filter.accept is defined %} {{ filter.accept | ternary("accept", "reject") }}; {% endif %} {% endmacro %} {% for name, session in bird__bgp_sessions.items() %} {% for version in [4, 6] %} {% for direction in ["import", "export"] %} filter bgp{{ version }}_{{ direction }}_{{ name }} { {% for filter in session[direction] %} {% set negate = filter.negate | default(False) %} {% set networks = filter.prefix | default([]) | ansible.utils.ipaddr(version=version) | map("suffix", filter.sub | default(False) | ternary("+", "")) | list %} {% set bgp_protos = filter.bgp_proto | default([]) | map("format_rev", 'proto {1} "bgp{2}_{0}"', negate | ternary("!=", "="), version) | list %} {% if networks or bgp_protos %} {% if networks %} {% set op = negate | ternary("!~", "~") %} if net {{ op }} [ {{ networks | join(", ") }} ] then { {% elif bgp_protos %} {% set op = negate | ternary("&&", "||") %} if {{ bgp_protos | join(" " + op + " ") }} then { {% endif %} {{ bird_filter(filter) | indent(8) }} } {% else %} {{ bird_filter(filter) | indent(4) }} {% endif %} {% endfor %} } {% endfor %} {% endfor %} {% endfor %} {% for name, session in bird__bgp_sessions.items() %} {% for local_address in session.local.address %} {% set version = local_address | ansible.utils.ipaddr(query="version") %} {% set remote_address = session.remote.address | ansible.utils.ipaddr(version=version) | first %} protocol bgp bgp{{ version }}_{{ name }} { local {{ local_address }} as {{ session.local.as }}; neighbor {{ remote_address }} as {{ session.remote.as }}; {{ "ipv4" if version == 4 else "ipv6" }} { {% if session.next_hop_self | default(False) %} next hop self; {% endif %} {% if session.direct | default(False) %} direct; {% endif %} import filter bgp{{ version }}_import_{{ name }}; export filter bgp{{ version }}_export_{{ name }}; }; } {% endfor %} {% endfor %} {% if bird__radv_interfaces %} protocol radv { {% for name, iface in bird__radv_interfaces.items() %} interface {{ name | enquote }} { max ra interval {{ bird__radv_max_interval | int }}; {% for prefix in iface.prefix | default([]) %} prefix {{ prefix | ipaddr }}; {% endfor %} {% for domain in iface.domain_search | default([]) %} dnssl {{ domain | enquote }}; {% endfor %} }; {% endfor %} {% for address in bird__radv_dns_servers %} rdnss {{ address | ipaddr }}; {% endfor %} } {% endif %} #}