How to Configure BGP Routing with BIRD on RHEL 7
Border Gateway Protocol (BGP) is the routing protocol that underpins the modern internet, enabling routers in different autonomous systems to exchange network reachability information. While large-scale BGP deployments typically run on dedicated hardware, Linux systems running RHEL 7 can participate in BGP routing using software daemons. BIRD (BIRD Internet Routing Daemon) is a lightweight, high-performance routing daemon that supports BGP, OSPF, RIP, and other protocols. This tutorial walks through installing BIRD from the EPEL repository, writing a working BGP configuration, establishing an eBGP peering session, and using the BIRD control shell to monitor routing state.
Prerequisites
- RHEL 7 system with root or sudo access
- EPEL repository enabled (
yum install epel-release) - A second router or BGP peer (physical, virtual, or a second RHEL 7 VM)
- Basic understanding of IP routing and autonomous system numbers (ASNs)
- Firewall access on TCP port 179 between peers
Step 1: Enable EPEL and Install BIRD
BIRD is not available in the default RHEL 7 repositories, so you must first enable the Extra Packages for Enterprise Linux (EPEL) repository. If you have a Red Hat subscription, you may also enable the Optional channel. Once EPEL is available, install BIRD along with its documentation package.
# Enable EPEL if not already present
yum install -y epel-release
# Install BIRD routing daemon
yum install -y bird
# Verify the installed version
bird --version
The package installs two binaries: bird (IPv4 daemon) and bird6 (IPv6 daemon). Both share a similar configuration syntax. This tutorial focuses on IPv4 BGP, but the concepts translate directly to bird6 with minor adjustments.
Step 2: Understand the BIRD Configuration File Structure
BIRD is configured through /etc/bird.conf. The file is divided into sections that define global options, routing tables, protocols, and filters. Before writing a BGP stanza, you need to configure several foundational protocols that BIRD requires for correct operation.
The four core protocol blocks are:
- device — scans the kernel network interfaces so BIRD knows which links exist
- kernel — synchronises BIRD’s routing table with the Linux kernel FIB
- static — allows manual static route injection into BIRD
- bgp — defines a peering session with a neighbor
Step 3: Write the Base /etc/bird.conf Configuration
Open the default configuration file and replace its contents with a clean working configuration. In this example, Router A has IP address 192.168.10.1 and belongs to AS 65001. Its eBGP peer, Router B, has IP address 192.168.10.2 and belongs to AS 65002.
# /etc/bird.conf — Router A (AS 65001)
# Global router ID — typically the primary loopback or management IP
router id 192.168.10.1;
# Log to syslog (messages appear in /var/log/messages)
log syslog all;
# -------------------------------------------------------
# Protocol: device
# Scans kernel interfaces; required by all other protocols
# -------------------------------------------------------
protocol device {
scan time 10;
}
# -------------------------------------------------------
# Protocol: kernel
# Exports BIRD routes into the Linux kernel routing table
# -------------------------------------------------------
protocol kernel {
persist; # keep routes in kernel when BIRD exits
scan time 20;
export all; # export all BIRD routes to the kernel
import all; # import kernel routes into BIRD
}
# -------------------------------------------------------
# Protocol: static
# Inject a locally originated prefix into BGP
# -------------------------------------------------------
protocol static static_bgp {
route 10.0.0.0/24 via 192.168.10.1;
route 10.0.1.0/24 blackhole;
}
# -------------------------------------------------------
# Filter: only export our locally originated prefixes
# -------------------------------------------------------
filter export_to_peer {
if proto = "static_bgp" then accept;
reject;
}
# -------------------------------------------------------
# Protocol: BGP — eBGP session with Router B
# -------------------------------------------------------
protocol bgp peer_b {
description "eBGP peer Router B";
local as 65001;
neighbor 192.168.10.2 as 65002;
# Export only our static prefixes; import everything from peer
export filter export_to_peer;
import all;
# Keep session alive even if no routes are exchanged
next hop self;
hold time 90;
keepalive time 30;
}
Step 4: Enable and Start the BIRD Service
With the configuration file in place, enable BIRD to start at boot and then start it immediately. The systemctl commands manage the bird.service unit.
# Enable BIRD to start at boot
systemctl enable bird
# Start BIRD now
systemctl start bird
# Verify the service is running
systemctl status bird
# Watch for any configuration errors in the system journal
journalctl -u bird -n 50 --no-pager
If the service fails to start, a syntax error in bird.conf is the most common cause. Check the journal output for the line number of the offending statement.
Step 5: Configure the Peer Router (Router B)
On Router B (AS 65002, IP 192.168.10.2), create a mirrored configuration. Swap the ASN, router ID, and neighbor address accordingly.
# /etc/bird.conf — Router B (AS 65002)
router id 192.168.10.2;
log syslog all;
protocol device { scan time 10; }
protocol kernel {
persist;
scan time 20;
export all;
import all;
}
protocol static static_bgp {
route 10.1.0.0/24 via 192.168.10.2;
}
filter export_to_peer {
if proto = "static_bgp" then accept;
reject;
}
protocol bgp peer_a {
description "eBGP peer Router A";
local as 65002;
neighbor 192.168.10.1 as 65001;
export filter export_to_peer;
import all;
next hop self;
hold time 90;
keepalive time 30;
}
Step 6: Open the Firewall for BGP
BGP uses TCP port 179. If firewalld is active on either router, you must permit this traffic.
# Allow BGP on the relevant zone (replace 'public' with your zone)
firewall-cmd --permanent --zone=public --add-port=179/tcp
# Reload firewalld to apply the rule
firewall-cmd --reload
# Verify the rule is active
firewall-cmd --zone=public --list-ports
Step 7: Monitor Sessions with the birdc Shell
BIRD provides an interactive control shell called birdc. It connects to the running daemon via a Unix socket and allows you to inspect protocol state, routing tables, and apply configuration changes without restarting the daemon.
# Launch the interactive shell
birdc
# Inside birdc — show all protocol states
bird> show protocols
# Show detailed state for the BGP peer
bird> show protocols peer_b
# Show the full routing table
bird> show route
# Show routes learned from a specific peer
bird> show route protocol peer_b
# Show routes exported to the peer (what we advertise)
bird> show route export peer_b
# Reload the configuration file without restarting
bird> configure
# Exit the shell
bird> quit
A healthy BGP session shows the state as Established in the show protocols output. If you see Active or Idle, the TCP connection to the peer has not been established — check IP connectivity, firewall rules, and that BIRD is running on both sides.
Step 8: BIRD vs Quagga and FRRouting
BIRD is not the only BGP daemon available for Linux. Quagga was the dominant open-source routing suite for many years, and FRRouting (FRR) is its modern, actively maintained fork. The table below summarises the key differences to help you choose the right tool for your environment.
- BIRD — single binary per address family (bird/bird6), powerful filter language, excellent performance, widely used in IXP route servers, configuration is declarative
- Quagga — multi-daemon architecture (zebra + bgpd + ospfd), Cisco-like CLI via vtysh, still available in EPEL but development stalled; largely superseded by FRR
- FRRouting (FRR) — community fork of Quagga, actively developed, supports EVPN, BFD, SR-MPLS, and modern BGP features; Cisco-like CLI familiar to network engineers
For route server use cases (IXP peering, traffic engineering) BIRD’s filtering language is unmatched. For environments where operators already know Cisco IOS syntax, FRR’s vtysh shell provides a gentler learning curve. Both are valid production choices on RHEL 7.
Conclusion
You have successfully installed BIRD from EPEL, written a complete /etc/bird.conf that defines device, kernel, static, and BGP protocol blocks, opened TCP port 179 in firewalld, and used birdc to verify that the eBGP session reached the Established state. The configuration demonstrated here is a minimal eBGP setup between two private autonomous systems, but the same principles — local AS declaration, neighbor specification, and import/export filters — apply directly to internet-facing deployments. From here you can extend the configuration with route reflectors, route communities, prefix lists, and multi-hop eBGP as your network requirements grow.