Skip to main content

Border Gateway Protocol (BGP)

What is BGP

Border Gateway Protocol (BGP) is the routing protocol for the Internet. Much like the post office processing mail, BGP picks the most efficient routes for delivering Internet traffic.

What is BIRD

The BIRD Internet Routing Daemon project aims to develop a fully functional dynamic IP routing daemon primarily targeted on (but not limited to) Linux, FreeBSD and other UNIX-like systems and distributed under the GNU General Public License.

Source: https://bird.network.cz/

Pre Install BGP on BIRD

Tested with Debian

Basic system preparation ensures the router can forward packets and handle high route load.

Enable IP forwarding

Input:

nano /etc/sysctl.conf

Uncomment the line:

net.ipv4.ip_forward=1

Reload: Input:

sysctl -p

This activates IPv4 forwarding so the system can route packets between interfaces.

Optional tuning for high-performance routing

Add the following lines to /etc/sysctl.conf when handling heavy BGP traffic:

fs.file-max = 16777216
fs.nr_open = 1073741824
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_congestion_control = bbr
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
vm.max_map_count = 1048575

These tune kernel buffers, multipath, and routing responsiveness.


Install and Configure Bird2

Install Bird2

Input:

apt install bird2 -y

Check version

Input:

bird --version

Output:

BIRD version 2.x.x

Shows installed Bird version.

Enable service

Input:

systemctl enable --now bird

Bird2 starts at boot and loads configuration from /etc/bird/bird.conf.


Basic Configuration

Bird learns directly connected IPs, the kernel routing table, and interface state.

Enable direct protocol

Edit Bird: Input:

nano /etc/bird/bird.conf

Change:

protocol direct {
## disabled;
ipv4;
ipv6;
}

This allows Bird to detect interface addresses automatically.

Kernel protocol – enable learn

Change kernel section:

protocol kernel {
ipv4 {
export all;
};
learn;
}

This allows Bird to read static routes created via ip route add.

Device scan time

protocol device {
scan time 5;
}

This lets Bird detect link up/down within 5 seconds.


BGP Configuration

Basic BGP Peer (R1 ↔ R2)

Router1 (AS100)

protocol bgp R2 {
local 192.168.46.1 as 100;
neighbor 192.168.46.2 as 200;
ipv4 {
import all;
export all;
};
}

Router2 (AS200)

protocol bgp R1 {
local 192.168.46.2 as 200;
neighbor 192.168.46.1 as 100;
ipv4 {
import all;
export all;
};
}

This establishes a basic eBGP session.


BGP With Custom Filter

protocol bgp R2 {
local 192.168.46.1 as 100;
neighbor 192.168.46.2 as 200;
ipv4 {
import filter FILTER_in;
export filter FILTER_out;
};
}

Filters allow selective prefix control.


BGP Multihop

protocol bgp R2 {
local 192.168.46.1 as 100;
neighbor 192.168.46.2 as 200;
multihop;
ipv4 {
import all;
export all;
};
}

Useful when peers are not directly connected.


BGP Route Reflector Client

protocol bgp R2 {
local 192.168.46.1 as 100;
neighbor 192.168.46.2 as 200;
rr client;
rr cluster id 1.1.1.1;
ipv4 {
import all;
export all;
};
}

Enables RR functions.


Route Filtering Basics in BIRD

Route filters allow you to change attributes (Local Pref, AS-Path, Community), validate prefixes, or drop unwanted routes before they enter or leave your BGP table.

Below are simplified explanations of each example.


Local Preference

Local Preference decides which exit path your AS prefers. Higher value = more preferred.

Input:

filter R2_in {
if net = 2.2.2.2/32 then {
bgp_local_pref = 200;
accept;
}
accept;
}

This sets Local Preference 200 only for the prefix 2.2.2.2/32 coming from R2.

PrefixActionLocal Pref
2.2.2.2/32accept + modify200
all othersacceptdefault

AS Path Prepend (2×)

AS-Path Prepend makes your route less preferred by making the AS-PATH look longer.

Input:

filter R2_out {
if net = 1.1.1.1/32 then {
bgp_path.prepend(100);
bgp_path.prepend(100);
accept;
}
reject;
}

