BGP Prefix-List and AS-Path Filtering on Cisco
BGP has no default policy. Once a session is Established, a router accepts every route its neighbor sends, apart from paths that already contain its own AS number, and advertises its best path for every prefix to every eBGP neighbor except the one it learned that path from. That includes routes learned from another provider, so an enterprise with two upstreams becomes a transit path between them unless something stops it. Cisco IOS has two purpose-built filters for this: the prefix-list, which matches a route by prefix and length, and the AS-path access-list, which matches the autonomous systems in its path. Both are applied below, inbound and outbound, on a four-router topology and then combined in a route-map; every block of output is what IOS XE printed. If your sessions are not up yet, start with configuring eBGP peering.
Part of the BGP learning hub. Practice on hands-on CCNP labs.
How BGP filters attach: per neighbor, per direction
Every BGP filter is bound to one neighbor and one direction. An inbound (in) filter decides which of that neighbor's routes enter your BGP table. An outbound (out) filter decides which of your best paths are sent to that neighbor. A session takes one of each command below per direction, and a route has to be permitted by every filter applied in that direction:
neighbor ADDRESS prefix-list NAME in|outmatches on prefix and length.neighbor ADDRESS filter-list NUMBER in|outmatches on the AS path, using anip as-path access-list.neighbor ADDRESS route-map NAME in|outmatches on either one (or on other attributes) and can also change attributes.
The example topology
R1 (10.255.0.1) and R2 (10.255.0.2) form AS 65001. They run iBGP between their loopbacks with OSPF underneath; iBGP update-source and next-hop-self covers that half. R1 peers with R3 (AS 65002) at 10.0.13.2, R2 peers with R4 (AS 65003) at 10.0.24.2, and R3 and R4 also peer with each other. AS 65001 originates 172.16.1.0/24 and 172.16.2.0/24, R3 originates 198.51.100.0/24, and R4 originates 203.0.113.0/24 and 192.0.2.0/24.
With no policy, R1 sends R3 four prefixes: its own two, plus the two R4 originates, which R1 learned from R2. It holds back only 198.51.100.0/24, the route R3 itself sent. AS 65001 is offering to carry traffic between its two providers.
R1# show ip bgp neighbors 10.0.13.2 advertised-routes
BGP table version is 8, local router ID is 10.255.0.1
...
Network Next Hop Metric LocPrf Weight Path
*> 172.16.1.0/24 0.0.0.0 0 32768 i
*>i 172.16.2.0/24 10.255.0.2 0 100 0 i
*>i 192.0.2.0 10.255.0.2 0 100 0 65003 i
*>i 203.0.113.0 10.255.0.2 0 100 0 65003 i
Total number of prefixes 4 R1 advertises AS 65003's prefixes to R3. The first filter removes them. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Prefix-lists: how a line matches
A prefix-list entry is ip prefix-list NAME [seq N] permit|deny PREFIX/LENGTH [ge MIN] [le MAX]. A route matches when two things are true: its first LENGTH bits equal those of PREFIX, and its own prefix length falls in the allowed range. With neither ge nor le, the range is LENGTH alone, so the entry matches one exact prefix. le MAX allows LENGTH through MAX, ge MIN allows MIN through 32, and both together allow MIN through MAX.
Entries are checked in sequence order and the first match decides. If you leave out seq, IOS numbers entries in steps of 5, which leaves room to insert a line later. A route that matches no entry is denied, so a list made only of deny lines blocks everything.
| Entry | Matches | Does not match |
|---|---|---|
| 172.16.0.0/16 | 172.16.0.0/16 only | 172.16.1.0/24, 172.16.0.0/15 |
| 172.16.0.0/16 le 24 | 172.16.0.0/16, 172.16.4.0/22, 172.16.1.0/24 | 172.16.1.128/25, 172.17.0.0/16 |
| 172.16.0.0/16 ge 24 | 172.16.1.0/24, 172.16.1.1/32 | 172.16.0.0/16, 172.16.4.0/22 |
| 172.16.0.0/16 ge 24 le 24 | Any /24 inside 172.16.0.0/16 | 172.16.0.0/16, 172.16.1.128/25 |
| 0.0.0.0/0 | The default route only | Every other route |
| 0.0.0.0/0 le 24 | Any route from /0 to /24, default included | Anything from /25 to /32 |
| 0.0.0.0/0 le 32 | Every IPv4 route | Nothing |
Step 1 — Advertise only your own prefixes with an outbound prefix-list
AS 65001 owns 172.16.0.0/16 and advertises /24s from it, so one entry describes everything R1 should send: 172.16.0.0/16 le 24. Without le 24, the entry would match only a 172.16.0.0/16 route, which R1 does not have, and R1 would send R3 nothing at all.
Build the list and test it before you bind it to a neighbor. show ip bgp prefix-list NAME lists the routes in your BGP table that conform to the list, and show ip prefix-list NAME PREFIX first-match names the entry a given prefix hits — entry 5 below, still on a hit count of 0 because the list is not attached to anything yet. Neither command changes anything, so a typo shows up here instead of on the session.
R1(config)# ip prefix-list AS65001-OUT permit 172.16.0.0/16 le 24
R1(config)# end
R1# show ip prefix-list AS65001-OUT
ip prefix-list AS65001-OUT: 1 entries
seq 5 permit 172.16.0.0/16 le 24
R1# show ip prefix-list AS65001-OUT 172.16.2.0/24 first-match
seq 5 permit 172.16.0.0/16 le 24 (hit count: 0, refcount: 1)
R1# show ip bgp prefix-list AS65001-OUT
BGP table version is 8, local router ID is 10.255.0.1
...
Network Next Hop Metric LocPrf Weight Path
*> 172.16.1.0/24 0.0.0.0 0 32768 i
*>i 172.16.2.0/24 10.255.0.2 0 100 0 iNo seq was typed; IOS numbered the entry 5. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Apply it and soft-reset the session
Bind the list with out, then run clear ip bgp 10.0.13.2 soft out. Adding the filter does not by itself re-evaluate the routes the two routers have already exchanged; the soft reset is what applies it. R1 runs its table through the new policy and sends R3 the resulting updates and withdrawals, without dropping the TCP session.
Read the result from R1's side. advertised-routes now lists only AS 65001's prefixes, show ip prefix-list detail shows two hits on entry 5 — one per permitted route — and show ip bgp neighbors names the list and its direction.
R1(config)# router bgp 65001
R1(config-router)# neighbor 10.0.13.2 prefix-list AS65001-OUT out
R1(config-router)# end
R1# clear ip bgp 10.0.13.2 soft out
R1# show ip bgp neighbors 10.0.13.2 advertised-routes
BGP table version is 8, local router ID is 10.255.0.1
...
Network Next Hop Metric LocPrf Weight Path
*> 172.16.1.0/24 0.0.0.0 0 32768 i
*>i 172.16.2.0/24 10.255.0.2 0 100 0 i
Total number of prefixes 2
R1# show ip prefix-list detail AS65001-OUT
ip prefix-list AS65001-OUT:
count: 1, range entries: 1, sequences: 5 - 5, refcount: 4
seq 5 permit 172.16.0.0/16 le 24 (hit count: 2, refcount: 1)
R1# show ip bgp neighbors 10.0.13.2 | include filter
Outgoing update prefix filter list is AS65001-OUTOnly AS 65001's prefixes remain, so R3 no longer learns AS 65003's routes through AS 65001. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
AS-path access-lists: matching on the path
An AS-path access-list, ip as-path access-list NUMBER permit|deny REGEX, matches a regular expression against the AS path written out as text, such as 65003 65002. The leftmost AS is the neighbor that sent the route and the rightmost AS originated it. As with a prefix-list, entries are read top-down and a path that matches nothing is denied.
An unanchored expression matches anywhere in that text. 65003 on its own also matches 165003 and 650031, both valid 4-byte AS numbers, so anchor every expression to the position you mean. The pieces you need:
^is the start of the path and$is the end._matches a delimiter: a space, a comma, a brace, or the start or end of the path..is any single character,*repeats the previous item zero or more times,+one or more times, and( )groups items.^$is an empty path: a route originated inside your own AS.^65003$is a route originated by AS 65003 and received directly from it.^65003_is any route received from AS 65003._65003$is any route originated by AS 65003, however far away._65003_is any route that passed through AS 65003.
Test the expression before you build the list
show ip bgp regexp runs an expression against your BGP table directly. On R2, ^65003$ matches the two routes R4 originated. That expression has a weakness: if R4 ever prepends its own AS, the path becomes 65003 65003 and no longer matches. ^65003(_65003)*$ accepts one or more copies of 65003 and nothing else. Here it matches the same two routes, because R4 does not prepend.
Once the expression is right, put it in a list. show ip as-path-access-list prints the list, and show ip bgp filter-list shows which routes in the table it permits.
R2# show ip bgp regexp ^65003$
BGP table version is 6, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
*> 203.0.113.0 10.0.24.2 0 0 65003 i
R2# show ip bgp regexp ^65003(_65003)*$
BGP table version is 6, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
*> 203.0.113.0 10.0.24.2 0 0 65003 i
R2(config)# ip as-path access-list 20 permit ^65003$
R2(config)# end
R2# show ip as-path-access-list 20
AS path access list 20
permit ^65003$
R2# show ip bgp filter-list 20
BGP table version is 6, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
*> 203.0.113.0 10.0.24.2 0 0 65003 iBoth expressions match the same two routes, the ones R4 originated. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Step 2 — Accept only a neighbor's own routes with a filter-list
R4 sends R2 its own two prefixes plus 198.51.100.0/24, which R4 learned from R3, so that route carries the path 65003 65002. If R2 should use R4 only for AS 65003's own networks, ^65003$ is the whole policy: it permits a path that is exactly R4's AS and nothing longer.
R2# show ip bgp neighbors 10.0.24.2 routes
BGP table version is 6, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
* 198.51.100.0 10.0.24.2 0 65003 65002 i
*> 203.0.113.0 10.0.24.2 0 0 65003 i
Total number of prefixes 3 Before the filter: R2 accepts R4's own routes and the route R4 carries for AS 65002. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Apply the filter-list inbound
Bind list 20 with filter-list 20 in and soft-reset inbound. clear ip bgp 10.0.24.2 soft in asks R4 to resend its routes through the route refresh capability, which IOS routers negotiate by default, so the session stays up.
R2 still reaches 198.51.100.0/24. The path left in its table is the internal one from R1 at 10.255.0.1, which is where AS 65002's routes should come from. The last line of the block is the neighbor's Local Policy Denied Prefixes counter for filter-lists, outbound first and inbound second: one route rejected on the way in.
R2(config)# router bgp 65001
R2(config-router)# neighbor 10.0.24.2 filter-list 20 in
R2(config-router)# end
R2# clear ip bgp 10.0.24.2 soft in
R2# show ip bgp neighbors 10.0.24.2 routes
BGP table version is 6, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
*> 203.0.113.0 10.0.24.2 0 0 65003 i
Total number of prefixes 2
R2# show ip bgp 198.51.100.0/24
BGP routing table entry for 198.51.100.0/24, version 5
Paths: (1 available, best #1, table default)
Advertised to update-groups:
1
Refresh Epoch 1
65002
10.255.0.1 (metric 11) from 10.255.0.1 (10.255.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
...
R2# show ip bgp neighbors 10.0.24.2 | include filter
Incoming update AS path filter list is 20
filter-list: 0 1198.51.100.0/24 is gone from R4's routes, and the denied counter reads one prefix inbound. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Step 3 — The AS-path way to stop transit
Step 1 stopped the leak by listing AS 65001's address space, which means editing the list every time the AS adds a prefix. The AS-path version describes the property you care about instead: only routes that originated inside AS 65001 may leave. In R1's table those routes have an empty path. That covers 172.16.1.0/24, which R1 originates, and 172.16.2.0/24, which R1 learned from R2, because iBGP does not add an AS number.
An outbound filter-list is checked against the path as it sits in the table, before R1 adds 65001 on the way out. ^$ is therefore the correct expression, and ^65001$ would match nothing R1 holds.
R1# show ip bgp regexp ^$
BGP table version is 8, local router ID is 10.255.0.1
...
Network Next Hop Metric LocPrf Weight Path
*> 172.16.1.0/24 0.0.0.0 0 32768 i
*>i 172.16.2.0/24 10.255.0.2 0 100 0 i
R1(config)# ip as-path access-list 10 permit ^$
R1(config)# router bgp 65001
R1(config-router)# neighbor 10.0.13.2 filter-list 10 out
R1(config-router)# end
R1# clear ip bgp 10.0.13.2 soft out
R1# show ip bgp neighbors 10.0.13.2 advertised-routes
BGP table version is 8, local router ID is 10.255.0.1
...
Network Next Hop Metric LocPrf Weight Path
*> 172.16.1.0/24 0.0.0.0 0 32768 i
*>i 172.16.2.0/24 10.255.0.2 0 100 0 i
Total number of prefixes 2
R1# show ip bgp neighbors 10.0.13.2 | include filter
Outgoing update AS path filter list is 10The Step 1 prefix-list is off here, so the filter-list is the only outbound policy: ^$ matches the two routes AS 65001 originated, and only those are sent. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
| Stopping transit | Outbound prefix-list | Outbound filter-list (^$) |
|---|---|---|
| What it describes | Your address space | Routes originated inside your AS |
| You add a new prefix | Not advertised unless the list already covers it | Advertised with no change |
| Someone originates a prefix by mistake | Blocked unless it falls inside the permitted range | Advertised |
| Routes learned from another AS | Blocked unless they fall inside the permitted range | Blocked |
Combine both in a route-map
Separate filters work when each one is a plain yes or no. When the policy is an ordered mix, such as "drop this prefix, then accept only that AS", or when some routes need an attribute changed, put the matches inside one route-map.
Two rules catch people out. First, permit in a prefix-list or AS-path list only means "this route matches"; the route-map clause's own permit or deny decides what happens to it. Second, a route-map ends with an implicit deny, so a route that matches no clause is dropped. In the map below, clause 10 drops 192.0.2.0/24, clause 20 accepts paths that are exactly 65003, and 198.51.100.0/24 falls through to the implicit deny.
Inside one clause, separate match commands must all be true. Several lists named on a single match command need only one of them to match. show route-map prints the clauses in order with the lists each one matches on; its Policy routing matches counter stays at zero because it counts policy-routed packets, not BGP routes. The same clause structure carries set local-preference or set weight when you want to prefer a path rather than drop it; BGP best path selection covers those.
R2(config)# ip as-path access-list 20 permit ^65003$
R2(config)# ip prefix-list R4-BLOCK permit 192.0.2.0/24
R2(config)# route-map R4-IN deny 10
R2(config-route-map)# match ip address prefix-list R4-BLOCK
R2(config-route-map)# exit
R2(config)# route-map R4-IN permit 20
R2(config-route-map)# match as-path 20
R2(config-route-map)# exit
R2(config)# router bgp 65001
R2(config-router)# neighbor 10.0.24.2 route-map R4-IN in
R2(config-router)# end
R2# clear ip bgp 10.0.24.2 soft in
R2# show ip bgp neighbors 10.0.24.2 routes
BGP table version is 8, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 203.0.113.0 10.0.24.2 0 0 65003 i
Total number of prefixes 1
R2# show route-map R4-IN
route-map R4-IN, deny, sequence 10
Match clauses:
ip address prefix-lists: R4-BLOCK
Set clauses:
Policy routing matches: 0 packets, 0 bytes
route-map R4-IN, permit, sequence 20
Match clauses:
as-path (as-path filter): 20
Set clauses:
Policy routing matches: 0 packets, 0 bytes
R2# show ip bgp neighbors 10.0.24.2 | include Route map
Route map for incoming advertisements is R4-INOnly 203.0.113.0/24 gets through: clause 10 drops 192.0.2.0/24 and 198.51.100.0/24 matches no clause. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Verify what a filter did
These commands answer most questions about a filter; the BGP commands cheat sheet lists the rest.
show ip bgp neighbors ADDRESS routeslists the routes accepted from the neighbor, after inbound policy.show ip bgp neighbors ADDRESS advertised-routeslists the routes sent to the neighbor, after outbound policy.show ip bgp neighbors ADDRESS received-routeslists everything the neighbor sent, before inbound policy. It needssoft-reconfiguration inboundon that neighbor, which keeps an unfiltered copy of every route in memory. Soft resets do not need it; turn it on for this comparison.show ip prefix-list detail NAMEshows a hit count for each entry.show ip bgp neighbors ADDRESSnames every filter bound to the session and its direction. Its Local Policy Denied Prefixes table counts the routes each kind of filter has rejected, outbound and inbound.
R2(config)# router bgp 65001
R2(config-router)# neighbor 10.0.24.2 soft-reconfiguration inbound
R2(config-router)# end
R2# clear ip bgp 10.0.24.2 soft in
R2# show ip bgp neighbors 10.0.24.2 received-routes
BGP table version is 11, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
* 198.51.100.0 10.0.24.2 0 65003 65002 i
*> 203.0.113.0 10.0.24.2 0 0 65003 i
Total number of prefixes 3
R2# show ip bgp neighbors 10.0.24.2 routes
BGP table version is 11, local router ID is 10.255.0.2
...
Network Next Hop Metric LocPrf Weight Path
*> 192.0.2.0 10.0.24.2 0 0 65003 i
*> 203.0.113.0 10.0.24.2 0 0 65003 i
Total number of prefixes 2 Captured with Step 2's filter-list applied: received-routes is what R4 sent, routes is what the filter let in. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Troubleshooting: a prefix-list that drops everything
A prefix-list written as a block list drops everything. Below, R1 was meant to refuse a single prefix from R3, but the list has no permit entry, so the implicit deny rejects every route R3 sends. The damage is easy to miss: 198.51.100.0/24 did not disappear. R1 now reaches R3's network the long way round, learning it from R2 on the path 65003 65002. The only clue in the summary is the 0 in the State/PfxRcd column for 10.0.13.2: a number there is a prefix count, so the session is Established and receiving nothing.
R1(config)# ip prefix-list R3-IN seq 5 deny 192.0.2.0/24
R1(config)# router bgp 65001
R1(config-router)# neighbor 10.0.13.2 prefix-list R3-IN in
R1(config-router)# end
R1# clear ip bgp 10.0.13.2 soft in
R1# show ip bgp 198.51.100.0/24
BGP routing table entry for 198.51.100.0/24, version 12
Paths: (1 available, best #1, table default)
Flag: 0x8100
Not advertised to any peer
Refresh Epoch 1
65003 65002
10.255.0.2 (metric 11) from 10.255.0.2 (10.255.0.2)
Origin IGP, metric 0, localpref 100, valid, internal, best
...
R1# show ip bgp summary
BGP router identifier 10.255.0.1, local AS number 65001
...
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
10.0.13.2 4 65002 31 41 11 0 0 00:17:16 0
10.255.0.2 4 65001 26 27 12 0 0 00:16:40 4An Established session that receives nothing, and the detour 198.51.100.0/24 took to arrive. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Fix: end the list with a permit
Add a last entry that permits what should pass. 0.0.0.0/0 le 32 permits every IPv4 route. On an Internet edge, 0.0.0.0/0 le 24 is a common alternative because it also refuses anything longer than /24; RFC 7454 collects that check with the other prefix filters an eBGP edge should run. After the soft reset, R3's routes return except the one the deny entry names, and the hit counts show which entry matched each route.
R1(config)# ip prefix-list R3-IN seq 10 permit 0.0.0.0/0 le 32
R1(config)# end
R1# clear ip bgp 10.0.13.2 soft in
R1# show ip bgp neighbors 10.0.13.2 routes
BGP table version is 13, local router ID is 10.255.0.1
...
Network Next Hop Metric LocPrf Weight Path
*> 198.51.100.0 10.0.13.2 0 0 65002 i
* 203.0.113.0 10.0.13.2 0 65002 65003 i
Total number of prefixes 2
R1# show ip prefix-list detail R3-IN
ip prefix-list R3-IN:
count: 2, range entries: 1, sequences: 5 - 10, refcount: 3
seq 5 deny 192.0.2.0/24 (hit count: 1, refcount: 1)
seq 10 permit 0.0.0.0/0 le 32 (hit count: 2, refcount: 1)Entry 5 matched 192.0.2.0/24 once; entry 10 let the other two routes through. Output captured on Cisco IOL (IOS XE 17.16) in Cisco Modeling Labs.
Other common problems (and the fix)
- The policy is in the config but nothing has changed yet. Run
clear ip bgp ADDRESS soft inorsoft outfor the direction you changed. An inbound reset waits on the neighbor to resend its routes, so allow a few seconds. Never runclear ip bgp *withoutsoft: it resets every session on the router. - The range misses the length.
172.16.0.0/16matches only the /16 itself. Addle 24, or whatever your longest advertised prefix is, to match the subnets. - Wrong direction or wrong neighbor. An
inlist on a session you meant to filteroutfilters the wrong routes.show ip bgp neighbors ADDRESS | include filternames each list and its direction. - An unanchored expression. Use
^,$and_so the expression means one AS in one position. - There was nothing to filter. If your own prefix never appears in
advertised-routes, even with no filter applied, the problem is origination, not policy. See why the network statement needs an exact match.
Frequently asked questions
What is the difference between a prefix-list and a distribute-list in BGP?
A distribute-list filters routes with a standard or extended access-list, which matches address bits but not prefix length, unless you use the extended ACL workaround of matching the mask in the destination fields. A prefix-list matches the prefix and its length directly, supports ge and le to cover a range of lengths, and can be edited one entry at a time by sequence number. That makes a prefix-list the clearer tool for BGP, and it is the one used throughout this guide.
Do I have to reset a BGP session after changing a filter?
Not a hard reset. Run clear ip bgp with the neighbor address and soft in or soft out, depending on the direction you changed. Until you do, the session keeps carrying what it carried before, because the new policy is only applied when a table is run through it again. A soft inbound reset uses the route refresh capability to ask the neighbor to resend its routes; a soft outbound reset runs your own table through the new policy. Either way the session stays up. A plain clear ip bgp without the soft keyword drops the session and withdraws its routes until it comes back.
What does the regular expression ^$ match in a BGP AS-path filter?
An empty AS path, which is how routes originated inside your own autonomous system appear in your BGP table, including routes learned from iBGP peers in the same AS. Applied outbound with a filter-list, it lets only your own routes out, because the check runs before your router adds its own AS number to the path. It is the standard way to stop an enterprise with two providers from acting as transit between them.
How do I permit all remaining routes at the end of a prefix-list?
End the list with a permit entry for 0.0.0.0/0 le 32, which matches every IPv4 prefix of any length. Without it, the implicit deny at the end of the list drops every route that no earlier entry permitted. Use le 24 instead of le 32 if you also want to refuse prefixes longer than /24 from the Internet.
Can a BGP neighbor have a prefix-list, a filter-list and a route-map at the same time?
Yes. Each neighbor accepts one of each per direction, and a route has to be permitted by every filter applied in that direction to be accepted or advertised. When the logic needs an ordered mix of permits and denies, or needs to change attributes such as local preference, a single route-map that matches on prefix-lists and AS-path lists is easier to read than three separate filters.
Practice BGP filtering
Write the filter yourself on real Cisco IOS in CML, then upload the config for a grade.
This is what grading your config looks like
A sample result — 4 of 5 requirements met. This is exactly what you see the moment you submit.
bgp-lab-export.yaml — read 3 device configs
- Passed: BGP process running as AS 65001 on R1
- Passed: eBGP neighbor 10.0.13.2 in AS 65002
- Passed: Session to 10.0.13.2 is Established
- Passed: 172.16.1.0/24 originated by an exact match
- Failed: next-hop-self toward the iBGP peer — missing on R2
Solution revealed
The full node-by-node answer key unlocks the moment you submit — so you see exactly what you missed.
Don't just read it — configure it
Reading is step one. Build BGP on real Cisco IOS and have your own config graded.