Ansible role for the Bird 2.x routing policy used in routing-rocks (AS202739), Freifunk Essen (AS206356), etc.
Bird 2.x routing policy used in routing-rocks (AS202739), Freifunk Essen (AS206356), etc.
In this example I will give a brief example how a policy inventory could look like. This is an short example which was derived from the actual routing policy of the ASes running this policy.
Given the following situation:
This bird configuration can also be used inside of NixOS.
The module enables and configures services.bird2
building and packaging the bird configuration by running ansible when running nixos-rebuild
.
The NixOS module can be imported using flakes.
{
inputs = {
routing-rocks-policy.url = "github:czerwonk/routing-rocks-policy-role";
};
outputs = { self, nixpkgs, routing-rocks-policy, ... }:
{
nixosConfigurations.my-router = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
routing-rocks-policy.nixosModule
{
routing-rocks.bird2 = {
enable = true;
configYML = ''
... put your config here or read it from filesystem (e.g. using builtins.readFile) ...
'';
asSets = ''
define AS_ROUTING_ROCKS = [
2001:678:1e0::/48
];
'';
};
}
];
};
};
}
Here we define the global settings valid for all routers of a specific group
routing.yml
asn: 202739
# RPKI validation is enabled and invalids will be rejected
rpki_validation: yes
rpki_validator:
host: 127.0.0.1
port: 3323
# local pref used for transit routes learned from
last_resort_local_pref: 1
# communities used to tag routes
communities:
origin: (202739, 0, 1000)
peer_import: (202739, 0, 2000)
upstream_import: (202739, 0, 3000)
downstream_import: (202739, 0, 4000)
filtered_bogon: (202739, 666, 1)
filtered_own_prefix: (202739, 666, 2)
filtered_own_communities: (202739, 666, 3)
filtered_rpki_invalid: (202739, 666, 4)
filtered_aspath_invalid: (202739, 666, 5)
filtered_tier1: (202739, 666, 6)
filtered_aspath_length: (202739, 666, 7)
# our prefixes announce
prefixes:
ipv6:
- 2001:678:1e0::/48
# global filters which can be used as alternative to the auto generated ones
filters:
ibgp_in:
prefixes:
- 2001:678:1e0::/48{56,64}
default_only:
accept_default: yes
# peer types are like templates defining common attributes for a group of peers
peer_types:
internal:
upstream:
local_pref: 100
as_prepend: 2
local_role: customer
metro_peer:
local_pref: 10000
local_role: peer
remote_peer:
local_pref: 1000
local_role: peer
peers:
202739: # routing-rocks
type: internal
54321: # upstream
upstream: yes
filters:
import: upstream_as54321_in
export: ebgp_as54321_out
type: upstream
rtbh_community: (54321,666)
rules: # our upstream uses the community (54321,200) to tag his customer routes, we use this to set the local pref
- when:
community: (54321,200)
then:
set_local_pref: 50000
206356: # ff-essen
filters:
import: peer_as206356_in
export: ebgp_as206356_out
type: metro_peer
max_prefix:
ipv6: 5
12345: # downstream
downstream: yes
filters:
import: peer_as12345_in
export: default_only
as_set:
ipv4: AS_EXAMPLE_IPv4
ipv6: AS_EXAMPLE_IPv6
type: metro_peer
This is the common configuration for all routers in one metro
metro.yml
communities_metro:
origin: (202739, 0, 1100)
peer_import: (202739, 0, 2100)
upstream_import: (202739, 0, 3100)
downstream_import: (202739, 0, 4100)
Here we define the actual sessions for the peers defined in the global config
router.yml
router_id: 100.64.0.1
source_ipv6: 2001:678:1e0:999::1
static.yml
# we have to define the static default route to be able to announce it downstream
static_default_routes:
ipv4: no
ipv6: yes
ospf.yml
ospf:
interfaces:
- name: eth0
- name: eth1
- name: gre1
ttl_security: yes
stub_interfaces:
- lo
prefixes:
ipv6:
- 2001:678:1e0::/48
bgp.yml
peerings:
- asn: 54321
sessions:
- name: upstream_01
ip: 100.64.1.0
- asn: 12345
sessions:
- name: downstream_01
ip: 2001:678:1e0:888::2
- asn: 206356
sessions:
- name: ff_essen_dus
ip: 2001:7f8:9e:0:3:2614:0:1
- name: ff_essen_fra
ip: 2001:7f8::3:2614:0:1
type: remote_peer # since DE-CIX FRA is remote peering for this router, we want to override the peering type here
Rules are very easy and basic way to do a little bit of TE. For now it is not possible to combine conditions. This is planned for future releases.
The policy expects definitions for the AS_SET values used in the inventory in the as-sets
directory. In my setup these prefix lists are auto generated via cronjob. This tooling for this task will be open sourced in the future. For now you have to make sure that theses files exists. In the example I used a AS_SET for a peering between routing-rocks and Freifunk Essen. This file looks like:
define AS_FFE_IPv4 = [
194.48.228.0/22{22,24}
];
define AS_FFE_IPv6 = [
2a0c:efc0::/29{29,48}
];
(c) Daniel Czerwonk, 2019. Licensed under MIT license.