From 866f175ed23415eafe7b183b84555ea09f34da1f Mon Sep 17 00:00:00 2001 From: Jeltz Date: Sat, 3 Sep 2022 03:44:31 +0200 Subject: [PATCH 01/24] bird: add role + playbook, with support for OSPF + RAdv --- filter_plugins/enquote.py | 16 +++++ playbooks/bird.yml | 49 ++++++++++++++ roles/bird/defaults/main.yml | 11 ++++ roles/bird/handlers/main.yml | 6 ++ roles/bird/tasks/main.yml | 21 ++++++ roles/bird/templates/bird.conf.j2 | 105 ++++++++++++++++++++++++++++++ 6 files changed, 208 insertions(+) create mode 100644 filter_plugins/enquote.py create mode 100755 playbooks/bird.yml create mode 100644 roles/bird/defaults/main.yml create mode 100644 roles/bird/handlers/main.yml create mode 100644 roles/bird/tasks/main.yml create mode 100644 roles/bird/templates/bird.conf.j2 diff --git a/filter_plugins/enquote.py b/filter_plugins/enquote.py new file mode 100644 index 0000000..576bf3f --- /dev/null +++ b/filter_plugins/enquote.py @@ -0,0 +1,16 @@ +class FilterModule: + def filters(self): + return { + "enquote": enquote, + } + + +def enquote(string, delimiter='"', escape="\\"): + translation = str.maketrans( + { + delimiter: f"{escape}{delimiter}", + escape: f"{escape}{escape}", + } + ) + escaped = string.translate(translation) + return f"{delimiter}{escaped}{delimiter}" diff --git a/playbooks/bird.yml b/playbooks/bird.yml new file mode 100755 index 0000000..f66c767 --- /dev/null +++ b/playbooks/bird.yml @@ -0,0 +1,49 @@ +#!/usr/bin/env ansible-playbook +--- +- hosts: + - isp-1.rtr.infra.auro.re + - isp-2.rtr.infra.auro.re + vars: + bird__router_ids: + isp-1.rtr.infra.auro.re: 10.136.0.1 + isp-2.rtr.infra.auro.re: 10.136.0.2 + bird__router_id: "{{ bird__router_ids[inventory_hostname] }}" + bird__ospf_broadcast_interfaces: + ens20: null + bird__ospf_stub_interfaces: + - client-0 + - client-1 + - client-2 + - client-3 + - client-4 + bird__radv_interfaces: + client-0: + prefix: + - 2a09:6841::/56 + domain_search: + - client-0.isp.auro.re + client-1: + prefix: + - 2a09:6841:0:100::/56 + domain_search: + - client-1.isp.auro.re + client-2: + prefix: + - 2a09:6841:0:200::/56 + domain_search: + - client-2.isp.auro.re + client-3: + prefix: + - 2a09:6841:0:300::/56 + domain_search: + - client-3.isp.auro.re + client-4: + prefix: + - 2a09:6841:0:400::/56 + domain_search: + - client-4.isp.auro.re + bird__radv_dns_servers: + - 2a09:6840:128::127 + roles: + - bird +... diff --git a/roles/bird/defaults/main.yml b/roles/bird/defaults/main.yml new file mode 100644 index 0000000..e053da4 --- /dev/null +++ b/roles/bird/defaults/main.yml @@ -0,0 +1,11 @@ +--- +bird__ospf_stub_interfaces: [] +bird__ospf_broadcast_interfaces: {} +bird__ospf_hello: 2 +bird__ospf_retransmit: 5 +bird__ospf_wait: 10 +bird__ospf_dead: 20 +bird__radv_interfaces: {} +bird__radv_dns_servers: [] +bird__radv_max_interval: 5 +... diff --git a/roles/bird/handlers/main.yml b/roles/bird/handlers/main.yml new file mode 100644 index 0000000..7de17ff --- /dev/null +++ b/roles/bird/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Reload bird + systemd: + name: bird.service + state: reloaded +... diff --git a/roles/bird/tasks/main.yml b/roles/bird/tasks/main.yml new file mode 100644 index 0000000..4b896ef --- /dev/null +++ b/roles/bird/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: Install bird + apt: + name: bird2 + +- name: Configure bird + template: + src: bird.conf.j2 + dest: /etc/bird/bird.conf + owner: root + group: bird + mode: u=rw,g=r,o= + notify: + - Reload bird + +- name: Enable and start bird + systemd: + name: bird.service + state: started + enabled: true +... diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 new file mode 100644 index 0000000..fa187f9 --- /dev/null +++ b/roles/bird/templates/bird.conf.j2 @@ -0,0 +1,105 @@ +{{ ansible_managed | comment }} + +log syslog all; + +router id {{ bird__router_id }}; + +protocol device { + scan time 10; +} + +protocol kernel { + ipv4 { + import all; + export all; + }; +} + +protocol kernel { + ipv6 { + import all; + export all; + }; +} + +protocol ospf v2 { + + ipv4 { + import all; + export where source = RTS_STATIC; + }; + + area 0 { +{% for name, iface in bird__ospf_broadcast_interfaces.items() %} + interface {{ name | enquote }} { + type broadcast; + hello {{ iface.hello | default(bird__ospf_hello) | int }}; + retransmit {{ iface.retransmit + | default(bird__ospf_retransmit) + | int }}; + wait {{ iface.wait | default(bird__ospf_wait) | int }}; + dead {{ iface.dead | default(bird__ospf_dead) | int }}; + }; +{% endfor %} +{% for name in bird__ospf_stub_interfaces %} + interface {{ name | enquote }} { + stub; + }; +{% endfor %} + }; + +} + +protocol ospf v3 { + + ipv6 { + import all; + export where source = RTS_STATIC; + }; + + area 0 { +{% for name, iface in bird__ospf_broadcast_interfaces.items() %} + interface {{ name | enquote }} { + type broadcast; + hello {{ iface.hello | default(bird__ospf_hello) | int }}; + retransmit {{ iface.retransmit + | default(bird__ospf_retransmit) + | int }}; + wait {{ iface.wait | default(bird__ospf_wait) | int }}; + dead {{ iface.dead | default(bird__ospf_dead) | int }}; + }; +{% endfor %} +{% for name in bird__ospf_stub_interfaces %} + interface {{ name | enquote }} { + stub; + }; +{% endfor %} + }; + +} + +{% if bird__radv_interfaces %} +protocol radv { + + ipv6 { + export all; + }; + +{% 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 %} From c7d7320367db474f98cf33065444b313c41408e6 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Sat, 3 Sep 2022 03:51:20 +0200 Subject: [PATCH 02/24] ifupdown2: configure isp-{1,2}.rtr interfaces --- playbooks/ifupdown2.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/playbooks/ifupdown2.yml b/playbooks/ifupdown2.yml index fcd816c..61a9265 100755 --- a/playbooks/ifupdown2.yml +++ b/playbooks/ifupdown2.yml @@ -115,6 +115,11 @@ - 2a09:6840:128::255/56 - 10.128.0.255/16 ens19: null + ens20: + forward: true + addresses: + - 2a09:6840:136:0:1::1/56 + - 10.136.0.1/16 clients: bridge_vlan_aware: true bridge_ports: @@ -158,6 +163,11 @@ - 2a09:6840:128::158/56 - 10.128.0.158/16 ens19: null + ens20: + forward: true + addresses: + - 2a09:6840:136:0:2::1/56 + - 10.136.0.2/16 clients: bridge_vlan_aware: true bridge_ports: From 61cdb980eaa85220a90d3507a0b9ded346d2450d Mon Sep 17 00:00:00 2001 From: Jeltz Date: Sat, 3 Sep 2022 14:09:37 +0200 Subject: [PATCH 03/24] keepalived: add minimal support for virtual_routes --- roles/keepalived/defaults/main.yml | 1 + roles/keepalived/templates/keepalived.conf.j2 | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/roles/keepalived/defaults/main.yml b/roles/keepalived/defaults/main.yml index ee034f3..4aeec8c 100644 --- a/roles/keepalived/defaults/main.yml +++ b/roles/keepalived/defaults/main.yml @@ -1,5 +1,6 @@ --- keepalived__virtual_addresses: {} +keepalived__virtual_routes: {} keepalived__notify_master: [] keepalived__notify_backup: [] keepalived__notify_fault: [] diff --git a/roles/keepalived/templates/keepalived.conf.j2 b/roles/keepalived/templates/keepalived.conf.j2 index c99ae10..dabd0e2 100644 --- a/roles/keepalived/templates/keepalived.conf.j2 +++ b/roles/keepalived/templates/keepalived.conf.j2 @@ -55,6 +55,15 @@ vrrp_instance instance_v4 { {{ address }} dev {{ dev }} {% endif %} {% endfor %} +{% endfor %} + } + virtual_routes { +{% for dev, addresses in keepalived__virtual_routes.items() %} +{% for address in addresses %} +{% if address | ansible.utils.ipv4 %} + {{ address }} dev {{ dev }} +{% endif %} +{% endfor %} {% endfor %} } {% if not (ipv4_enabled and ipv6_enabled) %} @@ -81,6 +90,15 @@ vrrp_instance instance_v6 { {{ address }} dev {{ dev }} {% endif %} {% endfor %} +{% endfor %} + } + virtual_routes { +{% for dev, addresses in keepalived__virtual_routes.items() %} +{% for address in addresses %} +{% if address | ansible.utils.ipv6 %} + {{ address }} dev {{ dev }} +{% endif %} +{% endfor %} {% endfor %} } {% if not (ipv4_enabled and ipv6_enabled) %} From b0e12b19f8d9359d7675fb458a517e65b38d56d3 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Sun, 4 Sep 2022 07:40:51 +0200 Subject: [PATCH 04/24] bird: prevent duplicate rules --- roles/bird/templates/bird.conf.j2 | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index fa187f9..a369d93 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -8,25 +8,30 @@ protocol device { scan time 10; } -protocol kernel { +protocol direct { + ipv4; + ipv6; +} + +protocol kernel kernel4 { ipv4 { import all; - export all; + export where source != RTS_DEVICE; }; } -protocol kernel { +protocol kernel kernel6 { ipv6 { import all; - export all; + export where source != RTS_DEVICE; }; } -protocol ospf v2 { +protocol ospf v2 ospf4 { ipv4 { import all; - export where source = RTS_STATIC; + export where source ~ [ RTS_STATIC, RTS_DEVICE ]; }; area 0 { @@ -50,11 +55,11 @@ protocol ospf v2 { } -protocol ospf v3 { +protocol ospf v3 ospf6 { ipv6 { import all; - export where source = RTS_STATIC; + export where source ~ [ RTS_STATIC, RTS_DEVICE ]; }; area 0 { @@ -81,10 +86,6 @@ protocol ospf v3 { {% if bird__radv_interfaces %} protocol radv { - ipv6 { - export all; - }; - {% for name, iface in bird__radv_interfaces.items() %} interface {{ name | enquote }} { max ra interval {{ bird__radv_max_interval | int }}; From 45ca2a32368e799b84de83cae8af202a44aa49e4 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Sun, 4 Sep 2022 07:41:17 +0200 Subject: [PATCH 05/24] keepalived: change global VIP + interface for VRRP adv. --- playbooks/keepalived.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/playbooks/keepalived.yml b/playbooks/keepalived.yml index e8239a1..52a3881 100755 --- a/playbooks/keepalived.yml +++ b/playbooks/keepalived.yml @@ -5,27 +5,27 @@ - isp-2.rtr.infra.auro.re vars: keepalived__virtual_router_id: 80 - keepalived__interface: ens18 + keepalived__interface: ens20 keepalived__virtual_addresses: client-0: - 100.64.0.1/27 - - 2a09:6841::/56 + - 2a09:6841::1/56 - fe80::1/10 client-1: - 100.64.0.33/27 - - 2a09:6841:0:100::/56 + - 2a09:6841:0:100::1/56 - fe80::1/10 client-2: - 100.64.0.65/27 - - 2a09:6841:0:100::/56 + - 2a09:6841:0:200::1/56 - fe80::1/10 client-3: - 100.64.0.97/27 - - 2a09:6841:0:200::/56 + - 2a09:6841:0:300::1/56 - fe80::1/10 client-4: - 100.64.0.129/27 - - 2a09:6841:0:300::/56 + - 2a09:6841:0:400::1/56 - fe80::1/10 roles: - keepalived From 8863eed9249204f3c2159f42d33a30491fade804 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 16:39:28 +0100 Subject: [PATCH 06/24] bird: add minimal BGP support --- roles/bird/defaults/main.yml | 2 + roles/bird/templates/bird.conf.j2 | 101 ++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) 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 { From 618cad720ab144b53836df191815a44ec5a4d747 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 16:51:43 +0100 Subject: [PATCH 07/24] bird: add OSPF stubnet support --- roles/bird/defaults/main.yml | 1 + roles/bird/templates/bird.conf.j2 | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/roles/bird/defaults/main.yml b/roles/bird/defaults/main.yml index 2fa912c..68e90f2 100644 --- a/roles/bird/defaults/main.yml +++ b/roles/bird/defaults/main.yml @@ -1,5 +1,6 @@ --- bird__ospf_stub_interfaces: [] +bird__ospf_stub_networks: [] bird__ospf_broadcast_interfaces: {} bird__ospf_hello: 2 bird__ospf_retransmit: 5 diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index bcb13c6..94a8cf5 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -58,6 +58,9 @@ protocol ospf v2 ospf4 { }; area 0 { +{% for network in bird__ospf_stub_networks | ansible.utils.ipv4 %} + stubnet {{ network }}; +{% endfor %} {% for name, iface in bird__ospf_broadcast_interfaces.items() %} interface {{ name | enquote }} { type broadcast; @@ -86,6 +89,9 @@ protocol ospf v3 ospf6 { }; area 0 { +{% for network in bird__ospf_stub_networks | ansible.utils.ipv6 %} + stubnet {{ network }}; +{% endfor %} {% for name, iface in bird__ospf_broadcast_interfaces.items() %} interface {{ name | enquote }} { type broadcast; From 99ba67f0742dadfe4d551af8b2cc7ac07fc0bc99 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 18:43:00 +0100 Subject: [PATCH 08/24] bird: add IPv6 support --- roles/bird/templates/bird.conf.j2 | 147 ++++++++++++++++++------------ 1 file changed, 89 insertions(+), 58 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index 94a8cf5..eeb9037 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -1,4 +1,4 @@ -{{ ansible_managed | comment }} +P{{ ansible_managed | comment }} log syslog all; @@ -113,81 +113,112 @@ 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([]) %} +{% for local_address in session.local.address %} {% - set networks = - pref.prefix - | product("+" if pref.sub else "") - | map("join") - | join(", ") + set version = + local_address + | ansible.utils.ipaddr(query="version") %} -{% set operator = '!~' if pref.negate | default(False) else '~' %} - if (net {{ operator }} [ {{ networks }} ]) then { +{% + set remote_address = + session.remote.address + | ansible.utils.ipaddr(version=version) + | first +%} +protocol bgp bgp_{{ session.name }}{{ version }} { + + local {{ local_address }} as {{ session.local.as }}; + neighbor {{ remote_address }} as {{ session.remote.as }}; + + {{ "ipv4" if version == 4 else "ipv6" }} { + + import filter { +{% for pref in session.import.local_pref | default([]) %} +{% + set networks = + pref.prefix + | default([]) + | ansible.utils.ipaddr(version=version) + | map("suffix", pref.sub + | default(False) + | ternary("+", "")) +%} +{% set operator = pref.negate | default(False) | ternary("!~", "~") %} +{% if networks %} + if net {{ operator }} [ {{ networks | join(", ") }} ] 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; +{% endif %} {% endfor %} +{% if session.import.accept == "all" %} + accept; +{% else %} +{% for accept in session.import.accept | default([]) %} +{% + set networks = + accept.prefix + | default([]) + | ansible.utils.ipaddr(version=version) + | map("suffix", accept.sub + | default(False) + | ternary("+", "")) +%} +{% set operator = accept.negate | default(False) | ternary("!~", "~") %} +{% if networks %} + if net {{ operator }} [ {{ networks | join(",") }} ] then accept; +{% endif %} +{% endfor %} reject; -{% endif %} +{% 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([]) %} +{% for prepend in session.export.as_prepend | default([]) %} {% set networks = - accept.prefix - | product("+" if accept.sub else "") - | map("join") - | join(", ") + prepend.prefix + | default([]) + | ansible.utils.ipaddr(version=version) + | map("suffix", prepend.sub + | default(False) + | ternary("+", "")) %} -{% set operator = '!~' if accept.negate | default(False) else '~' %} - if (net {{ operator }} [ {{ networks }} ]) then accept; +{% set operator = prepend.negate | default(False) | ternary("!~", "~") %} +{% if networks %} + if net {{ operator }} [ {{ networks | join(", ") }} ] then { +{% for _ in range(prepend.size) %} + bgp_path.prepend({{ session.local.as }}); +{% endfor %} + } +{% endif %} {% endfor %} +{% if session.export.accept == "all" %} + accept; +{% else %} +{% for accept in session.export.accept | default([]) %} +{% + set networks = + accept.prefix + | default([]) + | ansible.utils.ipaddr(version=version) + | map("suffix", accept.sub + | default(False) + | ternary("+", "")) +%} +{% set operator = accept.negate | default(False) | ternary("!~", "~") %} +{% if networks %} + if net {{ operator }} [ {{ networks | join(", ") }} ] then accept; +{% endif %} +{% endfor %} reject; -{% endif %} +{% endif %} }; + }; } +{% endfor %} {% endfor %} {% if bird__radv_interfaces %} From 64dcb4b28217292fe223452f4f01d6fdf1b85204 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 18:50:05 +0100 Subject: [PATCH 09/24] bird: add suffix filter --- filter_plugins/suffix.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 filter_plugins/suffix.py diff --git a/filter_plugins/suffix.py b/filter_plugins/suffix.py new file mode 100644 index 0000000..53c04ac --- /dev/null +++ b/filter_plugins/suffix.py @@ -0,0 +1,9 @@ +class FilterModule: + def filters(self): + return { + "suffix": suffix, + } + + +def suffix(value, suffix): + return value + suffix From 1c47ccc4a8a354d6465f453594676dc0c1a25705 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 19:48:22 +0100 Subject: [PATCH 10/24] bird: install prometheus-bird-exporter --- roles/bird/defaults/main.yml | 1 + roles/bird/handlers/main.yml | 6 ++++++ roles/bird/tasks/main.yml | 21 ++++++++++++++++++- .../templates/prometheus-bird-exporter.j2 | 3 +++ 4 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 roles/bird/templates/prometheus-bird-exporter.j2 diff --git a/roles/bird/defaults/main.yml b/roles/bird/defaults/main.yml index 68e90f2..1c72633 100644 --- a/roles/bird/defaults/main.yml +++ b/roles/bird/defaults/main.yml @@ -11,4 +11,5 @@ bird__radv_dns_servers: [] bird__radv_max_interval: 5 bird__static_unreachable: [] bird__bgp_sessions: [] +bird__prometheus_listen_address: 0.0.0.0:9324 ... diff --git a/roles/bird/handlers/main.yml b/roles/bird/handlers/main.yml index 7de17ff..2b17b11 100644 --- a/roles/bird/handlers/main.yml +++ b/roles/bird/handlers/main.yml @@ -3,4 +3,10 @@ systemd: name: bird.service state: reloaded + +- name: Reload prometheus-bird-exporter + systemd: + name: prometheus-bird-exporter.service + state: reloaded +... ... diff --git a/roles/bird/tasks/main.yml b/roles/bird/tasks/main.yml index 4b896ef..0f7bda1 100644 --- a/roles/bird/tasks/main.yml +++ b/roles/bird/tasks/main.yml @@ -1,7 +1,9 @@ --- - name: Install bird apt: - name: bird2 + name: + - bird2 + - prometheus-bird-exporter - name: Configure bird template: @@ -13,9 +15,26 @@ notify: - Reload bird +- name: Configure prometheus-bird-exporter + template: + src: prometheus-bird-exporter.j2 + dest: /etc/default/prometheus-bird-exporter + owner: root + group: root + mode: u=rw,g=r,o= + notify: + - Restart prometheus-bird-exporter + - name: Enable and start bird systemd: name: bird.service state: started enabled: true + +- name: Enable and start prometheus-bird-exporter + systemd: + name: prometheus-bird-exporter.service + state: started + enabled: true + ... diff --git a/roles/bird/templates/prometheus-bird-exporter.j2 b/roles/bird/templates/prometheus-bird-exporter.j2 new file mode 100644 index 0000000..86006b0 --- /dev/null +++ b/roles/bird/templates/prometheus-bird-exporter.j2 @@ -0,0 +1,3 @@ +{{ ansible_managed | comment }} + +ARGS="-format.new -bird.v2 -web.listen-address {{ bird__prometheus_listen_address }}" From aac915128051326776a4752ad1a52f622f186de4 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 19:49:46 +0100 Subject: [PATCH 11/24] bird: restart prometheus-bird-exporter reload is not supported by the service --- roles/bird/handlers/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/bird/handlers/main.yml b/roles/bird/handlers/main.yml index 2b17b11..51a9c2e 100644 --- a/roles/bird/handlers/main.yml +++ b/roles/bird/handlers/main.yml @@ -7,6 +7,6 @@ - name: Reload prometheus-bird-exporter systemd: name: prometheus-bird-exporter.service - state: reloaded + state: restarted ... ... From ea78f609b539a955789684311ebaad5e22088748 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 19:53:40 +0100 Subject: [PATCH 12/24] bird: indent with spaces --- roles/bird/templates/bird.conf.j2 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index eeb9037..b308bb8 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -30,22 +30,22 @@ protocol kernel kernel6 { {% if bird__static_unreachable | ansible.utils.ipv4 %} protocol static unreachable4 { - ipv4 { - export all; - }; + ipv4 { + export all; + }; {% for route in bird__static_unreachable | ansible.utils.ipv4 %} - route {{ route }} unreachable; + route {{ route }} unreachable; {% endfor %} } {% endif %} {% if bird__static_unreachable | ansible.utils.ipv6 %} protocol static unreachable6 { - ipv6 { - export all; - }; + ipv6 { + export all; + }; {% for route in bird__static_unreachable | ansible.utils.ipv6 %} - route {{ route }} unreachable; + route {{ route }} unreachable; {% endfor %} } {% endif %} From a670cbaba483b10b0c1acb9eb0bd957281f4fb30 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 21:01:47 +0100 Subject: [PATCH 13/24] bird: typos --- roles/bird/handlers/main.yml | 3 +-- roles/bird/templates/bird.conf.j2 | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/roles/bird/handlers/main.yml b/roles/bird/handlers/main.yml index 51a9c2e..8b3f2a0 100644 --- a/roles/bird/handlers/main.yml +++ b/roles/bird/handlers/main.yml @@ -4,9 +4,8 @@ name: bird.service state: reloaded -- name: Reload prometheus-bird-exporter +- name: Restart prometheus-bird-exporter systemd: name: prometheus-bird-exporter.service state: restarted ... -... diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index b308bb8..1439f4b 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -1,4 +1,4 @@ -P{{ ansible_managed | comment }} +{{ ansible_managed | comment }} log syslog all; From 412a63dc6cab1626cef0b48c8fa40340522c0029 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Wed, 21 Dec 2022 21:02:12 +0100 Subject: [PATCH 14/24] playbooks: add edge-{1,2} --- hosts | 2 + playbooks/bird.yml | 91 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/hosts b/hosts index 52f5078..90917a4 100644 --- a/hosts +++ b/hosts @@ -96,6 +96,8 @@ radius-fleming.adm.auro.re dns-1.int.infra.auro.re isp-1.rtr.infra.auro.re isp-2.rtr.infra.auro.re +edge-1.rtr.infra.auro.re +edge-2.rtr.infra.auro.re dhcp-1.isp.auro.re dhcp-2.isp.auro.re radius-fleming-backup.adm.auro.re diff --git a/playbooks/bird.yml b/playbooks/bird.yml index f66c767..6c3d300 100755 --- a/playbooks/bird.yml +++ b/playbooks/bird.yml @@ -46,4 +46,95 @@ - 2a09:6840:128::127 roles: - bird + + +- hosts: + - edge-1.rtr.infra.auro.re + - edge-2.rtr.infra.auro.re + vars: + bird__router_ids: + edge-1.rtr.infra.auro.re: 10.136.1.1 + edge-2.rtr.infra.auro.re: 10.136.1.2 + bird__asn: + aurore: 43619 + crans: 204515 + zayo: 8218 + viarezo: 212424 + bird__orig_prefixes: + aurore: + - 45.66.108.0/22 + - 2a09:6840::/29 + crans: + - 185.230.76.0/22 + - 2a0c:700::/32 + viarezo: + - 138.195.144.0/20 + - 192.159.121.0/24 + - 2a0c:b641:2f0::/44 + bird__router_id: "{{ bird__router_ids[inventory_hostname] }}" + bird__bgp_sessions: + - name: zayo + local: + address: + - 83.167.52.69 + - 2001:1b48:2:103::d7:2 + as: "{{ bird__asn.aurore }}" + remote: + address: + - 83.167.52.68 + - 2001:1b48:2:103::d7:1 + as: "{{ bird__asn.zayo }}" + import: + accept: all + export: + accept: + - prefix: "{{ ['aurore', 'crans', 'viarezo'] + | map('extract', bird__orig_prefixes) + | flatten }}" + sub: true + - name: crans + local: + address: + - 185.230.79.254 + - 2a0c:700:28::2 + as: "{{ bird__asn.aurore }}" + remote: + address: + - 185.230.79.253 + - 2a0c:700:28::1 + as: "{{ bird__asn.crans }}" + import: + accept: + - prefix: "{{ bird__orig_prefixes.crans }}" + sub: true + export: + accept: all + - name: viarezo + local: + address: + - 192.159.121.134 + - 2a0c:b641:2ff::6 + as: "{{ bird__asn.aurore }}" + remote: + address: + - 192.159.121.133 + - 2a0c:b641:2ff::5 + as: "{{ bird__asn.viarezo }}" + import: + local_pref: + - prefix: "{{ bird__orig_prefixes.viarezo }}" + sub: true + negate: true + pref: 50 + accept: all + export: + as_prepend: + - prefix: "{{ bird__orig_prefixes.aurore }}" + size: 3 + accept: all + bird__static_unreachable: + - 45.66.108.0/22 + - 2a09:6840::/29 + roles: + - bird ... From f43775fc02f5abb1340734ce4c2e9d4da5dcd901 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 10:48:52 +0100 Subject: [PATCH 15/24] bird: don't export static routes to kernel --- roles/bird/templates/bird.conf.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index 1439f4b..9ee2070 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -16,14 +16,14 @@ protocol direct { protocol kernel kernel4 { ipv4 { import all; - export where source != RTS_DEVICE; + export where source !~ [ RTS_DEVICE, RTS_STATIC ]; }; } protocol kernel kernel6 { ipv6 { import all; - export where source != RTS_DEVICE; + export where source !~ [ RTS_DEVICE, RTS_STATIC ]; }; } From b9fb9f377fd8e53030e81ed3d9dc125733048519 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 10:50:51 +0100 Subject: [PATCH 16/24] bird: remove unused OSPF protocol instances --- roles/bird/templates/bird.conf.j2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index 9ee2070..41a4cf8 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -50,6 +50,7 @@ protocol static unreachable6 { } {% endif %} +{% if bird__ospf_broadcast_interfaces %} protocol ospf v2 ospf4 { ipv4 { @@ -80,7 +81,9 @@ protocol ospf v2 ospf4 { }; } +{% endif %} +{% if bird__ospf_broadcast_interfaces %} protocol ospf v3 ospf6 { ipv6 { @@ -111,6 +114,8 @@ protocol ospf v3 ospf6 { }; } +{% endif %} + {% for session in bird__bgp_sessions %} {% for local_address in session.local.address %} From cc82841560dcafdbb494683e1a947da360e38d4b Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 11:00:37 +0100 Subject: [PATCH 17/24] bird: typos --- roles/bird/templates/bird.conf.j2 | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index 41a4cf8..da0c09c 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -31,7 +31,7 @@ protocol kernel kernel6 { {% if bird__static_unreachable | ansible.utils.ipv4 %} protocol static unreachable4 { ipv4 { - export all; + import all; }; {% for route in bird__static_unreachable | ansible.utils.ipv4 %} route {{ route }} unreachable; @@ -42,7 +42,7 @@ protocol static unreachable4 { {% if bird__static_unreachable | ansible.utils.ipv6 %} protocol static unreachable6 { ipv6 { - export all; + import all; }; {% for route in bird__static_unreachable | ansible.utils.ipv6 %} route {{ route }} unreachable; @@ -59,10 +59,10 @@ protocol ospf v2 ospf4 { }; area 0 { -{% for network in bird__ospf_stub_networks | ansible.utils.ipv4 %} +{% for network in bird__ospf_stub_networks | ansible.utils.ipv4 %} stubnet {{ network }}; -{% endfor %} -{% for name, iface in bird__ospf_broadcast_interfaces.items() %} +{% endfor %} +{% for name, iface in bird__ospf_broadcast_interfaces.items() %} interface {{ name | enquote }} { type broadcast; hello {{ iface.hello | default(bird__ospf_hello) | int }}; @@ -72,12 +72,12 @@ protocol ospf v2 ospf4 { wait {{ iface.wait | default(bird__ospf_wait) | int }}; dead {{ iface.dead | default(bird__ospf_dead) | int }}; }; -{% endfor %} -{% for name in bird__ospf_stub_interfaces %} +{% endfor %} +{% for name in bird__ospf_stub_interfaces %} interface {{ name | enquote }} { stub; }; -{% endfor %} +{% endfor %} }; } @@ -92,10 +92,10 @@ protocol ospf v3 ospf6 { }; area 0 { -{% for network in bird__ospf_stub_networks | ansible.utils.ipv6 %} +{% for network in bird__ospf_stub_networks | ansible.utils.ipv6 %} stubnet {{ network }}; -{% endfor %} -{% for name, iface in bird__ospf_broadcast_interfaces.items() %} +{% endfor %} +{% for name, iface in bird__ospf_broadcast_interfaces.items() %} interface {{ name | enquote }} { type broadcast; hello {{ iface.hello | default(bird__ospf_hello) | int }}; @@ -105,8 +105,8 @@ protocol ospf v3 ospf6 { wait {{ iface.wait | default(bird__ospf_wait) | int }}; dead {{ iface.dead | default(bird__ospf_dead) | int }}; }; -{% endfor %} -{% for name in bird__ospf_stub_interfaces %} +{% endfor %} +{% for name in bird__ospf_stub_interfaces %} interface {{ name | enquote }} { stub; }; @@ -130,7 +130,7 @@ protocol ospf v3 ospf6 { | ansible.utils.ipaddr(version=version) | first %} -protocol bgp bgp_{{ session.name }}{{ version }} { +protocol bgp bgp{{ version }}_{{ session.name }} { local {{ local_address }} as {{ session.local.as }}; neighbor {{ remote_address }} as {{ session.remote.as }}; From 6773c5e90dbb9a420366d759648b5898ad551838 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 12:02:56 +0100 Subject: [PATCH 18/24] bird: cleanup + bogons filtering --- playbooks/bird.yml | 67 ++++++++---- roles/bird/templates/bird.conf.j2 | 174 ++++++++++++------------------ 2 files changed, 115 insertions(+), 126 deletions(-) diff --git a/playbooks/bird.yml b/playbooks/bird.yml index 6c3d300..09c10e6 100755 --- a/playbooks/bird.yml +++ b/playbooks/bird.yml @@ -71,6 +71,31 @@ - 138.195.144.0/20 - 192.159.121.0/24 - 2a0c:b641:2f0::/44 + martians: + - 10.0.0.0/8 + - 172.16.0.0/12 + - 192.168.0.0/16 + - 100.64.0.0/10 + - 127.0.0.0/8 + - 169.254.0.0/16 + - 192.0.0.0/24 + - 192.0.2.0/24 + - 198.18.0.0/15 + - 198.51.100.0/24 + - 203.0.113.0/24 + - 224.0.0.0/4 + - 240.0.0.0/4 + - ::/128 + - ::1/128 + - ::ffff:0:0/96 + - ::/96 + - 100::/64 + - 2001:10::/28 + - 2001:db8::/32 + - fc00::/7 + - fe80::/10 + - fec0::/10 + - ff00::/8 bird__router_id: "{{ bird__router_ids[inventory_hostname] }}" bird__bgp_sessions: - name: zayo @@ -85,13 +110,14 @@ - 2001:1b48:2:103::d7:1 as: "{{ bird__asn.zayo }}" import: - accept: all + - accept: true export: - accept: - - prefix: "{{ ['aurore', 'crans', 'viarezo'] - | map('extract', bird__orig_prefixes) - | flatten }}" - sub: true + - prefix: "{{ ['aurore', 'crans', 'viarezo'] + | map('extract', bird__orig_prefixes) + | flatten }}" + sub: true + accept: true + - accept: false - name: crans local: address: @@ -104,11 +130,12 @@ - 2a0c:700:28::1 as: "{{ bird__asn.crans }}" import: - accept: - - prefix: "{{ bird__orig_prefixes.crans }}" - sub: true + - prefix: "{{ bird__orig_prefixes.crans }}" + sub: true + accept: true + - accept: false export: - accept: all + - accept: true - name: viarezo local: address: @@ -121,17 +148,19 @@ - 2a0c:b641:2ff::5 as: "{{ bird__asn.viarezo }}" import: - local_pref: - - prefix: "{{ bird__orig_prefixes.viarezo }}" - sub: true - negate: true - pref: 50 - accept: all + - prefix: "{{ bird__orig_prefixes.martians }}" + accept: false + - prefix: "{{ bird__orig_prefixes.viarezo }}" + sub: true + negate: true + local_pref: 50 + - accept: true export: - as_prepend: - - prefix: "{{ bird__orig_prefixes.aurore }}" + - prefix: "{{ bird__orig_prefixes.aurore }}" + as_prepend: + asn: "{{ bird__asn.aurore }}" size: 3 - accept: all + - accept: true bird__static_unreachable: - 45.66.108.0/22 - 2a09:6840::/29 diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index da0c09c..a4ae065 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -59,10 +59,10 @@ protocol ospf v2 ospf4 { }; area 0 { -{% for network in bird__ospf_stub_networks | ansible.utils.ipv4 %} +{% for network in bird__ospf_stub_networks | ansible.utils.ipv4 %} stubnet {{ network }}; -{% endfor %} -{% for name, iface in bird__ospf_broadcast_interfaces.items() %} +{% endfor %} +{% for name, iface in bird__ospf_broadcast_interfaces.items() %} interface {{ name | enquote }} { type broadcast; hello {{ iface.hello | default(bird__ospf_hello) | int }}; @@ -72,12 +72,12 @@ protocol ospf v2 ospf4 { wait {{ iface.wait | default(bird__ospf_wait) | int }}; dead {{ iface.dead | default(bird__ospf_dead) | int }}; }; -{% endfor %} -{% for name in bird__ospf_stub_interfaces %} +{% endfor %} +{% for name in bird__ospf_stub_interfaces %} interface {{ name | enquote }} { stub; }; -{% endfor %} +{% endfor %} }; } @@ -92,10 +92,10 @@ protocol ospf v3 ospf6 { }; area 0 { -{% for network in bird__ospf_stub_networks | ansible.utils.ipv6 %} +{% for network in bird__ospf_stub_networks | ansible.utils.ipv6 %} stubnet {{ network }}; -{% endfor %} -{% for name, iface in bird__ospf_broadcast_interfaces.items() %} +{% endfor %} +{% for name, iface in bird__ospf_broadcast_interfaces.items() %} interface {{ name | enquote }} { type broadcast; hello {{ iface.hello | default(bird__ospf_hello) | int }}; @@ -105,8 +105,8 @@ protocol ospf v3 ospf6 { wait {{ iface.wait | default(bird__ospf_wait) | int }}; dead {{ iface.dead | default(bird__ospf_dead) | int }}; }; -{% endfor %} -{% for name in bird__ospf_stub_interfaces %} +{% endfor %} +{% for name in bird__ospf_stub_interfaces %} interface {{ name | enquote }} { stub; }; @@ -116,114 +116,74 @@ protocol ospf v3 ospf6 { } {% endif %} +{% macro bird_filter_function(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 %} +return {{ filter.accept | ternary("true", "false") }}; +{% endif %} +{% endmacro %} {% for session in bird__bgp_sessions %} -{% 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 -%} +{% for version in [4, 6] %} +{% for direction in ["import", "export"] %} +function bgp{{ version }}_{{ direction }}_{{ session.name }}() { +{% for filter in session[direction] %} +{% if filter.prefix | default([]) %} +{% set op = + filter.negate + | default(False) + | ternary("!~", "~") %} +{% set networks = + filter.prefix + | default([]) + | ansible.utils.ipaddr(version=version) + | map("suffix", filter.sub + | default(False) + | ternary("+", "")) %} +{% if networks %} + if net {{ op }} [ {{ networks | join(", ") }} ] then { + {{ bird_filter_function(filter) | indent(8) }} + } +{% endif %} +{% else %} + {{ bird_filter_function(filter) | indent(4) }} +{% endif %} +{% endfor %} +} +{% endfor %} +{% endfor %} + +{% endfor %} + +{% for session in bird__bgp_sessions %} +{% 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 }}_{{ session.name }} { local {{ local_address }} as {{ session.local.as }}; neighbor {{ remote_address }} as {{ session.remote.as }}; {{ "ipv4" if version == 4 else "ipv6" }} { - - import filter { -{% for pref in session.import.local_pref | default([]) %} -{% - set networks = - pref.prefix - | default([]) - | ansible.utils.ipaddr(version=version) - | map("suffix", pref.sub - | default(False) - | ternary("+", "")) -%} -{% set operator = pref.negate | default(False) | ternary("!~", "~") %} -{% if networks %} - if net {{ operator }} [ {{ networks | join(", ") }} ] then { - bgp_local_pref = {{ pref.pref | int }}; - } -{% endif %} -{% endfor %} -{% if session.import.accept == "all" %} - accept; -{% else %} -{% for accept in session.import.accept | default([]) %} -{% - set networks = - accept.prefix - | default([]) - | ansible.utils.ipaddr(version=version) - | map("suffix", accept.sub - | default(False) - | ternary("+", "")) -%} -{% set operator = accept.negate | default(False) | ternary("!~", "~") %} -{% if networks %} - if net {{ operator }} [ {{ networks | join(",") }} ] then accept; -{% endif %} -{% endfor %} - reject; -{% endif %} - }; - - export filter { -{% for prepend in session.export.as_prepend | default([]) %} -{% - set networks = - prepend.prefix - | default([]) - | ansible.utils.ipaddr(version=version) - | map("suffix", prepend.sub - | default(False) - | ternary("+", "")) -%} -{% set operator = prepend.negate | default(False) | ternary("!~", "~") %} -{% if networks %} - if net {{ operator }} [ {{ networks | join(", ") }} ] then { -{% for _ in range(prepend.size) %} - bgp_path.prepend({{ session.local.as }}); -{% endfor %} - } -{% endif %} -{% endfor %} -{% if session.export.accept == "all" %} - accept; -{% else %} -{% for accept in session.export.accept | default([]) %} -{% - set networks = - accept.prefix - | default([]) - | ansible.utils.ipaddr(version=version) - | map("suffix", accept.sub - | default(False) - | ternary("+", "")) -%} -{% set operator = accept.negate | default(False) | ternary("!~", "~") %} -{% if networks %} - if net {{ operator }} [ {{ networks | join(", ") }} ] then accept; -{% endif %} -{% endfor %} - reject; -{% endif %} - }; - + import where bgp{{ version }}_import_{{ session.name }}(); + export where bgp{{ version }}_export_{{ session.name }}(); }; } -{% endfor %} +{% endfor %} {% endfor %} {% if bird__radv_interfaces %} From ac9947c50f3b17db8b61458d84489ad3c52b5707 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 12:12:01 +0100 Subject: [PATCH 19/24] bird: function -> filter --- roles/bird/templates/bird.conf.j2 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index a4ae065..f77ebe5 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -116,7 +116,7 @@ protocol ospf v3 ospf6 { } {% endif %} -{% macro bird_filter_function(filter, last) %} +{% 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 }}); @@ -133,7 +133,7 @@ return {{ filter.accept | ternary("true", "false") }}; {% for session in bird__bgp_sessions %} {% for version in [4, 6] %} {% for direction in ["import", "export"] %} -function bgp{{ version }}_{{ direction }}_{{ session.name }}() { +filter bgp{{ version }}_{{ direction }}_{{ session.name }} { {% for filter in session[direction] %} {% if filter.prefix | default([]) %} {% set op = @@ -149,11 +149,11 @@ function bgp{{ version }}_{{ direction }}_{{ session.name }}() { | ternary("+", "")) %} {% if networks %} if net {{ op }} [ {{ networks | join(", ") }} ] then { - {{ bird_filter_function(filter) | indent(8) }} + {{ bird_filter(filter) | indent(8) }} } {% endif %} {% else %} - {{ bird_filter_function(filter) | indent(4) }} + {{ bird_filter(filter) | indent(4) }} {% endif %} {% endfor %} } @@ -177,8 +177,8 @@ protocol bgp bgp{{ version }}_{{ session.name }} { neighbor {{ remote_address }} as {{ session.remote.as }}; {{ "ipv4" if version == 4 else "ipv6" }} { - import where bgp{{ version }}_import_{{ session.name }}(); - export where bgp{{ version }}_export_{{ session.name }}(); + import filter bgp{{ version }}_import_{{ session.name }}; + export filter bgp{{ version }}_export_{{ session.name }}; }; } From 2db69a8f1c3de410e306b80482744709c7c818b2 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 12:35:32 +0100 Subject: [PATCH 20/24] bird: return -> accept/reject --- roles/bird/templates/bird.conf.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index f77ebe5..92a8708 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -126,7 +126,7 @@ bgp_path.prepend({{ filter.as_prepend.asn }}); bgp_local_pref = {{ filter.local_pref }}; {% endif %} {% if filter.accept is defined %} -return {{ filter.accept | ternary("true", "false") }}; +{{ filter.accept | ternary("accept", "reject") }}; {% endif %} {% endmacro %} From 0a0fc8e52cd25f37595b022f30aeb556e2be80b9 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 13:12:24 +0100 Subject: [PATCH 21/24] bird: typos --- roles/bird/templates/bird.conf.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/bird/templates/bird.conf.j2 b/roles/bird/templates/bird.conf.j2 index 92a8708..c7e30ef 100644 --- a/roles/bird/templates/bird.conf.j2 +++ b/roles/bird/templates/bird.conf.j2 @@ -128,7 +128,7 @@ bgp_local_pref = {{ filter.local_pref }}; {% if filter.accept is defined %} {{ filter.accept | ternary("accept", "reject") }}; {% endif %} -{% endmacro %} +{% endmacro %} {% for session in bird__bgp_sessions %} {% for version in [4, 6] %} @@ -157,9 +157,9 @@ filter bgp{{ version }}_{{ direction }}_{{ session.name }} { {% endif %} {% endfor %} } -{% endfor %} -{% endfor %} +{% endfor %} +{% endfor %} {% endfor %} {% for session in bird__bgp_sessions %} From 9cd983aa4ca597cef7243f1fb16a796ad97e74a4 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 14:40:53 +0100 Subject: [PATCH 22/24] playbooks: add edge-{1,2}.rtr.infra.auro.re --- playbooks/bird.yml | 5 +++++ playbooks/ifupdown2.yml | 34 ++++++++++++++++++++++++++++++++++ playbooks/keepalived.yml | 22 ++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/playbooks/bird.yml b/playbooks/bird.yml index 09c10e6..4af77f0 100755 --- a/playbooks/bird.yml +++ b/playbooks/bird.yml @@ -97,6 +97,11 @@ - fec0::/10 - ff00::/8 bird__router_id: "{{ bird__router_ids[inventory_hostname] }}" + bird__ospf_broadcast_interfaces: + ens22: null + bird__ospf_stub_networks: + - 0.0.0.0/0 + - ::/0 bird__bgp_sessions: - name: zayo local: diff --git a/playbooks/ifupdown2.yml b/playbooks/ifupdown2.yml index 61a9265..49e0d00 100755 --- a/playbooks/ifupdown2.yml +++ b/playbooks/ifupdown2.yml @@ -7,6 +7,8 @@ - dhcp-2.isp.auro.re - isp-1.rtr.infra.auro.re - isp-2.rtr.infra.auro.re + - edge-1.rtr.infra.auro.re + - edge-2.rtr.infra.auro.re vars: # TODO: netbox ifupdown2__hosts: @@ -199,6 +201,36 @@ vlan_id: 1004 vlan_raw_device: clients ipv6_addrgen: false + edge-1.rtr.infra.auro.re: + ens18: + gateways: + - 2a09:6840:128::254 + - 10.128.0.254 + addresses: + - 2a09:6840:128::186/56 + - 10.128.0.186/16 + ens19: null # crans + ens20: null # vr + ens21: null # zayo + ens22: # backbone + addresses: + - 2a09:6840:203:1:1::/64 + - 10.203.1.1/16 + edge-2.rtr.infra.auro.re: + ens18: + gateways: + - 2a09:6840:128::254 + - 10.128.0.254 + addresses: + - 2a09:6840:128::228/56 + - 10.128.0.228/16 + ens19: null # crans + ens20: null # vr + ens21: null # zayo + ens22: # backbone + addresses: + - 2a09:6840:203:1:2::/64 + - 10.203.1.2/16 ifupdown2__interfaces: "{{ ifupdown2__hosts[inventory_hostname] }}" roles: - ifupdown2 @@ -210,6 +242,8 @@ - dhcp-2.isp.auro.re - isp-1.rtr.infra.auro.re - isp-2.rtr.infra.auro.re + - edge-1.rtr.infra.auro.re + - edge-2.rtr.infra.auro.re vars: resolvconf__nameservers: - 2a09:6840:128::127 diff --git a/playbooks/keepalived.yml b/playbooks/keepalived.yml index 52a3881..5f90142 100755 --- a/playbooks/keepalived.yml +++ b/playbooks/keepalived.yml @@ -29,4 +29,26 @@ - fe80::1/10 roles: - keepalived + +- hosts: + - edge-1.rtr.infra.auro.re + - edge-2.rtr.infra.auro.re + vars: + keepalived__virtual_router_id: 81 + keepalived__interface: ens22 + keepalived__virtual_addresses: + ens19: + - 185.230.79.254/29 + - 2a0c:700:28::2/64 + - fe80::1/10 + ens20: + - 192.159.121.134/30 + - 2a0c:b641:2ff::6/126 + - fe80::1/10 + ens21: + - 83.167.52.69/31 + - 2001:1b48:2:103::d7:2/126 + - fe80::1/10 + roles: + - keepalived ... From d653432d18374bbbd5f30c3ff783865a47c890c5 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 15:45:07 +0100 Subject: [PATCH 23/24] playbooks: add infra-{1,2}.rtr --- hosts | 2 ++ playbooks/ifupdown2.yml | 60 ++++++++++++++++++++++++++++++++++++++-- playbooks/keepalived.yml | 38 +++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/hosts b/hosts index 90917a4..4137022 100644 --- a/hosts +++ b/hosts @@ -98,6 +98,8 @@ isp-1.rtr.infra.auro.re isp-2.rtr.infra.auro.re edge-1.rtr.infra.auro.re edge-2.rtr.infra.auro.re +infra-1.rtr.infra.auro.re +infra-2.rtr.infra.auro.re dhcp-1.isp.auro.re dhcp-2.isp.auro.re radius-fleming-backup.adm.auro.re diff --git a/playbooks/ifupdown2.yml b/playbooks/ifupdown2.yml index 49e0d00..716458a 100755 --- a/playbooks/ifupdown2.yml +++ b/playbooks/ifupdown2.yml @@ -9,6 +9,8 @@ - isp-2.rtr.infra.auro.re - edge-1.rtr.infra.auro.re - edge-2.rtr.infra.auro.re + - infra-1.rtr.infra.auro.re + - infra-2.rtr.infra.auro.re vars: # TODO: netbox ifupdown2__hosts: @@ -214,7 +216,7 @@ ens21: null # zayo ens22: # backbone addresses: - - 2a09:6840:203:1:1::/64 + - 2a09:6840:203:1:1::1/64 - 10.203.1.1/16 edge-2.rtr.infra.auro.re: ens18: @@ -229,8 +231,60 @@ ens21: null # zayo ens22: # backbone addresses: - - 2a09:6840:203:1:2::/64 + - 2a09:6840:203:1:2::1/64 - 10.203.1.2/16 + infra-1.rtr.infra.auro.re: + ens18: + gateways: + - 2a09:6840:128::254 + - 10.128.0.254 + addresses: + - 2a09:6840:128::2:76/56 + - 10.128.2.76/16 + ens19: + addresses: + - 2a09:6840:1:3::1/64 + - 10.203.1.3/16 + ens20: + ipv6_addrgen: false + ens21: + ipv6_addrgen: false + ens22: + ipv6_addrgen: false + ens23: + ipv6_addrgen: false + ens1: + ipv6_addrgen: false + ens2: + ipv6_addrgen: false + enp1s3: + ipv6_addrgen: false + infra-2.rtr.infra.auro.re: + ens18: + gateways: + - 2a09:6840:128::254 + - 10.128.0.254 + addresses: + - 2a09:6840:128::2:27/56 + - 10.128.2.27/16 + ens19: + addresses: + - 2a09:6840:1:4::1/64 + - 10.203.1.4/16 + ens20: + ipv6_addrgen: false + ens21: + ipv6_addrgen: false + ens22: + ipv6_addrgen: false + ens23: + ipv6_addrgen: false + ens1: + ipv6_addrgen: false + ens2: + ipv6_addrgen: false + enp1s3: + ipv6_addrgen: false ifupdown2__interfaces: "{{ ifupdown2__hosts[inventory_hostname] }}" roles: - ifupdown2 @@ -244,6 +298,8 @@ - isp-2.rtr.infra.auro.re - edge-1.rtr.infra.auro.re - edge-2.rtr.infra.auro.re + - infra-1.rtr.infra.auro.re + - infra-2.rtr.infra.auro.re vars: resolvconf__nameservers: - 2a09:6840:128::127 diff --git a/playbooks/keepalived.yml b/playbooks/keepalived.yml index 5f90142..044b01b 100755 --- a/playbooks/keepalived.yml +++ b/playbooks/keepalived.yml @@ -51,4 +51,42 @@ - fe80::1/10 roles: - keepalived + +- hosts: + - infra-1.rtr.infra.auro.re + - infra-2.rtr.infra.auro.re + vars: + keepalived__virtual_router_id: 82 + keepalived__interface: ens19 + keepalived__virtual_addresses: + ens20: + - 10.204.0.1/16 + - 2a09:6840:204::1/64 + - fe80::1/10 + ens21: + - 10.205.0.1/16 + - 2a09:6840:205::1/64 + - fe80::1/10 + ens22: + - 10.206.0.1/16 + - 2a09:6840:206::1/64 + - fe80::1/10 + ens23: + - 10.207.0.1/16 + - 2a09:6840:207::1/64 + - fe80::1/10 + ens1: + - 10.208.0.1/16 + - 2a09:6840:208::1/64 + - fe80::1/10 + ens2: + - 10.209.0.1/16 + - 2a09:6840:209::1/64 + - fe80::1/10 + enp1s3: + - 10.210.0.1/16 + - 2a09:6840:210::1/64 + - fe80::1/10 + roles: + - keepalived ... From 5c17bc966408c380540c3fde989f9f203037cbf6 Mon Sep 17 00:00:00 2001 From: Jeltz Date: Thu, 22 Dec 2022 15:56:52 +0100 Subject: [PATCH 24/24] WIP: playbooks: OSPF config for infra-{1,2} --- playbooks/bird.yml | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/playbooks/bird.yml b/playbooks/bird.yml index 4af77f0..e7991df 100755 --- a/playbooks/bird.yml +++ b/playbooks/bird.yml @@ -47,14 +47,34 @@ roles: - bird +- hosts: + - infra-1.rtr.infra.auro.re + - infra-2.rtr.infra.auro.re + vars: + bird__router_ids: + infra-1.rtr.infra.auro.re: 10.203.1.3 + infra-2.rtr.infra.auro.re: 10.203.1.4 + bird__router_id: "{{ bird__router_ids[inventory_hostname] }}" + bird__ospf_broadcast_interfaces: + ens19: null + bird__ospf_stub_interfaces: + - ens20 + - ens21 + - ens22 + - ens23 + - ens1 + - ens2 + - ens1s3 + roles: + - bird - hosts: - edge-1.rtr.infra.auro.re - edge-2.rtr.infra.auro.re vars: bird__router_ids: - edge-1.rtr.infra.auro.re: 10.136.1.1 - edge-2.rtr.infra.auro.re: 10.136.1.2 + edge-1.rtr.infra.auro.re: 10.203.1.1 + edge-2.rtr.infra.auro.re: 10.203.1.2 bird__asn: aurore: 43619 crans: 204515