On 2/25/25 7:43 PM, MJ Ponsonby wrote: > This adds a multinode test showing ovn bgp interfacing with an external > bgp agent using frr, which learns the route to a VM and an external node > connects via the bgp peer to the VM. > > Signed-off-by: MJ Ponsonby <mj.ponso...@canonical.com> > ---
Hi MJ, > tests/multinode.at | 148 +++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 148 insertions(+) > > diff --git a/tests/multinode.at b/tests/multinode.at > index 68c9eba22..bfd8a638a 100644 > --- a/tests/multinode.at > +++ b/tests/multinode.at > @@ -3030,4 +3030,152 @@ m_as ovn-chassis-3 killall tcpdump > > AT_CLEANUP > > +AT_SETUP([ovn multinode bgp unnumbered]) > > +check_fake_multinode_setup > +cleanup_multinode_resources > + > +check m_as ovn-gw-3 ovs-vsctl del-port br-ex eth2 > + If we can't find a better way to start FRR outside the ovn-fake-multinode containers and we need to repurpose the ovn-gw-3 chassis that's fine by me I guess. But we should re-add the port on exit. I think something like this should do the trick: on_exit 'm_as ovn-gw-3 ovs-vsctl add-port br-ex eth2' > +check m_as ovn-gw-2 sed -i 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons > +check m_as ovn-gw-2 sed -i 's/StartLimitBurst=.*/StartLimitBurst=100/g' > /usr/lib/systemd/system/frr.service > +check m_as ovn-gw-2 systemctl daemon-reload > +check m_as ovn-gw-2 systemctl stop frr > + > +check m_as ovn-gw-3 sed -i 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons > +check m_as ovn-gw-3 sed -i 's/StartLimitBurst=.*/StartLimitBurst=100/g' > /usr/lib/systemd/system/frr.service > +check m_as ovn-gw-3 systemctl daemon-reload > +check m_as ovn-gw-3 systemctl restart frr > + > +check m_as ovn-gw-2 systemctl start frr > + > +echo "configure > +! > +ip prefix-list accept-all seq 5 permit any > +! > +router bgp 4200000100 > +neighbor eth2 interface remote-as external > +! > +address-family ipv4 unicast > + neighbor eth2 soft-reconfiguration inbound > + neighbor eth2 prefix-list accept-all in > +exit-address-family > +! > +address-family ipv6 unicast > + neighbor eth2 soft-reconfiguration inbound > + neighbor eth2 activate > +exit-address-family > +!" | podman exec -i ovn-gw-3 vtysh > + > +check m_as ovn-gw-2 ovs-vsctl set Open_vSwitch . > external-ids:ovn-bridge-mappings="physnet_ovn-gw-2_eth2:br-ex" > + > +check multinode_nbctl --wait=hv lr-add lr-ovn-gw-2-eth2 > +check multinode_nbctl --wait=hv set Logical_Router lr-ovn-gw-2-eth2 > options:chassis=ovn-gw-2 > +check multinode_nbctl set Logical_Router lr-ovn-gw-2-eth2 > options:dynamic-routing=true options:requested-tnl-key=10 > options:dynamic-routing-redistribute=nat > + > +check multinode_nbctl lrp-add lr-ovn-gw-2-eth2 lrp-ovn-gw-2-eth2 > 02:fb:d6:66:99:1c > +check multinode_nbctl lrp-set-options lrp-ovn-gw-2-eth2 > dynamic-routing-maintain-vrf=true > + > +check multinode_nbctl ls-add ls-ovn-gw-2-eth2 > + > +check multinode_nbctl lsp-add ls-ovn-gw-2-eth2 lsp-ovn-gw-2-eth2 > +check multinode_nbctl lsp-set-type lsp-ovn-gw-2-eth2 router > +check multinode_nbctl lsp-set-options lsp-ovn-gw-2-eth2 > router-port=lrp-ovn-gw-2-eth2 > +check multinode_nbctl lsp-set-addresses lsp-ovn-gw-2-eth2 router > + > +check multinode_nbctl lsp-add ls-ovn-gw-2-eth2 patch-ovn-gw-2-eth2 > +check multinode_nbctl lsp-set-addresses patch-ovn-gw-2-eth2 unknown > +check multinode_nbctl lsp-set-type patch-ovn-gw-2-eth2 localnet > +check multinode_nbctl --wait=hv lsp-set-options patch-ovn-gw-2-eth2 > network_name=physnet_ovn-gw-2_eth2 > + > +OVS_WAIT_UNTIL([m_as ovn-gw-2 ip link | grep -q ovnvrf10:.*UP]) > + > +check multinode_nbctl lsp-add ls-ovn-gw-2-eth2 lsp-ovn-gw-2-eth2-bgp > +check multinode_nbctl lsp-set-addresses lsp-ovn-gw-2-eth2-bgp unknown > + > +check multinode_nbctl add Logical_Router_Port lrp-ovn-gw-2-eth2 options > routing-protocols=\"BGP,BFD\" routing-protocol-redirect=lsp-ovn-gw-2-eth2-bgp > +check multinode_nbctl set Logical_Router_Port lrp-ovn-gw-2-eth2 > ipv6_ra_configs:send_periodic=true > +check multinode_nbctl set Logical_Router_Port lrp-ovn-gw-2-eth2 > ipv6_ra_configs:address_mode=slaac > +check multinode_nbctl set Logical_Router_Port lrp-ovn-gw-2-eth2 > ipv6_ra_configs:max_interval=1 > +check multinode_nbctl set Logical_Router_Port lrp-ovn-gw-2-eth2 > ipv6_ra_configs:min_interval=1 > + > +check m_as ovn-gw-2 ovs-vsctl add-port br-int eth2-bgp -- set Interface > eth2-bgp type=internal mac=\"02:fb:d6:66:99:1c\" > external-ids:iface-id=lsp-ovn-gw-2-eth2-bgp > +check m_as ovn-gw-2 ip link set dev eth2-bgp master ovnvrf10 > +check m_as ovn-gw-2 ip link set dev eth2-bgp up > + > +echo "configure > +ip prefix-list no-default seq 5 deny 0.0.0.0/0 > +ip prefix-list no-default seq 10 permit 0.0.0.0/0 le 32 > +ipv6 prefix-list no-default seq 5 deny ::/0 > +ipv6 prefix-list no-default seq 10 permit ::/0 le 128 > +vrf ovnvrf10 > +exit-vrf > +router bgp 4210000000 vrf ovnvrf10 > +bgp router-id 42.42.42.42 > +neighbor eth2-bgp interface remote-as external > +address-family ipv4 unicast > +redistribute kernel > +neighbor eth2-bgp prefix-list no-default out > +exit-address-family > +address-family ipv6 unicast > +neighbor eth2-bgp soft-reconfiguration inbound > +neighbor eth2-bgp prefix-list no-default out > +redistribute kernel > +neighbor eth2-bgp activate > +exit-address-family > +do copy running-config startup-config" | podman exec -i ovn-gw-2 vtysh > + > +# OVS_WAIT_UNTIL([m_as ovn-gw-2 vtysh -c 'show bgp vrf ovnvrf10 neighbors' | > grep 'Connections established' | sed 's/Connections established \([0-9]\+\); > dropped \([0-9]\+\)/\1-\2/' | bc | grep -q '1']) > +# OVS_WAIT_UNTIL([m_as ovn-gw-2 vtysh -c 'show bgp vrf ovnvrf10 neighbors' | > grep -qE 'Connections established \[1-9\]\[0-9\]*']) > +OVS_WAIT_UNTIL([m_as ovn-gw-2 vtysh -c 'show bgp vrf ovnvrf10 neighbors' | > grep -qE 'Connections established 1']) > + > +gw_lr="lr-ovn-gw-2-eth2" > +guest_ls="ls-guest-net" > +guest_lsp_to_lr="lsp-to-gw" > +lrp_to_guest_ls="lrp-to-guest" > +guest_lrp_ip="192.168.10.1" > +guest_lrp_cidr="$guest_lrp_ip/24" > +guest_vm_ip="192.168.10.10" > +guest_vm_cidr="$guest_vm_ip/24" > +guest_vm_iface="guest-vm" > +guest_vm_ns="ns-guest" > +lsp_name="ovn-gw-2-ns-guest-$guest_vm_iface" > + > +check multinode_nbctl lrp-add $gw_lr $lrp_to_guest_ls 02:00:ff:00:00:01 > $guest_lrp_cidr > +check multinode_nbctl ls-add $guest_ls > +check multinode_nbctl lsp-add $guest_ls $guest_lsp_to_lr > +check multinode_nbctl lsp-set-type $guest_lsp_to_lr router > +check multinode_nbctl lsp-set-options $guest_lsp_to_lr > router-port=$lrp_to_guest_ls > +check multinode_nbctl lsp-set-addresses $guest_lsp_to_lr router > + > +check multinode_nbctl lsp-add $guest_ls $lsp_name > +check multinode_nbctl lsp-set-addresses $lsp_name '00:00:02:00:01:01 > 192.168.10.10/24' > +m_as ovn-gw-2 /data/create_fake_vm.sh $lsp_name $guest_vm_ns > 00:00:02:00:01:01 1342 192.168.10.10 24 192.168.10.1 1000::3/64 1000:a/64 > + > +neighbor_lla=$(m_as ovn-gw-2 vtysh -c "show bgp vrf ovnvrf10 neighbor > eth2-bgp" | grep "^Foreign host:" | awk '{print $3}' | tr -d ',') > +check multinode_nbctl lr-route-add $gw_lr "0.0.0.0/0" $neighbor_lla > lrp-ovn-gw-2-eth2 > +check multinode_nbctl lr-nat-add $gw_lr dnat_and_snat 172.16.10.2 > 192.168.10.10 > + > +OVS_WAIT_UNTIL([m_as ovn-central-az1-1 ovn-sbctl list Advertised_Route | > grep -q 172.16.10.2]) > + > +OVS_WAIT_UNTIL([m_as ovn-gw-3 ip route | grep -q 'eth2']) > +OVS_WAIT_UNTIL([m_as ovn-gw-3 ping -W 1 -c 1 172.16.10.2]) > + > +check m_as ovn-chassis-2 ip addr add 10.42.0.10/24 dev eth1 > +check m_as ovn-gw-3 ip addr add 10.42.0.1/24 dev eth1 > +check m_as ovn-chassis-2 ip route del default > +check m_as ovn-chassis-2 ip route add default via 10.42.0.1 > + > +OVS_WAIT_UNTIL([m_as ovn-chassis-2 ping -W 1 -c 1 172.16.10.2]) > + > +check m_as ovn-chassis-2 ip route del default > +check m_as ovn-chassis-2 ip route add default via 10.88.0.1 dev eth0 proto > static metric 100 > +check m_as ovn-chassis-2 ip addr del 10.42.0.10/24 dev eth1 > +check m_as ovn-gw-3 ip addr del 10.42.0.1/24 dev eth1 > + > +check m_as ovn-gw-3 systemctl stop frr > +check m_as ovn-gw-2 systemctl stop frr > +check m_as ovn-gw-3 ovs-vsctl add-port br-ex eth2 > +check m_as ovn-gw-2 ovs-vsctl del-port br-int eth2-bgp All these cleanups should be done with "on_exit" before we have the chance to fail the test. > + > +AT_CLEANUP I was playing around and tried to start the "external" BGP directly in the host in a namespace. I got the sessions to establish and the routes are advertised but I probably messed up something in the datapath as traffic doesn't flow correctly. It's also not so nice because I just change the default frr configuration on the host. But maybe it's possible to start frr with a custom config instead. In any case, maybe this helps: https://github.com/dceara/ovn/commit/a078ae0f565918d40397e28bdd168c0caac7ac08 Again, if it's way too complicated to start the external speaker on the host, I'm ok with repurposing one of the fake-multinode chassis. Regards, Dumitru _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev