Configuring BGP using Bird on Ubuntu 14.04LTS
Table of Contents
As part of the QFX testing I’ve been doing at work, I’ve had to do the testing of running BGP between a switch and server. Although one of my seniors advised I could just test BGP between two switches, as BGP is BGP, and should work whether it’s a switch or server, the protocol is the same and should simply work. However, given the chance to learn something new, I went with it and thought this would be the perfect chance for a new post! I found out that our production servers use EXaBGP daemon. I looked into the configuration and the specs for EXaBGP…. Let just say was pretty lost very quickly (being polite)! I then started looking into alternative daemons and found BIRD. I had heard of BIRD before and from my research it didn’t look as complex as EXaBGP.
The BIRD project was developed as a school project at the Faculty of Mathematics and Physics at Charles University in Prague, with major contributions from developers Martin Mares, Pavel Machek, Ondrej Zajicek, Libor Forst and Ondrej Filip. Designed for a UNIX based system, BIRD is an open source daemon that runs an Internet protocol suite. It can run a number of Dynamic Routing Protocols: BGP, OSPF, RIP, Static Routing, Both IPv4 and IPv6 and can hold Multiple Routing Tables.
I had found a perfect post from mindless.gr that went into detail on how to configure a simple IPv4/IPv6 BGP session using BIRD, which was exactly what I needed.
With that in mind, this post will detail how to configure a simple IPv4 BGP session using BIRD on Ubuntu 14.04LTS
Let’s get Cracking :P
You will need sudo and root privileges
You will be able to make the changes here with sudo privileges. You need to install the BIRD package, which is nicely available via Ubuntu’s Advanced Packaging Tool apt-get install bird
marquk01@km-vm3:~$ apt-get install bird6
By default any modern Linux distribution will have IP Forwarding disabled; we’ll need the server to basically act as a router and we’ll need to have IP Forwarding enabled. Running the command sysctl net.ipv4.ip_forward=1
will enable IPv4 forwarding. You can also make this a permanent change so that on boot, IP forwarding will always been enabled. You will need to edit /etc/sysctl.conf
file. Check below for what you need to look out for and uncomment:
marquk01@km-vm3:~$ cat /etc/sysctl.conf
{...}
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
# Enabling this option disables Stateless Address Autoconfiguration
# based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1
{...}
Backup the original bird.conf by running something like cp bird.conf
bird.old.conf
(always need to cover your ass :p lol)
The config file looks quite complex at first appearance (when this was written I didn’t have a clue about any of it!!). If you want more detailed information about the config file and the different options available you can find them on the Bird Internet Routing Daemon: User’s Guide Page
For my example, I needed a simple configuration that had the server advertise 4 routes (3 x /24 and /22) and accept all routes. This was the same setup on the switch side, which is a Juniper QFX5100.
To edit the bird.conf
file, you’ll need it to be root. I tried a sudo nano however I got Permission Denied! So I sudo -s down to root and edited the conf file
marquk01@km-vm3:~$ sudo -s
[sudo] password for marquk01:
root@km-vm3:~# nano /etc/bird/bird.conf
Bird Configuration⌗
marquk01@km-vm3:~$ sudo cat /etc/bird/bird.conf
/\*
\* This is an example configuration file.
\*/
# Yes, even shell-like comments work...
# Configure logging
log syslog all;
# Override router ID
router id 192.31.1.3;
# This pseudo-protocol performs synchronization between BIRD's routing
# tables and the kernel. If your kernel supports multiple routing tables
# (as Linux 2.2.x does), you can run multiple instances of the kernel
# protocol and synchronize different kernel tables with different BIRD tables.
protocol kernel {
# learn; # Learn all alien routes from the kernel
persist; # Don't remove routes on bird shutdown
scan time 20; # Scan kernel routing table every 20 seconds
# import none; # Default is import all
export all; # Default is export none
# kernel table 5; # Kernel table to synchronize with (default: main)
}
# This pseudo-protocol watches all interface up/down events.
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
# Static routes (again, there can be multiple instances, so that you
# can disable/enable various groups of static routes on the fly).
protocol static static_bgp {
route 192.70.0.0:255.255.252.0 via 192.31.1.3;
route 192.70.1.0:255.255.255.0 via 192.31.1.3;
route 192.70.1.0:255.255.255.0 via 192.31.1.3;
route 192.70.2.0:255.255.255.0 via 192.31.1.3;
route 192.70.3.0:255.255.255.0 via 192.31.1.3;
}
#BGP Configuration
protocol bgp {
import all;
export where proto = "static_bgp";
local as 3000;
neighbor 192.31.1.2 as 4000;
}
Junos Switch Configuration⌗
set interfaces xe-0/0/4 description "km-vm3 10GB"
set interfaces xe-0/0/4 enable
set interfaces xe-0/0/4 unit 0 family inet address 192.31.1.2/31
set routing-options static route 192.69.0.0/24 reject
set routing-options static route 192.69.1.0/24 reject
set routing-options static route 192.69.2.0/24 reject
set routing-options static route 192.69.3.0/24 reject
set routing-options autonomous-system 4000
set protocols bgp enable
set protocols bgp local-as 4000
set protocols bgp group test local-address 192.31.1.2
set protocols bgp group test family inet unicast
set protocols bgp group test neighbor 192.31.1.3 export BGP-Export
set protocols bgp group test neighbor 192.31.1.3 peer-as 3000
set policy-options policy-statement BGP-Export from protocol static
set policy-options policy-statement BGP-Export then accept
Having configured the switch and the server, I needed to enable to the bird daemon. This was done by running the command invoke-rc.d bird start
root@km-vm3:~$ invoke-rc.d bird start
To enter the bird client, you will need to run the command birdc
and from there you’re able to run a verification command to check that routes are being advertised and received from server to the switch.
marquk01@km-vm3:~$ sudo birdc
\[sudo\] password for marquk01:
BIRD 1.4.0 ready.
bird>
Bird Verification⌗
From the bird client, you can run show route
to see the RIB table and to check the BGP status you will run show protocols all bgp1
show route⌗
bird> show route
192.69.0.0/24 via 192.31.1.2 on eth1 \[bgp1 11:35:14\] \* (100) \[AS4000i\]
192.69.1.0/24 via 192.31.1.2 on eth1 \[bgp1 11:35:14\] \* (100) \[AS4000i\]
192.69.2.0/24 via 192.31.1.2 on eth1 \[bgp1 11:35:14\] \* (100) \[AS4000i\]
192.69.3.0/24 via 192.31.1.2 on eth1 \[bgp1 11:35:14\] \* (100) \[AS4000i\]
192.70.0.0/22 via 192.31.1.3 on eth1 \[static_bgp 13:50:05\] ! (200)
192.70.1.0/24 via 192.31.1.3 on eth1 \[static_bgp 11:35:09\] ! (200)
192.70.2.0/24 via 192.31.1.3 on eth1 \[static_bgp 11:35:09\] ! (200)
192.70.3.0/24 via 192.31.1.3 on eth1 \[static_bgp 11:35:09\] ! (200)
show protocols all bgp1⌗
bird> show protocols all bgp1
name proto table state since info
bgp1 BGP master up 11:35:14 Established
Preference: 100
Input filter: ACCEPT
Output filter: (unnamed)
Routes: 4 imported, 4 exported, 4 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 4 0 0 0 4
Import withdraws: 0 0 --- 0 0
Export updates: 9 4 0 --- 5
Export withdraws: 0 --- --- --- 0
BGP state: Established
Neighbor address: 192.31.1.2
Neighbor AS: 4000
Neighbor ID: 10.1.0.241
Neighbor caps: refresh AS4
Session: external AS4
Source address: 192.31.1.3
Hold timer: 52/90
Keepalive timer: 18/30
Junos Verification⌗
On the switch, we can check when the BGP session is up and can see what routes that are being adverted and what routes are being received:
show bgp summary⌗
{master:0}
root@QFX-Bottom> show bgp summary group test
Groups: 1 Peers: 1 Down peers: 0
Table Tot Paths Act Paths Suppressed History Damp State Pending
inet.0
4 4 0 0 0 0
Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
192.31.1.3 3000 79 79 0 1 33:43 4/4/4/0 0/0/0/0
show route advertising-protocol bgp⌗
{master:0}
root@QFX-Bottom> show route advertising-protocol bgp 192.31.1.3
inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
Prefix Nexthop MED Lclpref AS path
* 192.69.0.0/24 Self I
* 192.69.1.0/24 Self I
* 192.69.2.0/24 Self I
* 192.69.3.0/24 Self I
show route receive-protocol bgp⌗
{master:0}
root@QFX-Bottom> show route receive-protocol bgp 192.31.1.3
inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
Prefix Nexthop MED Lclpref AS path
* 192.70.0.0/22 192.31.1.3 3000 I
* 192.70.1.0/24 192.31.1.3 3000 I
* 192.70.2.0/24 192.31.1.3 3000 I
* 192.70.3.0/24 192.31.1.3 3000 I
You can enable BIRD for IPv6 as well. The editing and process is exactly the same however you’ll need to edit the /etc/bird/bird6.conf
file with the appropriate IPv6 addressing. To enter the IPv6 BIRD client you’ll use the command birdc6
.
Being able to spin up VMs and have them configured as “dumb” BGP nodes is such a useful thing to have in a lab when you don’t have as many switches/routers as you need. From what I can see Bird can be a extremely useful tool for connecting BGP routes and I see that many Internet Exchange Points (IXPs) such as London Internet Exchange (LINX)
, London Network Access Point (LONAP)
, Deutscher Commercial Internet Exchange (DE-CIX)
, [Amsterdam Internet Exchange (AMS-IX)](https://nynj.ams-ix.net/technical--5/specifications-descriptions/ams-ix-route-servers)
and many more use BIRD for their Route Server. When I get a chance I will defiantly look into how to get the most out of BIRD!
You can find all the documentation and user guides on BIRD on the official website here