|
|
# Route server with community based filtering and multiple RIBs
|
|
|
|
|
|
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 are unfiltered (except max prefix limit) and connected to a routing table named T<AS#>. So it means that all prefixes received from R25192x1 and R25192x2 are stored in routing table T25192. So each AS has its own routing table. All those routing tables are connected to the master table by pipe protocols named P<AS#>. Filtering (both in and out) is applied inside those PIPE protocols. So it means that unwanted routes from AS1111 would be stored in routing table T1111 but would not go to the master routing table. From the master routing table all routes are distributed back into peer routing tables (with filtering - bgp_out() applied). Attached picture illustrates the whole architecture.
|
|
|
|
|
|
![Route Server - multiple RIB with filtering](bird-rs.png)
|
|
|
|
|
|
So if you want to see prefixes that are sent by the first router of a member with AS# 222 type:
|
|
|
bird> show route table T222 protocol R222x1
|
|
|
|
|
|
If you want to see routes that where accepted from this router to the master routing table then type:
|
|
|
bird> show route protocol R222x1
|
|
|
|
|
|
If you want to see all prefixes that will be (or are) propagated to a member with AS# 333 type:
|
|
|
bird> show route table T333
|
|
|
|
|
|
And the last example - if you want to see prefixes announced from AS111 to AS333:
|
|
|
bird> show route table T333 protocol R111
|
|
|
|
|
|
Inbound filters are named bgp_in_AS<AS#>. First of all, strange routes (rfc1918 and similar) are excluded by the function avoid_martians(). Then the filter checks if the first AS number is equal to the peer number. Then the AS number originating that prefix is matched with AS# set taken usually from RIPE db and then prefix is checked against prefix set taken also usually from RIPE DB.
|
|
|
|
|
|
Outbound filtering is done using one simple function called bgp_out() - it does filtering based on BGP communities. So each member can decide with prefixes are not propagated to which other member.
|
|
|
|
|
|
This variant consumes a lot of memory (and other resources) because each prefix is stored in all local routing tables. You might be also interested a [Simple route server](Simple_route_server) configuration.
|
|
|
|
|
|
I hope I explained it a little bit. If you have any other question, please do not hesitate to ask.
|
|
|
|
|
|
Ondrej Filip
|
|
|
|
|
|
|
|
|
/*
|
|
|
* Route server configuration example
|
|
|
*/
|
|
|
|
|
|
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(int peeras)
|
|
|
{
|
|
|
if ! (source = RTS_BGP ) then return false;
|
|
|
if peeras > 65535 then return true; # communities do not support AS32
|
|
|
if (0,peeras) ~ bgp_community then return false;
|
|
|
if (myas,peeras) ~ bgp_community then return true;
|
|
|
if (0, myas) ~ bgp_community then return false;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
####
|
|
|
# Protocol templates
|
|
|
|
|
|
template bgp PEERS {
|
|
|
local as myas;
|
|
|
import all;
|
|
|
export all;
|
|
|
import limit 10000 action restart;
|
|
|
rs client;
|
|
|
}
|
|
|
|
|
|
template pipe PIPES {
|
|
|
table master;
|
|
|
mode transparent;
|
|
|
}
|
|
|
|
|
|
|
|
|
####
|
|
|
# Configuration of BGP peer follows
|
|
|
|
|
|
### AS111 - Member1
|
|
|
table T111;
|
|
|
|
|
|
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 pipe P111 from PIPES {
|
|
|
description "Member 1";
|
|
|
peer table T111;
|
|
|
import filter bgp_in_AS111;
|
|
|
export where bgp_out(111);
|
|
|
}
|
|
|
|
|
|
protocol bgp R111x1 from PEERS {
|
|
|
description "Member 1 - peer 1";
|
|
|
neighbor 10.0.0.11 as 111;
|
|
|
table T111;
|
|
|
}
|
|
|
|
|
|
protocol bgp R111x2 from PEERS {
|
|
|
description "Member 1 - peer 2";
|
|
|
neighbor 10.0.0.12 as 111;
|
|
|
table T111;
|
|
|
}
|
|
|
|
|
|
### AS222 - Member2
|
|
|
table T222;
|
|
|
|
|
|
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 pipe P222 from PIPES {
|
|
|
description "Member 2";
|
|
|
peer table T222;
|
|
|
import filter bgp_in_AS222;
|
|
|
export where bgp_out(222);
|
|
|
}
|
|
|
|
|
|
protocol bgp R222x1 from PEERS {
|
|
|
description "Member 2 - peer 1";
|
|
|
neighbor 10.0.0.21 as 222;
|
|
|
table T222;
|
|
|
}
|
|
|
|
|
|
### AS333 - Member3
|
|
|
table T333;
|
|
|
|
|
|
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 pipe P333 from PIPES {
|
|
|
description "Member 3";
|
|
|
peer table T333;
|
|
|
import filter bgp_in_AS333;
|
|
|
export where bgp_out(333);
|
|
|
}
|
|
|
|
|
|
protocol bgp R333x1 from PEERS {
|
|
|
description "Member 3 - peer 1";
|
|
|
neighbor 10.0.0.31 as 333;
|
|
|
table T333;
|
|
|
}
|
|
|
|
|
|
protocol bgp R333x2 from PEERS {
|
|
|
description "Member 3 - peer 2";
|
|
|
neighbor 10.0.0.32 as 333;
|
|
|
table T333;
|
|
|
}
|
|
|
|
|
|
protocol bgp R333x3 from PEERS {
|
|
|
description "Member 3 - peer 3";
|
|
|
neighbor 10.0.0.33 as 333;
|
|
|
table T333;
|
|
|
} |