Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 45 additions & 120 deletions smoke/bgp_frr_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,158 +2,83 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Andrea Panattoni

# This test leverages the following architecture to test the BGP route exchange between an
# FRR+Grout setup and a pure FRR BGP peer. At the end of the configuration phase, Host-A
# and Host-B must be able to ping each other, as the respective default gateway routers
# have learned the correct routes.
# This test leverages the following architecture to test the BGP route exchange
# between an FRR+Grout setup and a pure FRR BGP peer. At the end of the
# configuration phase, grout must be able to ping the loopback interface in the
# "bgp-peer" namespace since grout has learned the BGP route.
#
#
# ┌────────────────────────────────┐ ┌──────────────────────────────────┐
# │ │ │ │
# │ │ │ << System under test >> │
# │ │ │ │
# │ frr-bgp-peer │ │ FRR + Grout │
# │ │ │ │
# │ ┌───────────┐ ┌────────────┐ │ │ ┌────────────┐ ┌────────────┐ │
# │ │ to-host-a │ │ p0 │ │ │ │ p0 │ │ p1 │ │
# └─┤ ├───┤ ├─┘ └─┤ ├────┤ ├─┘
# │ 16.0.0.1 │ │ 172.16.0.1 │ │ 172.16.0.1 │ │ 16.1.0.1 │
# └────┬──────┘ └─────────┬──┘ └──┬─────────┘ └────┬───────┘
# │ │ │ │
# │<<veth>> │ │ <<tap>>│
# │ │ <<tap>> │ │
# ┌────┴─────┐ └────────────────┘ ┌────┴─────┐
# │ eth0 │ │ eth0 │
# ┌─│ ├─┐ ┌─│ ├─┐
# │ │ 16.0.0.2 │ │ │ │ 16.1.0.2 │ │
# │ └──────────┘ │ <----- PING -----> │ └──────────┘ │
# │ Host-A │ │ Host-B │
# └──────────────┘ └──────────────┘
#

# .-------------------.
# | netns "bgp-peer" |
# .-------..-------------. | .------. |
# | zebra || grout | | | bgpd | |
# '-------'| | | '------' |
# .------. | .------------. .------------. .-------. |
# | bgpd | | | p0 | net_tap | x-p0 | | zebra | |
# '------' | | +---------------+ | '-------' |
# .----------. | 172.16.0.1 | | 172.16.0.2 |.----------. |
# | gr-loop0 | '------------' '------------'| lo | |
# '----------' | | | | |
# | ping <------------------------------------> | 16.0.0.1 | |
# | | | '----------' |
# '-------------' '-------------------'

. $(dirname $0)/_init_frr.sh

create_interface p0

# Avoid systemd-networkd to override the gr-loop0 MAC address
if [ -d /etc/systemd/network/ ]; then
cat <<EOF >> /etc/systemd/network/10-gr-loop-no-mac-address.link
[Match]
OriginalName=gr-loop*

[Link]
MACAddressPolicy=none
EOF

udevadm control --reload-rules
fi

create_interface p0 mac f0:0d:ac:dc:00:00
create_interface p1 mac f0:0d:ac:dc:00:01

netns_add ns-a
netns_add ns-b

# Configure Host-B
ip link set p1 netns ns-b
ip -n ns-b link set p1 address ba:d0:ca:ca:00:01
ip -n ns-b link set p1 up
ip -n ns-b addr add 16.1.0.2/24 dev p1
ip -n ns-b route add default via 16.1.0.1
ip -n ns-b addr show

set_ip_address p1 16.1.0.1/24
set_ip_address p0 172.16.0.1/24

# Create and start an FRR instance for the BGP peer
frr_bgp_peer_namespace="frr-bgp-peer"
start_frr_on_namespace $frr_bgp_peer_namespace
ip link set p0 netns $frr_bgp_peer_namespace

ip -n ns-a link add eth0 type veth peer name to-host-a
ip -n ns-a link set to-host-a up
ip -n ns-a link set eth0 up

# Configure Host-A
ip -n ns-a link set eth0 address ba:d0:ca:ca:00:02
ip -n ns-a link set eth0 up
ip -n ns-a addr add 16.0.0.2/24 dev eth0
ip -n ns-a route
ip -n ns-a addr show
ip -n ns-a route add default via 16.0.0.1

start_frr_on_namespace bgp-peer
ip link set x-p0 netns bgp-peer

# Configure FRR BGP peer router
ip -n ns-a link set to-host-a netns $frr_bgp_peer_namespace
vtysh -N bgp-peer <<-EOF
configure terminal

vtysh -N $frr_bgp_peer_namespace <<-EOF
configure terminal
interface x-p0
ip address 172.16.0.2/24
exit

interface p0
ip address 172.16.0.2/24
exit
interface lo
ip address 16.0.0.1/24
exit

interface to-host-a
ip address 16.0.0.1/24
exit
router bgp 64512
bgp router-id 172.16.0.2

router bgp 43
no bgp ebgp-requires-policy
no bgp network import-check

neighbor 172.16.0.1 remote-as 44
neighbor 172.16.0.1 remote-as 64512

address-family ipv4 unicast
network 16.0.0.0/24
network 172.16.0.0/24
network 16.0.0.0/24
exit-address-family
exit
exit
EOF


# Configure Grout loopback to work with BGP
ip addr add 172.16.0.1/32 dev gr-loop0
ip addr add 16.1.0.1/32 dev gr-loop0
ip route add 172.16.0.0/24 dev gr-loop0 via 172.16.0.1
ip route add 16.1.0.0/24 dev gr-loop0 via 16.1.0.1

# Configure Grout FRR instance
vtysh <<-EOF
configure terminal
configure terminal

router bgp 44
router bgp 64512
bgp router-id 172.16.0.1
no bgp ebgp-requires-policy
no bgp network import-check

neighbor 172.16.0.2 remote-as 43
neighbor 172.16.0.2 remote-as 64512
neighbor 172.16.0.2 update-source 172.16.0.1
neighbor 172.16.0.2 interface gr-loop0
neighbor 172.16.0.2 ip-transparent

address-family ipv4 unicast
network 16.1.0.0/24
network 172.16.0.0/24
exit-address-family
exit
exit
EOF

# Wait for BGP routes to be exchanged
SECONDS=0
expected_route_line="16.0.0.0/24[[:space:]]+type=L3.*origin=zebra"
while ! grcli route show | grep -qE "${expected_route_line}"; do
if [ "$SECONDS" -ge "10" ]; then
attempts=0
while ! grcli route show | grep -qE '16.0.0.0/24[[:space:]]+\<bgp\>'; do
if [ "$attempts" -ge 40 ]; then
fail "BGP route not learned in Grout"
fi
sleep 0.5
attempts=$((attempts + 1))
done

expected_frr_bgp_peer_route_line="B>\* 16.1.0.0/24"
while ! vtysh -N $frr_bgp_peer_namespace -c "show ip route" | grep -q "${expected_frr_bgp_peer_route_line}"; do
if [ "$SECONDS" -ge "10" ]; then
fail "BGP route not learned in FRR BGP Peer"
fi
sleep 0.5
done

# Verify host-a can ping host-b
ip netns exec ns-a ping -i0.01 -c3 -n 16.1.0.2
ip netns exec ns-b ping -i0.01 -c3 -n 16.0.0.2
grcli ping 16.0.0.1 count 3 delay 10