Route server with community based filtering and single RIB
The concept of the configuration is following: Each IXP member has one or more BGP peers. Those BGP sessions are named R<AS#>x<#>. So for example, R25192x2 is the second BGP peer of a member with AS number 25192. All sessions have inbound filters and are connected to a single routing table (master). Inbound filters are unique for every peering session. There is just a single outbound filer - bgp_out(). It is a function with parameter - AS# to which is the prefix exported.
Here is the configuration example:
/*
* Route server configuration example
* Single RIB configuration with filtering
*/
log "/var/log/bird.log" all;
router id 9.9.9.9;
define myas = 999;
ipv4 table master4 sorted;
protocol device { }
# This function excludes weird networks
# rfc1918, class D, class E, too long and too short prefixes
function avoid_martians()
prefix set martians;
{
martians = [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+, 10.0.0.0/8+,
224.0.0.0/4+, 240.0.0.0/4+, 0.0.0.0/32-, 0.0.0.0/0{25,32}, 0.0.0.0/0{0,7} ];
# Avoid RFC1918 and similar networks
if net ~ martians then return false;
return true;
}
# BGP output filter (based on communities)
function bgp_out_comm(int peeras)
{
if ! (source = RTS_BGP ) then return false;
if peeras > 65535 then
{
if (ro,0,peeras) ~ bgp_ext_community then return false;
if (ro,myas,peeras) ~ bgp_ext_community then return true;
} else {
if ((0,peeras) ~ bgp_community) || ((ro,0,peeras) ~ bgp_ext_community) then return false;
if ((myas,peeras) ~ bgp_community) || ((ro,myas,peeras) ~ bgp_ext_community) then return true;
}
if ((0,myas) ~ bgp_community) || ((ro,0,myas) ~ bgp_ext_community) then return false;
return true;
}
function bgp_out(int peeras)
{
if !bgp_out_comm(peeras) then return false;
# Remove IXP related communities
bgp_community.delete([(0,*)]);
bgp_community.delete([(myas,*)]);
bgp_ext_community.delete([(ro,0,*)]);
bgp_ext_community.delete([(ro,myas,*)]);
return true;
}
####
# Protocol templates
template bgp PEERS {
local as myas;
rs client;
connect delay time 60;
interpret communities off;
ipv4 {
import limit 25000 action restart;
import keep filtered on;
secondary on;
}
}
####
# Configuration of BGP peer follows
### AS111 - Member1
filter bgp_in_AS111
prefix set allnet;
int set allas;
{
if ! (avoid_martians()) then reject;
if (bgp_path.first != 111 ) then reject;
allas = [ 1234, 2345, 3456, 4567 ];
if ! (bgp_path.last ~ allas) then reject;
allnet = [ 12.34.0.0/16 , 23.45.0.0/16, 34.56.0.0/16, 45.56.0.0/16 ];
if ! (net ~ allnet) then reject;
accept;
}
protocol bgp R111x1 from PEERS {
description "Member 1 - peer 1";
neighbor 10.0.0.11 as 111;
import filter bgp_in_AS111;
export where bgp_out(111);
}
protocol bgp R111x2 from PEERS {
description "Member 1 - peer 2";
neighbor 10.0.0.12 as 111;
import filter bgp_in_AS111;
export where bgp_out(111);
}
### AS222 - Member2
filter bgp_in_AS222
prefix set allnet;
int set allas;
{
if ! (avoid_martians()) then reject;
if (bgp_path.first != 222 ) then reject;
allas = [ 4321, 5432, 6543 ];
if ! (bgp_path.last ~ allas) then reject;
allnet = [ 43.21.0.0/16 , 54.32.0.0/16, 65.43.0.0/16 ];
if ! (net ~ allnet) then reject;
accept;
}
protocol bgp R222x1 from PEERS {
description "Member 2 - peer 1";
neighbor 10.0.0.21 as 222;
import filter bgp_in_AS222;
export where bgp_out(222);
}
### AS333 - Member3
filter bgp_in_AS333
prefix set allnet;
int set allas;
{
if ! (avoid_martians()) then reject;
if (bgp_path.first != 333 ) then reject;
allas = [ 1111, 2222, 3333, 4444, 5555, 6666 ];
if ! (bgp_path.last ~ allas) then reject;
allnet = [ 11.11.0.0/16, 22.22.0.0/16, 33.33.0.0/16, 44.44.0.0/16, 55.55.0.0/16, 66.66.0.0/16 ];
if ! (net ~ allnet) then reject;
accept;
}
protocol bgp R333x1 from PEERS {
description "Member 3 - peer 1";
neighbor 10.0.0.31 as 333;
import filter bgp_in_AS333;
export where bgp_out(333);
}
protocol bgp R333x2 from PEERS {
description "Member 3 - peer 2";
neighbor 10.0.0.32 as 333;
import filter bgp_in_AS333;
export where bgp_out(333);
}
protocol bgp R333x3 from PEERS {
description "Member 3 - peer 3";
neighbor 10.0.0.33 as 333;
import filter bgp_in_AS333;
export where bgp_out(333);
}