|
|
# 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.
|
|
|
|
|
|
![Route Server - single RIB with filtering](rs-srib.png)
|
|
|
|
|
|
Here is the configuration example:
|
|
|
|
|
|
/*
|
|
|
* Route server configuration example
|
|
|
* Single RIB configuration with filtering
|
|
|
*/
|
|
|
|
|
|
log "/var/log/bird.log" all;
|
|
|
log syslog all;
|
|
|
|
|
|
router id 9.9.9.9;
|
|
|
define myas = 999;
|
|
|
|
|
|
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;
|
|
|
if ((ro,0,myas) ~ bgp_ext_community) then return false;
|
|
|
} 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;
|
|
|
secondary;
|
|
|
import limit 25000 action restart;
|
|
|
start delay time 60;
|
|
|
interpret communities off;
|
|
|
import keep filtered on;
|
|
|
}
|
|
|
|
|
|
table master sorted;
|
|
|
|
|
|
####
|
|
|
# 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);
|
|
|
} |