Verify end to end
With everything committed, check each layer from the bottom up: interfaces, sessions, what you send, what you receive, what you chose, and what actually forwards.
show ip bgp neighbors <peer> received-routes shows everything the neighbor sent (that's what soft-reconfiguration is for). show ip bgp neighbors <peer> routes shows only what survived your import policy. The difference between them is your filter at work.
Then prove the forwarding path from a host on the LAN. Traffic to the IX member's network should go out eth1 straight to 192.0.2.40. Everything else should follow the default route out eth0 to the upstream.
Finally, look at what VyOS actually handed to FRR. VyOS translates the set tree into FRR configuration, and it changes a few FRR defaults along the way. Those defaults explain behaviour you'll otherwise trip over.
vyos@R1:~$ show ip route 203.0.113.65
Routing entry for 203.0.113.64/26
Known via "bgp", distance 20, metric 0, best
Last update 00:00:35 ago
Flags: Selected
Status: Installed
* 192.0.2.40, via eth1, weight 1
vyos@R1:~$ show ip route 203.0.113.130
Routing entry for 203.0.113.128/25
Known via "bgp", distance 20, metric 0, best
Last update 00:00:35 ago
Flags: Selected
Status: Installed
* 203.0.113.0, via eth0, weight 1- Lines 1–7: An address in the IX member's /26: out eth1, directly to the member.
- Lines 9–15: An address behind the upstream: out eth0, to the upstream.
root@host:~# traceroute -n 203.0.113.65
traceroute to 203.0.113.65 (203.0.113.65), 30 hops max, 60 byte packets
1 198.51.100.1 8.710 ms 9.259 ms 9.308 ms
2 203.0.113.65 16.023 ms 16.007 ms 15.999 ms
root@host:~# traceroute -n 203.0.113.130
traceroute to 203.0.113.130 (203.0.113.130), 30 hops max, 60 byte packets
1 198.51.100.1 0.645 ms 0.625 ms 0.678 ms
2 203.0.113.130 1.665 ms 1.664 ms 1.659 ms- Line 3: Hop 1 is R1, the host's default gateway, in both cases.
- Line 4: The member answers directly at hop 2: no extra hop through the route server.
- Line 8: The upstream's address, also one hop past R1.
vyos@R1:~$ vtysh -c 'show running-config bgpd'
...
router bgp 64500
bgp router-id 198.51.100.1
no bgp ebgp-requires-policy
no bgp reject-as-sets
no bgp default ipv4-unicast
no bgp network import-check
neighbor 192.0.2.1 remote-as 64511
neighbor 192.0.2.1 description IX route server 1
no neighbor 192.0.2.1 enforce-first-as
neighbor 203.0.113.0 remote-as 64496
neighbor 203.0.113.0 description UPSTREAM transit
no neighbor 203.0.113.0 enforce-first-as
!
address-family ipv4 unicast
network 198.51.100.0/24
neighbor 192.0.2.1 activate
neighbor 192.0.2.1 soft-reconfiguration inbound
neighbor 192.0.2.1 maximum-prefix 100
neighbor 192.0.2.1 route-map IX-IN in
neighbor 192.0.2.1 route-map IX-OUT out
neighbor 203.0.113.0 activate
neighbor 203.0.113.0 soft-reconfiguration inbound
neighbor 203.0.113.0 maximum-prefix 1000
neighbor 203.0.113.0 route-map TRANSIT-IN in
neighbor 203.0.113.0 route-map TRANSIT-OUT out
exit-address-family
exit
!
end- Line 5: FRR normally refuses to exchange routes on eBGP sessions with no policy (RFC 8212). VyOS turns that off, which is why routes flowed before we added import maps.
- Line 8: FRR normally only originates a
networkif a matching route exists. VyOS turns that check off, so the blackhole is about forwarding, not about announcing. - Line 11: VyOS also disables enforce-first-as per neighbor. That matters for route servers: their routes don't start with the route server's AS. (The FRR member in this lab needed
no bgp enforce-first-asset by hand.) - Lines 16–27: The
settree, rendered as FRR address-family configuration.
vyos@R1:~$ show configuration commands | match "interfaces ethernet eth|protocols|policy|host-name"
set interfaces ethernet eth0 address '203.0.113.1/31'
set interfaces ethernet eth0 description 'TRANSIT-UPSTREAM'
set interfaces ethernet eth0 hw-id '52:54:00:00:00:01'
set interfaces ethernet eth1 address '192.0.2.25/24'
set interfaces ethernet eth1 description 'IX-PEERING-LAN'
set interfaces ethernet eth1 hw-id '52:54:00:00:01:01'
set interfaces ethernet eth2 address '198.51.100.1/25'
set interfaces ethernet eth2 description 'LAN'
set interfaces ethernet eth2 hw-id '52:54:00:00:02:01'
set policy prefix-list BOGONS rule 10 action 'permit'
set policy prefix-list BOGONS rule 10 le '32'
set policy prefix-list BOGONS rule 10 prefix '0.0.0.0/8'
set policy prefix-list BOGONS rule 20 action 'permit'
set policy prefix-list BOGONS rule 20 le '32'
set policy prefix-list BOGONS rule 20 prefix '10.0.0.0/8'
set policy prefix-list BOGONS rule 30 action 'permit'
set policy prefix-list BOGONS rule 30 le '32'
set policy prefix-list BOGONS rule 30 prefix '100.64.0.0/10'
set policy prefix-list BOGONS rule 40 action 'permit'
set policy prefix-list BOGONS rule 40 le '32'
set policy prefix-list BOGONS rule 40 prefix '127.0.0.0/8'
set policy prefix-list BOGONS rule 50 action 'permit'
set policy prefix-list BOGONS rule 50 le '32'
set policy prefix-list BOGONS rule 50 prefix '169.254.0.0/16'
set policy prefix-list BOGONS rule 60 action 'permit'
set policy prefix-list BOGONS rule 60 le '32'
set policy prefix-list BOGONS rule 60 prefix '172.16.0.0/12'
set policy prefix-list BOGONS rule 70 action 'permit'
set policy prefix-list BOGONS rule 70 le '32'
set policy prefix-list BOGONS rule 70 prefix '192.168.0.0/16'
set policy prefix-list BOGONS rule 80 action 'permit'
set policy prefix-list BOGONS rule 80 le '32'
set policy prefix-list BOGONS rule 80 prefix '224.0.0.0/3'
set policy prefix-list OUR-PREFIXES rule 10 action 'permit'
set policy prefix-list OUR-PREFIXES rule 10 prefix '198.51.100.0/24'
set policy prefix-list OUR-PREFIXES-ANY rule 10 action 'permit'
set policy prefix-list OUR-PREFIXES-ANY rule 10 le '32'
set policy prefix-list OUR-PREFIXES-ANY rule 10 prefix '198.51.100.0/24'
set policy route-map IX-IN rule 10 action 'deny'
set policy route-map IX-IN rule 10 match ip address prefix-list 'BOGONS'
set policy route-map IX-IN rule 20 action 'deny'
set policy route-map IX-IN rule 20 match ip address prefix-list 'OUR-PREFIXES-ANY'
set policy route-map IX-IN rule 30 action 'permit'
set policy route-map IX-IN rule 30 set local-preference '150'
set policy route-map IX-OUT rule 10 action 'permit'
set policy route-map IX-OUT rule 10 match ip address prefix-list 'OUR-PREFIXES'
set policy route-map IX-OUT rule 100 action 'deny'
set policy route-map TRANSIT-IN rule 10 action 'deny'
set policy route-map TRANSIT-IN rule 10 match ip address prefix-list 'BOGONS'
set policy route-map TRANSIT-IN rule 20 action 'deny'
set policy route-map TRANSIT-IN rule 20 match ip address prefix-list 'OUR-PREFIXES-ANY'
set policy route-map TRANSIT-IN rule 30 action 'permit'
set policy route-map TRANSIT-IN rule 30 set local-preference '100'
set policy route-map TRANSIT-OUT rule 10 action 'permit'
set policy route-map TRANSIT-OUT rule 10 match ip address prefix-list 'OUR-PREFIXES'
set policy route-map TRANSIT-OUT rule 100 action 'deny'
set protocols bgp address-family ipv4-unicast network 198.51.100.0/24
set protocols bgp neighbor 192.0.2.1 address-family ipv4-unicast maximum-prefix '100'
set protocols bgp neighbor 192.0.2.1 address-family ipv4-unicast route-map export 'IX-OUT'
set protocols bgp neighbor 192.0.2.1 address-family ipv4-unicast route-map import 'IX-IN'
set protocols bgp neighbor 192.0.2.1 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp neighbor 192.0.2.1 description 'IX route server 1'
set protocols bgp neighbor 192.0.2.1 remote-as '64511'
set protocols bgp neighbor 203.0.113.0 address-family ipv4-unicast maximum-prefix '1000'
set protocols bgp neighbor 203.0.113.0 address-family ipv4-unicast route-map export 'TRANSIT-OUT'
set protocols bgp neighbor 203.0.113.0 address-family ipv4-unicast route-map import 'TRANSIT-IN'
set protocols bgp neighbor 203.0.113.0 address-family ipv4-unicast soft-reconfiguration inbound
set protocols bgp neighbor 203.0.113.0 description 'UPSTREAM transit'
set protocols bgp neighbor 203.0.113.0 remote-as '64496'
set protocols bgp parameters router-id '198.51.100.1'
set protocols bgp system-as '64500'
set protocols static route 198.51.100.0/24 blackhole
set protocols static route 198.51.100.0/24 description 'Anchor our aggregate; discard unused space'
set system host-name 'R1'
set system login operator-group default command-policy allow '*'- Line 4:
hw-idbinds each interface name to a MAC. VyOS adds it automatically on first boot.