diff --git a/roles/bird/defaults/main.yml b/roles/bird/defaults/main.yml index e053da4..2fa912c 100644 --- a/roles/bird/defaults/main.yml +++ b/roles/bird/defaults/main.yml @@ -8,4 +8,6 @@ bird__ospf_dead: 20 bird__radv_interfaces: {} bird__radv_dns_servers: [] bird__radv_max_interval: 5 +bird__static_unreachable: [] +bird__bgp_sessions: [] ... diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index a369d93..bcb13c6 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -27,6 +27,29 @@ protocol kernel kernel6 { }; } + +{% if bird__static_unreachable | ansible.utils.ipv4 %} +protocol static unreachable4 { + ipv4 { + export 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 { + export all; + }; +{% for route in bird__static_unreachable | ansible.utils.ipv6 %} + route {{ route }} unreachable; +{% endfor %} +} +{% endif %} + protocol ospf v2 ospf4 { ipv4 { @@ -83,6 +106,84 @@ protocol ospf v3 ospf6 { } +{% for session in bird__bgp_sessions %} +protocol bgp {{ session.name }} { + + local as {{ session.local.as }}; + source address {{ session.local.address }}; + neighbor {{ session.remote.address }} as {{ session.remote.as }}; + + ipv4 { + import filter { +{% for pref in session.import.local_pref | default([]) %} +{% + set networks = + pref.prefix + | product("+" if pref.sub else "") + | map("join") + | join(", ") +%} +{% set operator = '!~' if pref.negate | default(False) else '~' %} + if (net {{ operator }} [ {{ networks }} ]) then { + bgp_local_pref = {{ pref.pref | int }}; + } +{% endfor %} +{% if session.import.accept == "all" %} + accept; +{% else %} +{% for accept in session.import.accept | default([]) %} +{% + set networks = + accept.prefix + | product("+" if accept.sub else "") + | map("join") + | join(", ") +%} +{% set operator = '!~' if accept.negate | default(False) else '~' %} + if (net {{ operator }} [ {{ networks }} ]) then accept; +{% endfor %} + reject; +{% endif %} + }; + export filter { +{% for prepend in session.export.as_prepend | default([]) %} +{% + set networks = + prepend.prefix + | product("+" if prepend.sub else "") + | map("join") + | join(", ") +%} +{% set operator = '!~' if prepend.negate | default(False) else '~' %} + if (net {{ operator }} [ {{ networks }} ]) then { +{% for _ in range(prepend.size) %} + bgp_path.prepend({{ session.local.as }}); +{% endfor %} + } +{% endfor %} +{% if session.export.accept == "all" %} + accept; +{% else %} +{% for accept in session.export.accept | default([]) %} +{% + set networks = + accept.prefix + | product("+" if accept.sub else "") + | map("join") + | join(", ") +%} +{% set operator = '!~' if accept.negate | default(False) else '~' %} + if (net {{ operator }} [ {{ networks }} ]) then accept; +{% endfor %} + reject; +{% endif %} + }; + }; + +} + +{% endfor %} + {% if bird__radv_interfaces %} protocol radv {