Testing bgpipe with netlab
Ever since Pawel Foremski talked about BGP Pipe @ RIPE88 meeting, I wanted to kick its tires in netlab. BGP Pipe is a Go executable that runs under Linux (but also FreeBSD or MacOS), so I could add a Linux VM (or container) to a netlab topology and install the software after the lab has been started. However, I wanted to have the BGP neighbor configured on the other side of the link (on the device talking with the BGP Pipe daemon).
I could solve the problem in a few ways:
- Use an existing BGP daemon like BIRD and tweak its settings and the configuration files;
- Start the lab topology without BGP and configure BGP manually;
- Define a new device and tell netlab it supports BGP.
However, there’s another neat trick (that I used in the very first BGP lab exercise): define bgp to be a generic node attribute without any data validation. That allows me to configure BGP AS on a device that does not support BGP, tricking netlab into configuring the BGP neighbors on adjacent devices.
Here’s the lab topology I used:
defaults.attributes.node.bgp:
provider: clab
defaults.devices.linux.group_vars.docker_shell: bash
nodes:
rtr:
module: [ bgp ]
device: frr
bgp.as: 65000
probe:
device: linux
image: netlab/bgpipe:latest
bgp.as: 65100
links:
- rtr:
probe:
The solution’s crux is the first line: tell netlab any node can have bgp attributes (otherwise, netlab requires a node with bgp attributes to use the BGP configuration module).
The rest of the configuration should be self-evident if you used netlab in the past:
- The lab is using containers (line 3)
- We should be using bash as the shell on the Linux containers (line 4)
- The lab has a router running BGP on FRRouting. It has BGP AS number 65000 (lines 7-10)
- The other node in the lab is a Linux host using the
netlab/bgpipe:latest
container image. It’s expected to have BGP AS number 65100 (lines 11-14) - The lab topology has a single link with both nodes attached to it.
I could have used the Ubuntu container image and installed bgpipe every time the lab started, but I decided it would be better to build a new container image (netlab/bgpipe:latest
) and use that. The Dockerfile
is trivial:
- It takes the baseline Ubuntu image
- It installs a few utilities
- It downloads bgpipe executable into
/usr/local/bin
1
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
LABEL maintainer="Netlab project <netlab.tools>"
LABEL description="bgpipe container"
RUN apt-get update && \
apt-get install -y bash iputils-ping net-tools iproute2 wget jq && \
wget https://github.com/bgpfix/bgpipe/releases/download/v0.8.8/bgpipe-linux-amd64 -q -O /usr/local/bin/bgpipe && \
chmod a+x /usr/local/bin/bgpipe
WORKDIR /root
CMD /usr/bin/bash
After spending a few seconds building the container, I was ready to test the lab. After the few seconds it took netlab up to start the lab (FRRouting starts ridiculously fast), I was able to log into the Linux container and establish a BGP session with the router:
$ netlab connect probe
Connecting to container clab-bgpipe-probe, starting bash
root@probe:~# bgpipe -o speaker --asn 65100 172.16.0.1
2024-08-11 15:03:31 INF dialing 172.16.0.1:179 stage="[2] connect"
2024-08-11 15:03:31 INF connected 172.16.0.2:54132 -> 172.16.0.1:179 stage="[2] connect"
["L",1,"2024-08-11T15:03:31.615",97,"OPEN",{"bgp":4,"asn":65000,"id":"10.0.0.1","hold":9,"caps":{"MP":["IPV4/UNICAST"],"ROUTE_REFRESH":true,"EXTENDED_MESSAGE":true,"GRACEFUL_RESTART":"0xc078","AS4":65000,"ADDPATH":"0x00010101","ENHANCED_ROUTE_REFRESH":true,"LLGR":"0x00010180000000","FQDN":{"host":"rtr"},"VERSION":"0x144652526f7574696e672f31302e302e315f676974"}},{}]
["R",1,"2024-08-11T15:03:31.615",-1,"OPEN",{"bgp":4,"asn":65100,"id":"10.0.0.0","hold":90,"caps":{"MP":["IPV4/UNICAST","IPV4/FLOWSPEC","IPV6/UNICAST","IPV6/FLOWSPEC"],"ROUTE_REFRESH":true,"EXTENDED_MESSAGE":true,"AS4":65100}},{}]
["R",2,"2024-08-11T15:03:31.615",0,"KEEPALIVE",null,{}]
["L",2,"2024-08-11T15:03:31.615",0,"KEEPALIVE",null,{}]
2024-08-11 15:03:31 INF negotiated session capabilities caps="{\"MP\":[\"IPV4/UNICAST\"],\"ROUTE_REFRESH\":true,\"EXTENDED_MESSAGE\":true,\"AS4\":65100}"
2024-08-11 15:03:31 INF event bgpfix/pipe.ESTABLISHED seq=15 vals=[1723388611]
["L",3,"2024-08-11T15:03:32.716",37,"UPDATE",{"reach":["10.0.0.1/32"],"attrs":{"ORIGIN":{"flags":"T","value":"IGP"},"ASPATH":{"flags":"TX","value":[65000]},"NEXTHOP":{"flags":"T","value":"172.16.0.1"},"MED":{"flags":"O","value":0}}},{}]
["R",3,"2024-08-11T15:03:34.616",0,"KEEPALIVE",null,{}]
["L",4,"2024-08-11T15:03:34.616",0,"KEEPALIVE",null,{}]
["R",4,"2024-08-11T15:03:37.616",0,"KEEPALIVE",null,{}]
["L",5,"2024-08-11T15:03:37.616",0,"KEEPALIVE",null,{}]
As always, you can find the source code on GitHub, and you can start the lab in GitHub Codespaces:
- After starting the codespace, change the working directory to
BGP/bgpipe
- Execute
docker build . -t netlab/bgpipe:latest
to build the container with bgpipe - Execute
netlab up
to start the lab.
-
Hint: downloading an executable from the Internet and running it as root is probably not a good security practice. At least I can pretend I downloaded it from a reputable site (GitHub). ↩︎