BIRD: Filters and Functions example

BIRD contains a simple programming language. There are two objects in this language: filters and functions. Filters are interpreted by BIRD core when a route is being passed between protocols and routing tables. The filter language contains control structures such as if's and switches, but it allows no loops.
BIRD supports functions, so that you don't have to repeat the same blocks of code over and over. Functions can have zero or more parameters and they can have local variables. Recursion is not allowed.

In this post we will configure an inbound filter that will set MED to a specific value for a specific ASN and also set Local Preference attribute for a specific prefix from the specific upstream ISP.

Lets set MED 50 to all routes originated in Twitter ASN 13414. Also lets set local preffor prefix 4.0.0.0/9 received via Level3. The simple and non-elegant way to do that is define the following filter:

filter BGP_FROM_EDGE2 { if source = RTS_BGP then { if bgp_path.last = 13414 then { bgp_med = 50; } if (net = 4.0.0.0/9 ) && (bgp_path.first = 3356) then { bgp_local_pref = 300; } accept; } else reject; }

What if we want to change MED for morenetworks, originated in other ASs and set LP for other prefixes. It would be nice to be able to re-use the code. So lets write a function that will setMED to routes originated in the specified ASN. And lets define another function that will set local preference to a prefix coming from specific ISP:

function SET_MED_ORIGIN_AS(int ORIGIN_AS; int MED) { if bgp_path.last = ORIGIN_AS then { bgp_med = MED; } return true; } function SET_LOCAL_PREF_NET(prefix NET; int TRANSIT_AS; int LOCAL_PREF){ if (net = NET ) && (bgp_path.first = TRANSIT_AS) then { bgp_local_pref = LOCAL_PREF; } return true; }

And our filter will have a different look now:

filter BGP_FROM_EDGE int EdgeCast_AS; int Twitter_AS; int Fastly_AS; { EdgeCast_AS = 15133; Twitter_AS = 13414; Fastly_AS = 54113; if source = RTS_BGP then { SET_MED_ORIGIN_AS(13414, 50); SET_LOCAL_PREF_NET(4.0.0.0/9, 3356, 300); accept; } else reject; }