Prefix lists filter routes by address and mask length. But BGP policy often needs more — matching on AS-path patterns, community values, or MED, and then changing attributes to influence path selection. Route maps provide this full match-and-set capability, making them the primary tool for BGP traffic engineering on Cisco IOS XE.
Route Map Structure
A route map is an ordered list of clauses, each with a sequence number, a permit/deny action, match conditions, and set actions:
route-map NAME {permit|deny} SEQ
match CONDITION
set ACTION- Sequence numbers: Evaluated top-to-bottom. First matching clause wins.
- permit: If all match conditions are met, apply the set actions and accept the route.
- deny: If all match conditions are met, reject the route.
- Implicit deny: Routes not matching any clause are denied (just like ACLs).
- No match statement: A clause with no match condition matches everything.
Common Match Conditions
! Match by prefix list
match ip address prefix-list PL-NAME
! Match by AS-path (using a regex in an as-path access-list)
match as-path AS-PATH-ACL-NUMBER
! Match by community
match community COMMUNITY-LIST-NAME [exact-match]
! Match by MED
match metric 100
! Match by next-hop
match ip next-hop prefix-list NH-LIST
! Match by route source (advertising peer)
match ip route-source prefix-list PEER-LISTCommon Set Actions
! Set local preference (iBGP path selection)
set local-preference 150
! Set MED (influence neighbor's inbound path)
set metric 50
! Set weight (local to this router only)
set weight 200
! Set community
set community 65001:100 additive
! Prepend AS-path
set as-path prepend 65001 65001
! Set next-hop
set ip next-hop 10.1.1.1
! Set origin
set origin igpApplying Route Maps to BGP Neighbors
router bgp 65001
neighbor 172.16.0.2 route-map ISP-A-IN in
neighbor 172.16.0.2 route-map ISP-A-OUT outReal-World Policy Examples
Example 1: Prefer ISP-A for Specific Prefixes, ISP-B for Everything Else
ip prefix-list PARTNER-NETS seq 10 permit 100.64.0.0/18
ip prefix-list PARTNER-NETS seq 20 permit 100.64.64.0/18
!
route-map ISP-A-IN permit 10
match ip address prefix-list PARTNER-NETS
set local-preference 200
!
route-map ISP-A-IN permit 20
set local-preference 90
!
route-map ISP-B-IN permit 10
match ip address prefix-list PARTNER-NETS
set local-preference 90
!
route-map ISP-B-IN permit 20
set local-preference 200
!
router bgp 65001
neighbor 172.16.0.2 route-map ISP-A-IN in
neighbor 172.16.0.6 route-map ISP-B-IN inPartner networks (100.64.0.0/18, 100.64.64.0/18) get local-pref 200 via ISP-A and 90 via ISP-B — so they route through ISP-A. Everything else gets the inverse — local-pref 200 via ISP-B, 90 via ISP-A.
Example 2: Tag Routes with Communities on Inbound
ip as-path access-list 10 permit ^65010$
ip as-path access-list 20 permit ^65010_
!
route-map TAG-ISP-A permit 10
match as-path 10
set community 65001:100 additive
!
route-map TAG-ISP-A permit 20
match as-path 20
set community 65001:200 additive
!
route-map TAG-ISP-A permit 30Routes originated by ISP-A (AS-path is exactly "65010") get community 65001:100. Routes that ISP-A learned from others (AS-path starts with "65010 " followed by more) get 65001:200. Everything else passes through clause 30 unmodified. You can then use these communities for outbound filtering or further policy decisions.
Example 3: AS-Path Prepending on Outbound
route-map PREPEND-TO-ISP-B permit 10
set as-path prepend 65001 65001 65001
!
router bgp 65001
neighbor 172.16.0.6 route-map PREPEND-TO-ISP-B outThis makes routes advertised to ISP-B appear 3 hops longer, discouraging ISP-B's upstream from sending traffic through this path. See BGP AS-Path Prepending for when this works and when it doesn't.
AS-Path Access Lists
Route maps often match on AS-path patterns using regular expressions:
! Match routes originated by AS 65010
ip as-path access-list 10 permit ^65010$
! Match routes transiting AS 65010
ip as-path access-list 20 permit _65010_
! Match routes with AS-path length of exactly 1
ip as-path access-list 30 permit ^[0-9]+$
! Match any route (empty regex matches everything)
ip as-path access-list 99 permit .*Regex key characters: ^ = start, $ = end, _ = any delimiter (space, start, end), . = any character, * = zero or more of the preceding, + = one or more.
Continue Statement
Normally, once a route matches a clause, evaluation stops. The continue statement lets you chain clauses — useful for applying multiple set actions conditionally:
route-map COMPLEX-POLICY permit 10
match ip address prefix-list CRITICAL-NETS
set local-preference 200
continue 20
!
route-map COMPLEX-POLICY permit 20
match as-path 10
set community 65001:500 additive
!
route-map COMPLEX-POLICY permit 30A critical-net prefix originated by AS 65010 gets both local-pref 200 (from clause 10) AND community 65001:500 (from clause 20). Without continue, evaluation would stop at clause 10.
Verification
R1-HQ# show route-map ISP-A-IN
route-map ISP-A-IN, permit, sequence 10
Match clauses:
ip address prefix-lists: PARTNER-NETS
Set clauses:
local-preference 200
Policy routing matches: 0 packets, 0 bytes
route-map ISP-A-IN, permit, sequence 20
Match clauses:
Set clauses:
local-preference 90
Policy routing matches: 0 packets, 0 bytes
R1-HQ# show ip bgp neighbors 172.16.0.2 | include route-map
Route map for incoming advertisements is ISP-A-IN
Route map for outgoing advertisements is *not set*Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| All routes dropped after applying route-map | Missing a final permit clause — implicit deny blocks everything not explicitly matched | Add an empty permit clause at the end (e.g., route-map NAME permit 999) to pass unmatched routes through. |
| Set action not taking effect | Route matching a different clause than expected (earlier sequence number) | Check show route-map [name] and verify match conditions per clause. Move specific matches to lower sequence numbers. |
| Route-map applied but BGP table unchanged | Changes require a soft reset to take effect | Run clear ip bgp [peer] soft in (inbound) or clear ip bgp [peer] soft out (outbound). |
Key Takeaways
- Route maps provide full match-and-set policy for BGP — match on prefix, AS-path, community, MED, then set local-pref, weight, community, AS-path prepend, and more.
- Always include a final permit clause to avoid the implicit deny blocking unmatched routes.
- Use
continueto chain clauses when a route needs multiple conditional set actions. - AS-path access lists with regex patterns are powerful for matching routes by origin or transit AS.
- After applying or modifying a route-map, do a soft reset to trigger re-evaluation of existing routes.