Route maps are one of those Cisco IOS features that quietly show up everywhere once you start looking — redistribution, policy-based routing, BGP attribute manipulation, NAT, VPN traffic selection. If you’ve configured any of these, you’ve used a route map, whether or not you fully understood what was happening under the hood. I want to break down exactly how route maps work, the logic behind sequence numbers and match/set clauses, and walk through practical, real configurations across the three areas where you’ll use them most: filtering, redistribution, and PBR.
What Is a Route Map?
A route map is a conditional, ordered set of rules that says: “if a route or packet matches these conditions, then do these actions.” It’s essentially an if-then-else construct built into IOS configuration syntax. Route maps are more flexible than a plain ACL or prefix-list because they let you combine multiple matching criteria and apply specific actions — not just permit or deny.
I like to describe a route map as a series of checkpoints on an assembly line. Each item (a route, or a packet, depending on context) moves down the line, checkpoint by checkpoint (sequence number by sequence number). At each checkpoint, if the item matches the criteria, it either gets stamped with an action and pulled off the line, or it’s explicitly rejected. If it doesn’t match at a checkpoint, it moves to the next one. If it reaches the end without matching anything, it’s dropped by default (this “implicit deny at the end” is a critical detail people often forget).
Anatomy of a Route Map
route-map NAME {permit | deny} SEQUENCE-NUMBER
match <condition>
set <action>
- NAME: an arbitrary name you choose, referenced elsewhere in the configuration.
- permit/deny: whether matching entries are accepted (and have
setactions applied) or rejected outright. - SEQUENCE-NUMBER: determines evaluation order, lowest first. Leaving gaps (10, 20, 30 instead of 1, 2, 3) is a best practice — it gives you room to insert new logic later without renumbering everything.
- match: the condition(s) — can match on prefix lists, ACLs, route tags, metrics, interfaces, AS-path, community, and more depending on context.
- set: the action(s) applied when a match occurs — set metric, set next-hop, set community, set local-preference, and so on.
A route map with no match statement in a permit clause matches everything. A route map with no match statement in a deny clause denies everything remaining — commonly used as a final “catch-all deny” or, conversely, a route map that ends with an empty permit sequence acts as a catch-all “let everything else through unchanged.”
Use Case 1: Filtering Routes
Let’s say you’re redistributing OSPF into EIGRP, but you only want to allow certain subnets through — say, only routes matching 10.10.0.0/16 and more specific.
Step 1: Build a Prefix List (Cleaner Than an ACL for Route Filtering)
Router(config)# ip prefix-list ALLOWED-ROUTES seq 10 permit 10.10.0.0/16 le 32
Step 2: Reference It in a Route Map
Router(config)# route-map FILTER-ROUTES permit 10
Router(config-route-map)# match ip address prefix-list ALLOWED-ROUTES
Router(config-route-map)# exit
Because there’s no explicit permit 20 catch-all, anything not matching sequence 10 hits the implicit deny at the end and is filtered out.
Step 3: Apply During Redistribution
Router(config)# router eigrp 100
Router(config-router)# redistribute ospf 1 route-map FILTER-ROUTES metric 10000 100 255 1 1500
Now only the allowed subnets make it from OSPF into EIGRP.
Use Case 2: Redistribution with Metric and Tag Manipulation
Redistribution between routing protocols is probably the single most common place route maps get used in enterprise networks — mainly because different protocols understand metrics completely differently (OSPF cost vs. EIGRP composite metric vs. BGP MED), and you almost always need to control what gets redistributed to avoid routing loops.
Here’s a more advanced example: redistributing EIGRP into OSPF, but tagging the routes so they can be identified and filtered later (a very important loop-prevention technique in mutual redistribution scenarios).
Router(config)# route-map EIGRP-TO-OSPF permit 10
Router(config-route-map)# match tag 0
Router(config-route-map)# set tag 100
Router(config-route-map)# set metric-type type-1
Router(config-route-map)# exit
Router(config)# router ospf 1
Router(config-router)# redistribute eigrp 100 route-map EIGRP-TO-OSPF subnets
And on the router doing the reverse redistribution (OSPF into EIGRP), you’d deny anything already tagged 100 to prevent it from looping back:
Router(config)# route-map OSPF-TO-EIGRP deny 10
Router(config-route-map)# match tag 100
Router(config-route-map)# exit
Router(config)# route-map OSPF-TO-EIGRP permit 20
Router(config-route-map)# exit
Router(config)# router eigrp 100
Router(config-router)# redistribute ospf 1 route-map OSPF-TO-EIGRP metric 10000 100 255 1 1500
This tag-based loop prevention pattern is a best practice you’ll see in almost every real mutual redistribution deployment.
Use Case 3: Policy-Based Routing
I cover PBR in depth in a separate guide, but the route map piece specifically looks like this:
Router(config)# route-map PBR-POLICY permit 10
Router(config-route-map)# match ip address ACL-NAME
Router(config-route-map)# set ip next-hop 192.168.100.1
Router(config-route-map)# exit
Router(config)# interface GigabitEthernet0/0
Router(config-if)# ip policy route-map PBR-POLICY
The key structural difference here versus the redistribution examples: PBR route maps act on live packets flowing through an interface, while redistribution route maps act on routes being exchanged between routing protocol processes. Same syntax, fundamentally different context — which is exactly why understanding the underlying logic matters more than memorizing specific command strings.
Use Case 4: BGP Route Maps
Route maps are absolutely essential in BGP for manipulating path attributes — setting local preference, prepending AS paths, filtering based on community strings, and more.
Router(config)# route-map SET-LOCAL-PREF permit 10
Router(config-route-map)# match ip address prefix-list CUSTOMER-ROUTES
Router(config-route-map)# set local-preference 200
Router(config-route-map)# exit
Router(config)# router bgp 65000
Router(config-router)# neighbor 203.0.113.1 route-map SET-LOCAL-PREF in
Verifying Route Maps
Router# show route-map
route-map FILTER-ROUTES, permit, sequence 10
Match clauses:
ip address prefix-lists: ALLOWED-ROUTES
Set clauses:
Policy routing matches: 0 packets, 0 bytes
For redistribution, check the resulting routing table to confirm expected routes appear (or don’t):
Router# show ip route eigrp
Router# show ip route ospf
For BGP, check attributes directly:
Router# show ip bgp neighbors 203.0.113.1 received-routes
Router# show ip bgp 10.10.10.0
Multiple Match Conditions: AND vs. OR Logic
This is a subtlety that catches people out. Within a single route-map sequence, multiple match statements of different types are ANDed together — all must be true. Multiple match statements of the same type within one sequence are ORed together.
route-map EXAMPLE permit 10
match ip address prefix-list LIST-A
match tag 100
This requires BOTH the prefix-list match AND the tag match to be true.
route-map EXAMPLE permit 10
match ip address prefix-list LIST-A LIST-B
This matches if the route/prefix matches LIST-A OR LIST-B.
Different route-map sequences (10, 20, 30…) are always evaluated independently in order, and the first matching sequence wins — later sequences aren’t evaluated once a match is found.
Real-World Enterprise Scenario
A very common enterprise pattern: a network running EIGRP internally and connecting to an MPLS provider via BGP. Route maps here do triple duty — filtering which internal routes get advertised to the provider (avoiding leaking internal-only subnets like management VLANs), setting local preference on inbound provider routes to prefer one circuit over another, and redistributing a default route from BGP into EIGRP for internal routing, tagged so it never gets accidentally redistributed back into BGP and creating a routing loop.
Common Configuration Mistakes
- Forgetting the implicit deny at the end of every route map — routes/packets that don’t match any sequence are dropped by default, not passed through.
- Confusing AND/OR logic for match statements of the same vs. different type.
- Not using tags for loop prevention during mutual redistribution — this is one of the most common causes of redistribution routing loops in real networks.
- Reusing the same route-map name for unrelated purposes across different parts of the configuration, causing confusing, hard-to-audit behavior.
- Numbering sequences too tightly (1, 2, 3) leaving no room to insert new logic later without a full renumber.
Troubleshooting Checklist
show route-map <name>— check match/set clauses and hit counters (very useful for confirming a sequence is actually being triggered).- Confirm referenced ACLs or prefix-lists actually match what you expect with
show ip prefix-listorshow access-list. - For redistribution issues, check
show ip route <protocol>on the receiving side to confirm expected routes appear. - For BGP, use
show ip bgp neighbors <ip> received-routesandshow ip bgp neighbors <ip> advertised-routesto see the effect of inbound/outbound route maps. - Watch for the implicit deny — if routes are disappearing unexpectedly, check whether they’re falling through to the end of the route map without matching any permit clause.
Performance Tuning Tips
- Prefer prefix-lists over ACLs for route filtering in route maps — they’re purpose-built for prefix matching and are generally more efficient and readable for that use case.
- Keep route maps well-documented with clear naming conventions (e.g.,
RM-EIGRP-TO-OSPF-REDISTrather thanRM1) since these configurations tend to get complex over time in larger networks. - Regularly audit hit counters (
show route-map) to identify stale or unused sequences that can be cleaned up.
FAQs
What happens if I don’t include any match statement in a permit sequence? It matches everything — commonly used as a final catch-all to allow all remaining routes/traffic through unmodified.
Can a route map deny specific routes while permitting everything else? Yes — use a deny sequence for the routes you want to exclude, followed by a permit sequence with no match statement to allow everything else through.
Is a route map the same as an ACL? No. An ACL is a single matching mechanism (permit/deny based on address/protocol criteria). A route map is a broader conditional construct that can reference ACLs, prefix-lists, tags, and other criteria, and can apply actions (set commands), not just permit/deny.
Why do my redistributed routes disappear even though I configured redistribution correctly? Almost always the implicit deny at the end of the referenced route map — if you added match criteria but no catch-all permit, everything not matching that specific criteria gets silently dropped.
Summary
Route maps are the Swiss Army knife of Cisco IOS routing configuration — the same syntax structure powers everything from simple route filtering to complex BGP policy and PBR. The essentials: sequences are evaluated in order with first-match-wins logic, there’s always an implicit deny at the end, match statements of the same type are ORed while different types are ANDed, and tagging routes during redistribution is the standard way to prevent routing loops. Once the match/set/sequence logic clicks, you’ll recognize route maps everywhere in Cisco configurations — and you’ll be able to build exactly the conditional logic your network needs.
References
- Cisco: Route-Map Command Reference
- Cisco: IP Routing Protocol-Independent Configuration Guide (Redistribution)
- Cisco: BGP Configuration Guide
