BIRD Cheat Sheet
Overview
BIRD (BIRD Internet Routing Daemon) is an open-source routing daemon for Unix-like systems that implements multiple Internet routing protocols including BGP, OSPF (v2 and v3), RIP, BFD, Babel, and static routing. BIRD is widely used in Internet Exchange Points (IXPs), route servers, data centers, and by network operators who need a flexible and performant software router. It powers the route servers at many of the world’s largest IXPs and is used as the routing agent by MetalLB and Calico in Kubernetes environments.
BIRD 2.x unified the previously separate IPv4 and IPv6 daemons into a single binary with multi-protocol and multi-table support. Its powerful filter language allows complex route manipulation, policy implementation, and traffic engineering. BIRD maintains separate routing tables (RIBs) per protocol instance and uses a flexible pipe mechanism to exchange routes between tables. The configuration language is expressive, supporting functions, variables, sets, and pattern matching for building sophisticated routing policies.
Installation
Package Installation
# Ubuntu/Debian
sudo apt install bird2
# RHEL/CentOS (EPEL)
sudo dnf install bird
# From source
wget https://bird.network.cz/download/bird-2.15.1.tar.gz
tar xzf bird-2.15.1.tar.gz
cd bird-2.15.1
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
make && sudo make install
# Start service
sudo systemctl enable bird
sudo systemctl start bird
Core Commands
| Command | Description |
|---|---|
birdc | Enter BIRD control CLI |
birdc show status | Show daemon status |
birdc show protocols all | Show all protocol instances |
birdc show route | Show main routing table |
birdc show route for <prefix> | Show routes for specific prefix |
birdc show route export <protocol> | Show routes exported to protocol |
birdc show route protocol <name> | Show routes from a protocol |
birdc configure | Reload configuration |
birdc configure check | Validate configuration |
birdc down | Shutdown BIRD |
birdc restart <protocol> | Restart a protocol instance |
birdc disable <protocol> | Disable a protocol |
birdc enable <protocol> | Enable a protocol |
Route Inspection
# Show all routes
birdc show route
# Show routes with details (AS path, communities, etc.)
birdc show route all
# Show routes for a specific prefix
birdc show route for 10.0.0.0/8
# Show routes learned from specific peer
birdc show route protocol bgp_upstream1 all
# Show routes exported to a peer
birdc show route export bgp_peer2
# Show route count per protocol
birdc show route count
# Show BGP neighbor status
birdc show protocols all bgp_upstream1
# Show memory usage
birdc show memory
Configuration
Basic Structure (/etc/bird/bird.conf)
# Global settings
router id 10.0.0.1;
# Logging
log syslog all;
log "/var/log/bird.log" { debug, trace, info, remote, warning, error, auth, fatal, bug };
# Device protocol (required - scans interfaces)
protocol device {
scan time 10;
}
# Direct protocol (generates routes for directly connected networks)
protocol direct {
ipv4;
ipv6;
interface "eth*", "ens*";
}
# Kernel protocol (syncs routes to OS kernel)
protocol kernel {
ipv4 {
export all;
import all;
};
learn;
scan time 15;
merge paths on;
}
protocol kernel {
ipv6 {
export all;
import all;
};
learn;
scan time 15;
}
Static Routes
protocol static static_v4 {
ipv4;
route 10.10.0.0/24 via 10.0.0.2;
route 10.20.0.0/24 via "eth1";
route 10.30.0.0/24 blackhole;
route 0.0.0.0/0 via 10.0.0.1;
}
protocol static static_v6 {
ipv6;
route 2001:db8:1::/48 via 2001:db8::2;
}
BGP Configuration
# BGP template
template bgp bgp_template {
local as 64500;
hold time 90;
keepalive time 30;
graceful restart on;
error wait time 30, 120;
ipv4 {
import filter bgp_import;
export filter bgp_export;
next hop self;
};
}
# Upstream provider
protocol bgp bgp_upstream1 from bgp_template {
neighbor 203.0.113.1 as 64501;
description "ISP Transit Provider";
multihop 2;
password "bgpsecret";
ipv4 {
import limit 500000 action block;
receive limit 600000 action disable;
};
}
# eBGP peer
protocol bgp bgp_peer_ix from bgp_template {
neighbor 198.51.100.5 as 64502;
description "IX Peer";
ipv4 {
add paths rx;
import limit 100000 action restart;
};
}
# iBGP peer
protocol bgp bgp_ibgp1 {
local as 64500;
neighbor 10.0.0.2 as 64500;
rr client;
ipv4 {
import all;
export all;
next hop self;
};
}
OSPF Configuration
protocol ospf v2 ospf_v4 {
router id 10.0.0.1;
ecmp yes;
tick 1;
area 0 {
interface "eth0" {
type pointopoint;
cost 10;
hello 10;
dead 40;
authentication cryptographic;
password "ospfpass";
};
interface "eth1" {
type broadcast;
cost 100;
priority 1;
stub;
};
stubnet 10.10.0.0/24;
};
area 1 {
nssa;
interface "eth2" {
cost 20;
};
};
ipv4 {
import all;
export filter {
if source = RTS_STATIC then accept;
reject;
};
};
}
protocol ospf v3 ospf_v6 {
ipv6 {
import all;
export where source = RTS_STATIC;
};
area 0 {
interface "eth0" {
type pointopoint;
cost 10;
};
};
}
Filter Language
# Define filter functions
function is_bogon_prefix() {
return net ~ [
0.0.0.0/8+, # RFC 1122 "this host"
10.0.0.0/8+, # RFC 1918
100.64.0.0/10+, # RFC 6598 CGN
127.0.0.0/8+, # Loopback
169.254.0.0/16+, # Link-local
172.16.0.0/12+, # RFC 1918
192.0.0.0/24+, # RFC 6890
192.0.2.0/24+, # TEST-NET-1
192.168.0.0/16+, # RFC 1918
198.18.0.0/15+, # Benchmarking
198.51.100.0/24+, # TEST-NET-2
203.0.113.0/24+, # TEST-NET-3
224.0.0.0/4+, # Multicast
240.0.0.0/4+ # Reserved
];
}
# Import filter
filter bgp_import {
if is_bogon_prefix() then reject;
if bgp_path.len > 64 then reject;
if net.len > 24 then reject;
if net.len < 8 then reject;
# Tag with community
bgp_community.add((64500, 100));
# Set local preference based on peer
if bgp_path.first = 64501 then bgp_local_pref = 200;
accept;
}
# Export filter
filter bgp_export {
if source != RTS_BGP && source != RTS_STATIC then reject;
if (64500, 999) ~ bgp_community then reject; # No-export community
if net = 0.0.0.0/0 then reject;
accept;
}
Advanced Usage
BFD (Bidirectional Forwarding Detection)
protocol bfd {
interface "eth0" {
min rx interval 100 ms;
min tx interval 100 ms;
idle tx interval 1 s;
multiplier 5;
};
neighbor 10.0.0.2;
}
# Use BFD in BGP
protocol bgp bgp_peer {
neighbor 10.0.0.2 as 64502;
bfd on;
ipv4 { import all; export all; };
}
Route Server (IXP)
template bgp rs_client {
local as 64999; # Route server AS
rs client;
ipv4 {
import filter rs_import;
export filter rs_export;
add paths tx;
};
}
protocol bgp rs_member1 from rs_client {
neighbor 198.51.100.1 as 64501;
}
protocol bgp rs_member2 from rs_client {
neighbor 198.51.100.2 as 64502;
}
RPKI Validation
protocol rpki rpki_validator {
roa4 { table roa_v4; };
roa6 { table roa_v6; };
remote "rpki-validator.example.com" port 3323;
retry keep 90;
refresh keep 900;
expire keep 172800;
}
roa4 table roa_v4;
roa6 table roa_v6;
function check_rpki() {
if (roa_check(roa_v4, net, bgp_path.last_nonaggregated) = ROA_INVALID) then {
reject;
}
}
Troubleshooting
| Issue | Solution |
|---|---|
| Configuration syntax error | Run birdc configure check before applying |
| BGP session not establishing | Check firewall (TCP 179); verify neighbor IP and AS number |
| Routes not appearing in kernel | Ensure kernel protocol exports routes; check birdc show route export kernel1 |
| OSPF adjacency stuck in ExStart | Check MTU matches on both sides; verify authentication |
| High memory usage | Set import limit on BGP sessions; reduce table size with filters |
| Route flapping | Enable error wait time; check BFD timers; verify physical link stability |
| BIRD not starting | Check config syntax; verify router id is set; check log file permissions |