Skip to content

autocracy/bgp-tables

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bgp-table

A Docker-based lab that loads a full live BGP table (IPv4 + IPv6) into a BIRD2 router for policy experimentation. Routes are sourced from RouteViews MRT RIB dumps, aggregated by origin AS, and injected via a native BGP implementation written in Rust. The original Python test was 3x slower to process the dump files and the ExaBGP speaker crawled, hence the Rust port.

Why

The primary use case is traffic engineering by origin AS: assign higher local-preference to prefixes from a specific origin AS to steer outbound traffic toward a preferred interface without managing static routes.

# bird.conf — prefer Google (AS15169) out interface A
if bgp_path.last = 15169 then bgp_local_pref = 200;

Architecture

┌─────────────────────────────────────────┐
│  bgp-feeder (172.28.0.3)                │
│                                         │
│  feeder-rs                              │
│  ├── downloads RouteViews MRT RIB dump  │
│  ├── aggregates prefixes by origin AS   │
│  └── injects via native BGP session ───────────┐
└─────────────────────────────────────────┘       │ BGP (port 179)
                                                  ▼
┌─────────────────────────────────────────┐
│  bgp-router (172.28.0.2)                │
│                                         │
│  BIRD2                                  │
│  ├── master4  ~400k IPv4 prefixes       │
│  └── master6   ~92k IPv6 prefixes       │
└─────────────────────────────────────────┘

feeder-rs (Rust):

  • Fetches the latest 2-hour MRT RIB slot from route-views2 (IPv4) and route-views6 (IPv6)
  • Caches downloads to ./rib-cache/ so container restarts skip the download
  • Aggregates ~1M raw prefixes down to ~493k by collapsing adjacent and covered prefixes per origin AS
  • Connects directly to BIRD on port 179 and announces routes as BGP UPDATEs, sending keepalives inline every 5,000 routes
  • After the initial table load the session is kept alive with periodic keepalives

BIRD2: holds the full table in memory (≈ 2 GB). Nothing is installed in the kernel routing table — it's a policy/lookup engine only.

Quick start

docker compose up -d
docker exec bgp-router birdc 'show protocols all feeder'
# wait ~5 min for the initial download + announcement, then:
docker exec bgp-router birdc 'show route count'

Expected output after loading:

master4: 400257 routes
master6:  92329 routes

Setting local-preference by origin AS

Edit bird.conf and add rules inside filter set_local_pref:

filter set_local_pref {
    bgp_local_pref = 100;   # default

    if bgp_path.last = 15169 then bgp_local_pref = 200;  # Google  → prefer ifA
    if bgp_path.last = 32934 then bgp_local_pref = 200;  # Meta    → prefer ifA
    if bgp_path.last = 16509 then bgp_local_pref = 50;   # AWS     → prefer ifB

    accept;
}

Then reload BIRD without restarting:

docker exec bgp-router birdc configure

Requirements

  • Docker + Docker Compose
  • ~2 GB RAM for the BIRD container (full IPv4+IPv6 table)
  • ~200 MB disk for cached MRT dumps (./rib-cache/)

Network layout

Container IPv4 IPv6 AS
bgp-router 172.28.0.2 fd00:dead:beef::2 64512
bgp-feeder 172.28.0.3 fd00:dead:beef::3 65001

Useful BIRD commands

# Session state
docker exec bgp-router birdc 'show protocols all feeder'

# Route count
docker exec bgp-router birdc 'show route count'

# Routes from a specific origin AS (e.g. Google)
docker exec bgp-router birdc 'show route where bgp_path.last = 15169'

# Reload config (e.g. after editing local-pref rules)
docker exec bgp-router birdc configure

How feeder-rs works

  1. URL selection — computes the latest completed 2-hour RouteViews slot (e.g. rib.20260402.0600.bz2), backing off one slot if the file is less than 30 minutes old to avoid partial uploads.
  2. Caching — downloads to ./rib-cache/{collector}.{filename} and skips the download on subsequent runs if the file is present.
  3. Parsing — uses bgpkit-parser to stream-parse the bz2 MRT file, deduplicating prefixes and grouping by origin AS.
  4. Aggregation — for each origin AS, sorts prefixes and iteratively merges adjacent sibling pairs (e.g. 10.0.0.0/25 + 10.0.0.128/2510.0.0.0/24) and removes covered prefixes, reducing the table size by roughly 50%.
  5. BGP injection — opens a TCP connection to BIRD on port 179, exchanges OPEN/KEEPALIVE, then streams BGP UPDATE messages. Keepalives are sent inline every 5,000 routes so the hold timer never expires during the initial flood.

Data sources

  • IPv4: archive.routeviews.org/route-views2/bgpdata/
  • IPv6: archive.routeviews.org/route-views6/bgpdata/

RouteViews publishes new RIB snapshots every 2 hours. The feeder loads the most recent available snapshot at startup and holds it until the container is restarted.

About

Download and modify public BGP exports to announce into your own system for policy work

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors