:: Table of content
- Intro
- Testdrive
- Checks
- Turn it on
- Conclusion
:: Intro
Back in 2019 when I studied for my CCNP service Provider SPROUTE, I learned about IOS-XR and when we enable BGP and set up the sessions, nothing happens. We always need a route policy to enable advertisement and reception of prefix information.
The official statement is:
“IOS XR requires a routing policy to be associated with an EBGP peer as a security measure to ensure that routes are not accidentally accepted or advertised. If a route policy is not configured in the appropriate address-family, then NLRIs are discarded upon receipt and no NLRIs are advertised to EBGP peers.”
So, we have BGP route security to prevent nasty things with wrong regex implementations.

A typical network engineer in an equipment room after changing a BGP policy the wrong way.
Very and very recently, like 10 days ago, I saw this tweet from my friend David at CiscoL!ve 2024 in Las Vegas:

Cisco has “secretly” added a gem in IOS-XE from version 17.2.1 and we didn’t knew it.

:: Testdrive
My beast machine was asleep for a few days but was hungry to test this shorty.
Let’s setup a the simplest BGP topology ever:

We have set up a point-to-point public transit between the routers and added a Loopback0 interface on both sides with each a unique network subnet and advertise both networks with a network statement.
Let’s show the basic configurations of both routers:
============= C8Kv-1 Configurations =============
Current configuration : 5938 bytes
!
! Last configuration change at 20:38:00 UTC Fri Jun 7 2024
!
version 17.5
service timestamps debug datetime msec
service timestamps log datetime msec
! Call-home is enabled by Smart-Licensing.
service call-home
!
hostname C8Kv-1
!
interface Loopback0
ip address 192.168.10.1 255.255.255.0
!
interface GigabitEthernet1
ip address 203.25.163.25 255.255.255.252
negotiation auto
!
router bgp 100
bgp log-neighbor-changes
network 192.168.10.0
neighbor 203.25.163.26 remote-as 200
!
end
============= C8Kv-2 Configurations =============
Current configuration : 5938 bytes
!
! Last configuration change at 20:37:57 UTC Fri Jun 7 2024
!
version 17.5
service timestamps debug datetime msec
service timestamps log datetime msec
! Call-home is enabled by Smart-Licensing.
service call-home
!
hostname C8Kv-2
!
interface Loopback0
ip address 192.168.20.1 255.255.255.0
!
interface GigabitEthernet1
ip address 203.25.163.26 255.255.255.252
negotiation auto
!
router bgp 200
bgp log-neighbor-changes
network 192.168.20.0
neighbor 203.25.163.25 remote-as 100
!
end
:: Checks:
============= C8Kv-1 BGP Table =============
C8Kv-1#sh ip bgp
BGP table version is 3, local router ID is 192.168.10.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.10.0 0.0.0.0 0 32768 i
*> 192.168.20.0 203.25.163.26 0 0 200 i
============= C8Kv-2 BGP Table =============
C8Kv-2# sh ip bgp
BGP table version is 3, local router ID is 192.168.20.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.10.0 203.25.163.25 0 0 100 i
*> 192.168.20.0 0.0.0.0 0 32768 i
:: Turn it on
C8Kv-1(config-router)#do sh run | sec bgp
router bgp 100
bgp log-neighbor-changes
bgp safe-ebgp-policy >> added command
network 192.168.10.0
neighbor 203.25.163.26 remote-as 200
Immediately, an unreachable is sent for the advertised prefix 192.168.10.0/24, and a route refresh is pushed to C8Kv-2 to withdraw the prefix 192.168.10.0/24.
From C8Kv-1:
C8Kv-1(config-router)#
*Jun 16 09:35:21.951: BGP(0): (base) 203.25.163.26 send unreachable (format) 192.168.10.0/24
*Jun 16 09:35:41.266: BGP: nbr_topo global 203.25.163.26 IPv4 Unicast:base (0x7F943AB93C78:1) rcvd Refresh Start-of-RIB
*Jun 16 09:35:41.266: BGP: nbr_topo global 203.25.163.26 IPv4 Unicast:base (0x7F943AB93C78:1) refresh_epoch is 3
*Jun 16 09:35:41.266: BGP(0): 203.25.163.26 rcvd UPDATE w/ attr: nexthop 203.25.163.26, origin i, metric 0, merged path 200, AS_PATH
*Jun 16 09:35:41.266: BGP(0): 203.25.163.26 rcvd 192.168.20.0/24 -- DENIED due to: ebgp-safe-policy
*Jun 16 09:35:41.266: BGP: nbr_topo global 203.25.163.26 IPv4 Unicast:base (0x7F943AB93C78:1) rcvd Refresh End-of-RIB
From C8Kv-2:
*Jun 16 09:35:21.964: BGP: nbr_topo global 203.25.163.25 IPv4 Unicast:base (0x7FC913AAF450:1) rcvd Refresh Start-of-RIB
*Jun 16 09:35:21.964: BGP: nbr_topo global 203.25.163.25 IPv4 Unicast:base (0x7FC913AAF450:1) refresh_epoch is 4
*Jun 16 09:35:21.965: BGP(0): 203.25.163.25 rcv UPDATE about 192.168.10.0/24 -- withdrawn
*Jun 16 09:35:21.965: BGP(0): no valid path for 192.168.10.0/24
*Jun 16 09:35:21.965: BGP: nbr_topo global 203.25.163.25 IPv4 Unicast:base (0x7FC913AAF450:1) rcvd Refresh End-of-RIB
*Jun 16 09:35:21.965: BGP: topo global:IPv4 Unicast:base Remove_fwdroute for 192.168.10.0/24
*Jun 16 09:35:41.277: BGP(0): (base) 203.25.163.25 send UPDATE (format) 192.168.20.0/24, next 203.25.163.26, metric 0, path Local
Interestingly enough from the perspective of C8Kv-1, the prefix 192.168.20.0/24 is also not received. This implies both inbound and outbound are controlled by the ebgp-safe-policy feature as perfectly commercially advertised.
C8Kv-1#sh ip bgp
BGP table version is 4, local router ID is 192.168.10.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.10.0 0.0.0.0 0 32768 i
C8Kv-2#sh ip bgp
BGP table version is 6, local router ID is 192.168.20.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.20.0 0.0.0.0 0 32768 i
Implement Route-policy with ebgp-safe-policy for AS 100 on router C8Kv-1:
!
ip prefix-list advertised-routes seq 5 permit 192.168.10.0/24 le 28
ip prefix-list received-routes seq 5 permit 192.168.20.0/24 le 28
!
route-map bgp-inbound-accept permit 10
match ip address prefix-list received-routes
route-map bgp-outbound-accept permit 10
match ip address prefix-list advertised-routes
!
router bgp 100
neighbor 203.25.163.26 route-map bgp-inbound-accept in
neighbor 203.25.163.26 route-map bgp-outbound-accept out
!
Debug BGP neighbor on C8Kv-1:
*Jun 16 09:47:22.643: BGP(0): (base) 203.25.163.26 send UPDATE (format) 192.168.10.0/24, next 203.25.163.25, metric 0, path Local
*Jun 16 09:47:41.691: BGP: nbr_topo global 203.25.163.26 IPv4 Unicast:base (0x7F943AB93C78:1) rcvd Refresh Start-of-RIB
*Jun 16 09:47:41.691: BGP: nbr_topo global 203.25.163.26 IPv4 Unicast:base (0x7F943AB93C78:1) refresh_epoch is 4
*Jun 16 09:47:41.692: BGP(0): 203.25.163.26 rcvd UPDATE w/ attr: nexthop 203.25.163.26, origin i, metric 0, merged path 200, AS_PATH
*Jun 16 09:47:41.692: BGP(0): 203.25.163.26 rcvd 192.168.20.0/24
*Jun 16 09:47:41.692: BGP: nbr_topo global 203.25.163.26 IPv4 Unicast:base (0x7F943AB93C78:1) rcvd Refresh End-of-RIB
*Jun 16 09:47:41.692: BGP(0): Revise route installing 1 of 1 routes for 192.168.20.0/24 -> 203.25.163.26(global) to main IP table
Debug BGP neighbor on C8Kv-2:
*Jun 16 09:47:22.657: BGP(0): Revise route installing 1 of 1 routes for 192.168.10.0/24 -> 203.25.163.25(global) to main IP table
*Jun 16 09:47:41.704: BGP(0): (base) 203.25.163.25 send UPDATE (format) 192.168.20.0/24, next 203.25.163.26, metric 0, path Local
============= C8Kv-1 BGP Table =============
C8Kv-1#sh ip bgp
BGP table version is 5, local router ID is 192.168.10.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.10.0 0.0.0.0 0 32768 i
*> 192.168.20.0 203.25.163.26 0 0 200 i
============= C8Kv-2 BGP Table =============
C8Kv-2#sh ip bgp
BGP table version is 7, local router ID is 192.168.20.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
x best-external, a additional-path, c RIB-compressed,
t secondary path, L long-lived-stale,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
Network Next Hop Metric LocPrf Weight Path
*> 192.168.10.0 203.25.163.25 0 0 100 i
*> 192.168.20.0 0.0.0.0 0 32768 i
:: Conclusion
This feature introduces an additional security perimeter on advertised and received routes with BGP like IOS-XR has from the start.
Misconfigurations, especially made on the fly, could lead to receiving too many prefixes or advertising the wrong prefixes to your partner. In practice, it’s better to block all-in – and outbound prefixes until a proper policy is set.
Would it solve the misconfiguration failures? I don’t believe it will, but it will force the user to think about what they do and might prevent first step failures. If it fails the second step, I suggest to tighten your policies on change management and educate your personnel.