== mellowd.dev ==
Darren's random posts

Migrating from bird to bird2 - part 3

I have two main pieces of code I need to update. First is the parser which runs every 5 minutes to scrape a ton of information out of bird and place into a database. The second piece is my glass RPC server which directly requests information from bird. Most changes are there simply because of syntax changes as well as the move to a single daemon.


The parserer runs every 5 minutes. My code is pretty modular so the parser collects all this information, converts that data into a struct, then pushes that data to my collection RPC server which dumps the data into a database. As such, I only need to update the parser itself.

This is the commit change for this file.

One item I collect is the amount of peers I have configured and how many of them are established. IPv4 and IPv6 peers were in different daemons before but the same now. As such I added a _v4 and _v6 suffix to my peers so I could easily parse them out. Another big change is when I collect prefix information itself. I used to be able to do a show route in each respective daemon now, but in bird2 you need to add the table you want to look at if looking at a specific table. The default IPv4 and IPv6 tables are labelled master4 and master6 respectivily.


Glass code updates are quite similar. Adjust my commands to look at the correct table when requied. One big advantage now though is if I’m looking for a specific prefix, I can just do a shwo route primary x regardless if it’s IPv4 or IPv6.

The biggest change on the glass side is how I pull information for a specific ROA. In bird, I used a static ROA list updated 4 times a day, then used bird to do an eval roa_check(). I’m currently running RPKI-RTR so wanted a better way of doing this. I decided to use local-pref for this part. I have a new inbound BGP filter doing the following:

  if ( roa_check(roa_v4, net, bgp_path.last_nonaggregated ) = ROA_INVALID ) then bgp_local_pref=50;
  if ( roa_check(roa_v4, net, bgp_path.last_nonaggregated ) = ROA_UNKNOWN ) then bgp_local_pref=100;
  if ( roa_check(roa_v4, net, bgp_path.last_nonaggregated ) = ROA_VALID ) then bgp_local_pref=200;

Doing it this way, I just need to check the local preference of a route to determine the ROA status. I then have a map to convert local pref into a status and return that.

But, after implementing this there is an issue. It turns out bird2 does not re-evalute filter when a ROA is updated. So if I receive a prefix with an unknown ROA which then gets a valid ROA, that prefix does not go through the filter again to get it’s local pref updated :(

I have an open thread here, but it seems like this isn’t something that will be fixed soon. Another option is to move back to the eval roa_check(), however bird 2.0.5 has a bug with this as well.

So, what should I do? For now I’ve decided to keep the RPKI-RTR and filter setup, then 4 times a day run a cronjob to do the following:

57 4,10,16,22 * * * /usr/sbin/birdc reload in all

This forces bird2 to refresh all BGP inbound so all prefixes go through the prefix filter again. tbh, I’m not sure if I’m going to keep it this way yet or not. I should probably just upgrade to bird 2.0.7 and revert back to a eval check. But I’ve yet to decide.