How to deploy a BGP route generator? | Containerlab | ExaBGP

Hi all!

The blog post is sort of "How to ...?"


Some time ago I needed to prepare a lab environment where I should have to simulate a huge amount of BGP updates between routers.  How can we arrange that? The main thing is how to generate a lot of BGP updates? As I see we have two ways:

  • VM with network OS from classic vendors (Cisco, Juniper, Nokia);
  • Linux BGP daemon
Sure, BGP daemons are more scalable and suitable for lab purposes. And a lot of companies use them in production (in most cases as BGP RR). Of course, I knew about different Linux BGP daemons but didn't have experience with them. This time I followed the next simple workflow in the tech world - don't know something? Let's Googling! (don't use this way in the production environment - firstly, read tech books, user guides, RFC, etc :) )

This way I've found all that I need:

1) BGP daemon. I decided to use ExaBGP
2) Route generator. It's a simple python script route-smash that uses ExaBGP API.

As a lab environment, I'm using Containerlab. Don't know what more I can add about Containerlab. If you don't use it - I highly recommend trying. In my opinion and experience, it's the best tool for network labs.  Kudos to the development team!

Lab steps

1) ExaBGP instance

Let's create ExaBGP instance. It will be a reference for the further route generators. 

a) ExaBGP installation
The project has several installation ways. You can use a suitable way for you (check README). 
I decided to clone the project.

Clone to any dir, further we will copy the project to Docker containers.

git clone exabgp

b) ExaBGP configuration
We're creating configuration as a template this time.

Config file has path:


Config file example (We will modify it for every BGP speaker.)

process gen_routes {
	run ./usr/bin/python3 /home/;
	encoder text;

template {
        neighbor test {
                local-as 65000;
                peer-as 65000;
		api {
			processes [ gen_routes ];

neighbor {
        inherit test;

c) environment file
We should add one option to the environment file. Another way we will get stuck ExaBGP during route generation (I'd faced with the issue)

cat exabgp/etc/exabgp/exabgp.env
ack = false

2) Route-smash

Clone route-smash project. The script is simple, but it's an advantage. Every engineer can modify it for any needs (e.g. modify route count or route generation speed). Thanks a lot, @Benjamin_Dale.
Just clone to any dir.

git clone

3) Lab environment

Containerlab has great documentation. I just mention some points of lab preparation.

Here's lab topology

a) lab description
The important point is adding "bind" parameter to the Linux container description. It helps to mount dirs from the host.
Let's mount host files to the container. The target path will be "/home

My example
name: BGP_gen

      kind: vr-sros
      image: vrnetlab/vr-sros:20.10.R1
      type: sr-1
      license: license.key
      kind: vr-sros
      image: vrnetlab/vr-sros:20.10.R1
      type: sr-1
      license: license.key
      kind: vr-sros
      image: vrnetlab/vr-sros:20.10.R1
      type: sr-1
      license: license.key
      kind: vr-sros
      image: vrnetlab/vr-sros:20.10.R1
      type: sr-1
      license: license.key
      kind: linux
      image: alpine:latest
       - BGP_gen1:/home
      kind: linux
      image: alpine:latest
       - BGP_gen2:/home
    - endpoints: ["P1:eth1", "P2:eth1"]
    - endpoints: ["P1:eth2", "P3:eth1"]
    - endpoints: ["P2:eth2", "P4:eth1"]
    - endpoints: ["P3:eth2", "P4:eth2"]
    - endpoints: ["BGP_gen1:eth1", "P1:eth3"]
    - endpoints: ["BGP_gen2:eth1", "P4:eth3"]

b) project tree

We should create folders BGP_gen1 and BGP_gen2. We can put here any files that we need and they will be available inside containers:
  • exabgp - it's ExaBGP project;
  • - it's the script from route-smash
  • - it's a tiny bash script for container deploying. It will be described further.
My example
├── BGP_gen1
│   ├──
│   ├── exabgp
│   └──
├── BGP_gen2
│   ├──
│   ├── exabgp
│   └──
├── BGP_gen.yml
├── clab-BGP_gen
│   ├── ansible-inventory.yml
│   ├── P1
│   ├── P2
│   ├── P3
│   └── P4
└── license.key

4) Container preparing

The linux node should have python3 and network configuration. Also, we should modify dir owner - /home.
 We can create a simple script for every linux node.

My example
cat BGP_gen1/ 
apk add python3
chown root:root /home
ip address add dev eth1

cat BGP_gen2/ 
apk add python3
chown root:root /home
ip address add dev eth1

5) ExaBGP start

In this step, I just show how we can start ExaBGP daemon. As Containerlab successfully started we can jump inside containers.

sudo docker exec -it clab-BGP_gen-BGP_gen1 ash

/ # /home/

Then we can start ExaBGP. At the first time, we can disable the route generation script for pure BGP testing. And after that come back to the API calls.

ExaBGP start
/home/exabgp/sbin/exabgp /home/exabgp/etc/exabgp.conf 

6) Testing

Every case has its own goals. And I think my testing outputs and routers configuration couldn't be useful. 
But as an example, I'll leave these here.

A:P1# show router 100 bgp summary neighbor | match "BGP Summary" post-lines 15 
BGP Summary
Legend : D - Dynamic Neighbor
                   AS PktRcvd InQ  Up/Down   State|Rcv/Act/Sent (Addr Family)
                      PktSent OutQ
               65000    10006    0 00h04m17s 250000/250000/0 (IPv4)
                           12    0           

250K BGP routes - not bad! :)


The architecture of my lab is simple, but it is suitable for my purposes. And I've made sure that Containerlab ideology is the best way for creating network environments. Especially when we use any Linux tools, daemons, etc. As a result, we get a reproducible and lightweight testing environment.
As for ExaBGP, I just looked inside a bit. It has more powerful possibilities for BGP steering than I use. I will come back to ExaBGP as required for any other investigation of BGP stack.