eBGP between loopbacks
Loopbacks aren't only for iBGP. With two or more links to a customer or peer in another AS, a single eBGP session between loopbacks gives you the same benefits. Make R2 its own AS (64501). There's no shared IGP between different organisations, so each side uses static routes to the other's loopback, one per link.
With just the static routes and update-source, something surprising happens: the session comes up. FRR treats an eBGP neighbor as directly connected if the route to it points at a directly connected next hop, so R2's loopback counts as one hop away and the default TTL of 1 is enough. But the route isn't installed. R1 receives 203.0.113.0/24 with next hop 198.51.100.2, and because R2 is a single-hop eBGP peer, R1 insists on resolving that next hop as directly connected. A loopback isn't, so the route is marked inactive and never reaches the forwarding table. The session looks perfect and carries no traffic.
There are two fixes:
disable-connected-check: "this peer isn't on a shared subnet, but it is one hop away." The session stays at TTL 1, so a packet from further away can't reach it. Use this when the loopbacks are on routers that are directly linked, as here.ebgp-multihop <n>: raise the TTL to n. Needed when the peer's loopback really is several routers away. Prefer the smallest n that works.
On many other platforms you need one of these before the session will come up at all. On FRR (and so VyOS), you need one before the routes will be used.
With disable-connected-check on both sides, the session resets once and comes back. The route is installed via R2's loopback, which resolves to both links. One eBGP session now load-balances across two circuits.
delete protocols ospf
delete protocols bgp
set protocols static route 198.51.100.2/32 next-hop 192.0.2.1
set protocols static route 198.51.100.2/32 next-hop 192.0.2.3
set protocols bgp system-as '64500'
set protocols bgp parameters router-id '198.51.100.1'
set protocols bgp neighbor 198.51.100.2 remote-as '64501'
set protocols bgp neighbor 198.51.100.2 description 'R2 AS64501 loopback'
set protocols bgp neighbor 198.51.100.2 update-source '198.51.100.1'
set protocols bgp neighbor 198.51.100.2 address-family ipv4-unicast- Lines 1–2: Start this phase from scratch: no OSPF, no old BGP config.
- Lines 3–4: One static route to R2's loopback per link.
- Lines 7–8: R2 is now AS64501.
- Line 9: Still sourced from our loopback.
delete protocols ospf
delete protocols bgp
set protocols static route 198.51.100.1/32 next-hop 192.0.2.0
set protocols static route 198.51.100.1/32 next-hop 192.0.2.2
set protocols bgp system-as '64501'
set protocols bgp parameters router-id '198.51.100.2'
set protocols bgp neighbor 198.51.100.1 remote-as '64500'
set protocols bgp neighbor 198.51.100.1 description 'R1 AS64500 loopback'
set protocols bgp neighbor 198.51.100.1 update-source '198.51.100.2'
set protocols bgp neighbor 198.51.100.1 address-family ipv4-unicast
set protocols bgp address-family ipv4-unicast network 203.0.113.0/24- Lines 3–4: Static routes back to R1's loopback.
- Line 11: Still announcing its prefix.
vyos@R1:~$ show ip bgp summary
IPv4 Unicast Summary:
BGP router identifier 198.51.100.1, local AS number 64500 VRF default vrf-id 0
BGP table version 7
RIB entries 1, using 160 bytes of memory
Peers 1, using 30 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc
198.51.100.2 4 64501 8 12 7 0 0 00:00:32 1 1 R2 AS64501 loopback
Total number of neighbors 1
vyos@R1:~$ show bgp ipv4 203.0.113.0/24
BGP routing table entry for 203.0.113.0/24, version 7
Paths: (1 available, best #1, table default)
Advertised to peers:
198.51.100.2
64501
198.51.100.2 from 198.51.100.2 (198.51.100.2)
Origin IGP, metric 0, valid, external, best (First path received)
Last update: Sat Oct 17 00:41:26 2026
vyos@R1:~$ show ip route 203.0.113.0/24
Routing entry for 203.0.113.0/24
Known via "bgp", distance 20, metric 0
Last update 00:00:32 ago
Flags: None
Status: Changed
198.51.100.2 inactive, weight 1- Line 10: The eBGP session is Established, with one prefix received.
- Lines 19–20: BGP considers the path valid and best…
- Lines 26–28: …but zebra won't install it:
inactivenext hop, because a single-hop eBGP next hop must be directly connected.
set protocols bgp neighbor 198.51.100.2 disable-connected-check- Line 1: R2 is one hop away even though its loopback isn't on a shared subnet. R2 has the same line for 198.51.100.1.
vyos@R1:~$ show ip bgp summary
IPv4 Unicast Summary:
BGP router identifier 198.51.100.1, local AS number 64500 VRF default vrf-id 0
BGP table version 11
RIB entries 1, using 160 bytes of memory
Peers 1, using 30 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc
198.51.100.2 4 64501 18 21 11 0 0 00:00:02 1 1 R2 AS64501 loopback
Total number of neighbors 1
vyos@R1:~$ show ip route 203.0.113.0/24
Routing entry for 203.0.113.0/24
Known via "bgp", distance 20, metric 0, best
Last update 00:00:02 ago
Flags: Recursion Selected
Status: Installed
198.51.100.2 (recursive), weight 1
* 192.0.2.1, via eth0, weight 1
* 192.0.2.3, via eth1, weight 1
vyos@R1:~$ ping 203.0.113.1 count 3
PING 203.0.113.1 (203.0.113.1) 56(84) bytes of data.
64 bytes from 203.0.113.1: icmp_seq=1 ttl=64 time=2.49 ms
64 bytes from 203.0.113.1: icmp_seq=2 ttl=64 time=2.89 ms
64 bytes from 203.0.113.1: icmp_seq=3 ttl=64 time=2.99 ms
--- 203.0.113.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2010ms
rtt min/avg/max/mdev = 2.490/2.790/2.993/0.216 ms- Line 10: The session reset once when the setting changed, then came back.
- Line 19: Next hop R2's loopback…
- Lines 20–21: …via both links: one eBGP session, two circuits.
- Lines 24–26: Traffic flows.
Check your understanding
An eBGP session to a peer's loopback is Established, but show ip route lists the route as inactive. What's missing?
- The peer isn't announcing it
- disable-connected-check or ebgp-multihop
- An import route-map
- update-source