Display the rejected BGP routes
Jernej sent me an interesting question: “does Cisco IOS have an equivalent to the Extremeware’s show bgp neighbor a.b.c.d rejected-routes command which displays all routes rejected by inbound filters?”
Short answer: it doesn’t.
Somewhat longer explanation
If you want to display routes rejected by an inbound BGP filter, you have to store every route you ever received from the BGP neighbor, increasing the memory consumption of your BGP process. You can do that in Cisco IOS if you configure neighbor a.b.c.d soft-reconfiguration in.
Configuring per-neighbor inbound soft reconfiguration significantly increases BGP memory consumption. On top of BGP routes inserted in the main BGP table, the BGP process has to store every route received from the BGP neighbor in a neighbor-specific table (two copies of the accepted routes are needed because an inbound route-map might have changed the route attributes).
Workaround
Use this procedure to find rejected routes:
- Within the BGP process configuration, enter neighbor a.b.c.d soft-reconfiguration in (this command might clear the BGP session).
- Populate the per-neighbor table with the clear ip bgp a.b.c.d soft in.
- Display the routes received from the neighbor with the show ip bgp neighbor a.b.c.d received-routes.
- Display the routes sent by the neighbor and accepted by the inbound BGP filters with the show ip bgp neighbor a.b.c.d routes.
- Do a diff of the two printouts (if you’ll write a short Tclsh script that does that, please feel free to send it to me or submit it in the comments).
show ip bgp neighbor a.b.c.d received-routes | redirect tftp://x.x.x.x/received.txt
show ip bgp neighbor a.b.c.d routes | redirect tftp://x.x.x.x/routes.txt
If you had enough flash you could actually do the diff on the router, but probably not many people are running enough flash for a whole BGP table:
show ip bgp neighbor a.b.c.d received-routes | redirect flash://x.x.x.x/received.txt
show ip bgp neighbor a.b.c.d routes | redirect flash://x.x.x.x/routes.txt
show archive config diff flash:received.txt flash:routes.txt
I haven't tried this with BGP but it works in a quick lab test with some IGPs.
puts -nonewline "\n\nBGP Neighbor IP? "
flush stdout
set neighbor [ gets stdin ]
set recv_routes [ split [ exec "show ip bgp neighbor $neighbor received-routes" ] "\n" ]
set routes [ split [ exec "show ip bgp neighbor $neighbor routes" ] "\n" ]
set matched 0
puts "\nThe following prefixes were received from neighbor $neighbor but not installed.\n"
foreach recvd $recv_routes {
set matched 0
foreach route $routes {
set test [ string compare $recvd $route ]
if { $test == 0 } { set matched 1 }
}
if { !$matched && [ regexp "(\[0-9]{1,3})\.(\[0-9]{1,3})\.(\[0-9]{1,3})\.(\[0-9]{1,3})" $recvd ] } {
puts $recvd
}
}
Beware line wrapping. Here's what the output looks like:
R3#tclsh disk0:bgpdenied.tcl
BGP Neighbor IP? 23.23.23.2
The following prefixes were received from neighbor 23.23.23.2 but not installed.
* i1.0.0.0 12.12.12.1 0 100 0 i
* i10.0.0.0 12.12.12.1 0 100 0 i
R3#
The following script can be pasted directly into tclsh from the CLI but you need to replace <neighborip> with the correct IP.
log_user 0
set neighbor <neighborip>
set recv_routes [ split [ exec "show ip bgp neighbor $neighbor received-routes" ] "\n" ]
set routes [ split [ exec "show ip bgp neighbor $neighbor routes" ] "\n" ]
set matched 0
foreach recvd $recv_routes {
set matched 0
foreach route $routes {
set test [ string compare $recvd $route ]
if { $test == 0 } { set matched 1 }
}
if { !$matched && [ regexp "(\[0-9]{1,3})\.(\[0-9]{1,3})\.(\[0-9]{1,3})\.(\[0-9]{1,3})" $recvd ] } {
puts $recvd
}
}
http://pastebin.com/f60cc87d1