This prepends AS100 two times only on route 1.1.1.1/32.

PrefixAction
1.1.1.1/32AS100 AS100 prepended + send
all othersdrop

Add Standard Community

Communities are tags used for routing policies.

Input:

filter RO2_out {
if net = 3.3.3.3/32 then {
bgp_community.add((100,109));
accept;
}
reject;
}

This attaches community 100:109 to the outgoing BGP update.

PrefixActionCommunity Added
3.3.3.3/32accept + tag100:109
all othersrejectnone

Add Large Community

Large Communities use a 3-tuple for more structured tagging.

Input:

filter RO2_out {
if net = 4.4.4.4/32 then {
bgp_large_community.add((100,200,109));
accept;
}
reject;
}

This sends only 4.4.4.4/32 with large community 100:200:109.

PrefixActionLarge Community
4.4.4.4/32accept + tag100:200:109
all othersrejectnone

BGP with ROA Validation (RPKI)

RPKI checks whether the advertised prefix and origin AS are valid.

Function:

function is_rpki_invalid() {
if net.type = NET_IP4 then
return roa_check(rpki4, net, bgp_path.last_nonaggregated) = ROA_INVALID;
}

Filter:

filter neighbor_in {
if is_rpki_invalid() then reject;
accept;
}

This rejects IPv4 prefixes that fail ROA validation.

Prefix StatusAction
ROA INVALIDreject
VALID/UNKNOWNaccept

RPKI ROA Configuration

These lines define the RPKI tables and connection to the cache server.

Input:

roa4 table rpki4;
roa6 table rpki6;

protocol rpki cache {
roa4 { table rpki4; };
roa6 { table rpki6; };
remote 10.0.0.1 port 3323;
retry 30;
}

This:

ComponentFunction
roa4 table rpki4Stores IPv4 ROAs
roa6 table rpki6Stores IPv6 ROAs
RPKI protocol blockConnects to RPKI cache at 10.0.0.1:3323

Useful Commands

See prefixes received from neighbor

Input:

birdc show route protocol R2

Output:

BIRD 2.0.12 ready.
Table master4:
192.168.46.0/24 unicast [R2 09:46:18.875] (100) [AS200i]
via 192.168.46.2 on eth1
192.168.1.0/24 unicast [R2 09:46:18.875] (100) [AS200i]
via 192.168.46.2 on eth1

See detailed prefix info

Input:

birdc show route protocol R2 all

Output:

birdc show route protocol R2 all
BIRD 2.0.12 ready.
Table master4:
192.168.46.0/24 unicast [R2 09:46:18.875] (100) [AS200i]
via 192.168.46.2 on eth1
Type: BGP univ
BGP.origin: IGP
BGP.as_path: 200
BGP.next_hop: 192.168.46.2
BGP.local_pref: 100
192.168.1.0/24 unicast [R2 09:46:18.875] (100) [AS200i]
via 192.168.46.2 on eth1
Type: BGP univ
BGP.origin: IGP
BGP.as_path: 200
BGP.next_hop: 192.168.46.2
BGP.local_pref: 100

See chosen route to a specific prefix

Input:

birdc show route for 192.168.1.1 protocol R2 all

Output:

BIRD 2.0.12 ready.
Table master4:
192.168.1.0/24 unicast [R2 09:46:18.875] (100) [AS200i]
via 192.168.46.2 on eth1
Type: BGP univ
BGP.origin: IGP
BGP.as_path: 200
BGP.next_hop: 192.168.46.2
BGP.local_pref: 100

See exported prefixes

Input:

birdc show route export R2 all

Output:

BIRD 2.0.12 ready.
Table master4:
0.0.0.0/0 unicast [kernel1 09:46:08.875] * (10)
via 192.168.1.1 on eth0 onlink
Type: inherit univ
Kernel.source: 3
Kernel.metric: 0
192.168.46.0/24 unicast [direct2 09:46:08.875] * (240)
dev eth1
Type: device univ
192.168.1.0/24 unicast [direct2 09:46:08.875] * (240)
dev eth0
Type: device univ