Add FRRouting support to VPP Containerlab

This commit is contained in:
Pim van Pelt
2025-05-07 20:31:28 +02:00
parent dc1840a6ec
commit 49b8df9709
11 changed files with 197 additions and 41 deletions

View File

@ -7,11 +7,16 @@ one Alpine linux container, in the following topology:
![learn-vpp](learn-vpp.png)
You can deploy it using `containerlab deploy --topo vpp.clab.yml`.
This container ships with both Bird2 and FRRouting as controlplane agents.
Two relevant files for VPP are included in this repository:
You can deploy:
* Bird2: `containerlab deploy --topo vpp-bird.clab.yml`.
* FRR: `containerlab deploy --topo vpp-frr.clab.yml`.
three relevant files for VPP are included in this repository:
1. `config/vpp*/vppcfg.yaml` configures the dataplane interfaces, including a loopback address.
1. `config/vpp*/bird-local.conf` configures the controlplane to enable BFD and OSPF.
1. `config/vpp*/frr.conf` configures the controlplane to enable BFD and OSPF.
Once the lab comes up, you can SSH to the VPP containers (`vpp1` and `vpp2`) which will have your
SSH keys installed (if available). Otherwise, you can log in as user `root` using password `vpp`.

2
config/lab-frr.env Normal file
View File

@ -0,0 +1,2 @@
BIRD_ENABLED=false
FRR_ENABLED=true

34
config/vpp1/frr.conf Normal file
View File

@ -0,0 +1,34 @@
frr version 10.3
frr defaults traditional
hostname vpp1
log syslog informational
service integrated-vtysh-config
!
ip router-id 10.82.98.0
!
interface eth2
ip ospf bfd
ip ospf cost 10
ip ospf network point-to-point
ipv6 ospf6 area 0
ipv6 ospf6 bfd
ipv6 ospf6 cost 10
ipv6 ospf6 network point-to-point
exit
!
interface loop0
ip ospf passive
exit
!
router ospf
redistribute connected
network 10.82.98.0/24 area 0
exit
!
router ospf6
redistribute connected
exit
!
bfd
exit
!

31
config/vpp2/frr.conf Normal file
View File

@ -0,0 +1,31 @@
frr version 10.3
frr defaults traditional
hostname vpp2
log syslog informational
service integrated-vtysh-config
!
ip router-id 10.82.98.1
!
interface eth2
ip ospf bfd
ip ospf cost 10
ip ospf network point-to-point
ipv6 ospf6 area 0
ipv6 ospf6 bfd
ipv6 ospf6 cost 10
ipv6 ospf6 network point-to-point
exit
!
interface loop0
ip ospf passive
exit
!
router ospf
redistribute connected
network 10.82.98.0/24 area 0
exit
!
router ospf6
redistribute connected
exit
!

View File

@ -17,9 +17,16 @@ RUN pip install --break-system-packages build netaddr yamale argparse pyyaml ipa
RUN git clone https://git.ipng.ch/ipng/vppcfg.git && cd vppcfg && python3 -m build && \
pip install --break-system-packages dist/vppcfg-*-py3-none-any.whl
# Install FRR
RUN curl -s -o /usr/share/keyrings/frrouting.gpg https://deb.frrouting.org/frr/keys.gpg && \
echo deb '[signed-by=/usr/share/keyrings/frrouting.gpg]' https://deb.frrouting.org/frr bookworm frr-stable \
> /etc/apt/sources.list.d/frr.list && \
apt -y update && apt -y install frr frr-pythontools && apt clean
# Config files
COPY files/etc/vpp/* /etc/vpp/
COPY files/etc/bird/* /etc/bird/
COPY files/etc/frr/* /etc/frr/
COPY files/init-container.sh /sbin/
RUN chmod 755 /sbin/init-container.sh
CMD ["/sbin/init-container.sh"]

View File

@ -0,0 +1,17 @@
# These are the daemons that FRR will use for VPP Containerlab
# NOTE: we need to run in the 'dataplane' network namespace, and use the `dplane_fpm_nl` plugin
bgpd=yes
ospfd=yes
ospf6d=yes
bfdd=yes
ldpd=yes
vtysh_enable=yes
watchfrr_options="--netns=dataplane"
zebra_options=" -A 127.0.0.1 -s 67108864 -M dplane_fpm_nl"
bgpd_options=" -A 127.0.0.1"
ospfd_options=" -A 127.0.0.1"
ospf6d_options=" -A ::1"
staticd_options="-A 127.0.0.1"
bfdd_options=" -A 127.0.0.1"
ldpd_options=" -A 127.0.0.1"

View File

@ -0,0 +1,10 @@
# This is the VPP Containerlab default FRR configuration.
frr defaults traditional
log syslog informational
ip forwarding
ipv6 forwarding
service integrated-vtysh-config
!
ip router-id 192.0.2.1
!

View File

@ -5,6 +5,7 @@ CLAB_VPP_FILE=${CLAB_VPP_FILE:=/etc/vpp/clab.vpp}
VPPCFG_VPP_FILE=${VPPCFG_VPP_FILE:=/etc/vpp/vppcfg.vpp}
NETNS=${NETNS:="dataplane"}
BIRD_ENABLED=${BIRD_ENABLED:="true"}
FRR_ENABLED=${FRR_ENABLED:="false"}
echo "Creating dataplane namespace"
/usr/bin/mkdir -p /etc/netns/$NETNS
@ -25,6 +26,13 @@ if [ "$BIRD_ENABLED" == "true" ]; then
/usr/bin/nsenter --net=/var/run/netns/$NETNS /usr/sbin/bird -u bird -g bird
fi
if [ "$FRR_ENABLED" == "true" ]; then
echo "Starting FRRouting in $NETNS"
ROUTERID=$(ip -br a show eth0 | awk '{ print $3 }' | cut -f1 -d/)
sed -i -e "s,^ip router-id .*,ip router-id $ROUTERID," /etc/frr/frr.conf
/etc/init.d/frr start
fi
echo "Generating $CLAB_VPP_FILE"
: > $CLAB_VPP_FILE
MTU=9216

39
vpp-bird.clab.yml Normal file
View File

@ -0,0 +1,39 @@
name: learn-vpp
prefix: ""
topology:
kinds:
fdio_vpp:
image: git.ipng.ch/ipng/vpp-containerlab:latest
startup-config: config/__clabNodeName__/vppcfg.yaml
binds:
- config/__clabNodeName__/bird-local.conf:/etc/bird/bird-local.conf:ro
linux:
image: alpine:latest
nodes:
vpp1:
kind: fdio_vpp
vpp2:
kind: fdio_vpp
client1:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:01 dev eth1
- ip addr add 10.82.98.66/28 dev eth1
- ip route add 10.82.98.0/24 via 10.82.98.65
- ip addr add 2001:db8:8298:101::2/64 dev eth1
- ip route add 2001:db8:8298::/48 via 2001:db8:8298:101::1
client2:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:02 dev eth1
- ip addr add 10.82.98.82/28 dev eth1
- ip route add 10.82.98.0/24 via 10.82.98.81
- ip addr add 2001:db8:8298:102::2/64 dev eth1
- ip route add 2001:db8:8298::/48 via 2001:db8:8298:102::1
links:
- endpoints: ["vpp1:eth2", "vpp2:eth2"]
- endpoints: ["client1:eth1", "vpp1:eth1"]
- endpoints: ["client2:eth1", "vpp2:eth1"]

41
vpp-frr.clab.yml Normal file
View File

@ -0,0 +1,41 @@
name: learn-vpp
prefix: ""
topology:
kinds:
fdio_vpp:
image: git.ipng.ch/ipng/vpp-containerlab:latest
startup-config: config/__clabNodeName__/vppcfg.yaml
binds:
- config/__clabNodeName__/frr.conf:/etc/frr/frr.conf
env-files:
- config/lab-frr.env
linux:
image: alpine:latest
nodes:
vpp1:
kind: fdio_vpp
vpp2:
kind: fdio_vpp
client1:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:01 dev eth1
- ip addr add 10.82.98.66/28 dev eth1
- ip route add 10.82.98.0/24 via 10.82.98.65
- ip addr add 2001:db8:8298:101::2/64 dev eth1
- ip route add 2001:db8:8298::/48 via 2001:db8:8298:101::1
client2:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:02 dev eth1
- ip addr add 10.82.98.82/28 dev eth1
- ip route add 10.82.98.0/24 via 10.82.98.81
- ip addr add 2001:db8:8298:102::2/64 dev eth1
- ip route add 2001:db8:8298::/48 via 2001:db8:8298:102::1
links:
- endpoints: ["vpp1:eth2", "vpp2:eth2"]
- endpoints: ["client1:eth1", "vpp1:eth1"]
- endpoints: ["client2:eth1", "vpp2:eth1"]

View File

@ -1,39 +0,0 @@
name: learn-vpp
prefix: ""
topology:
kinds:
fdio_vpp:
image: git.ipng.ch/ipng/vpp-containerlab:latest
startup-config: config/__clabNodeName__/vppcfg.yaml
binds:
- config/__clabNodeName__/bird-local.conf:/etc/bird/bird-local.conf:ro
linux:
image: alpine:latest
nodes:
vpp1:
kind: fdio_vpp
vpp2:
kind: fdio_vpp
client1:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:01 dev eth1
- ip addr add 10.82.98.66/28 dev eth1
- ip route add 10.82.98.0/24 via 10.82.98.65
- ip addr add 2001:db8:8298:101::2/64 dev eth1
- ip route add 2001:db8:8298::/48 via 2001:db8:8298:101::1
client2:
kind: linux
exec:
- ip link set address 00:c1:ab:00:00:02 dev eth1
- ip addr add 10.82.98.82/28 dev eth1
- ip route add 10.82.98.0/24 via 10.82.98.81
- ip addr add 2001:db8:8298:102::2/64 dev eth1
- ip route add 2001:db8:8298::/48 via 2001:db8:8298:102::1
links:
- endpoints: ["vpp1:eth2", "vpp2:eth2"]
- endpoints: ["client1:eth1", "vpp1:eth1"]
- endpoints: ["client2:eth1", "vpp2:eth1"]

1
vpp.clab.yml Symbolic link
View File

@ -0,0 +1 @@
vpp-bird.clab.yml