Skip to content
Log in Sign up My account

1.2 Route Maps, Prefix Lists and Route Filtering

Blueprint 1.2: Troubleshoot route map for any routing protocol (attributes, tagging, filtering)

  • Route map structure: sequences, permit and deny, match and set, the implicit deny
  • Match tools: prefix lists (with ge and le), standard ACLs, tags, route types, interfaces
  • Setting attributes per protocol: metric, metric type, tag, BGP local preference, weight, AS path, community, MED
  • Where route maps attach: redistribution, distribute lists, BGP neighbors, PBR
  • Distribute lists for EIGRP, RIP, OSPF and BGP, and why OSPF behaves differently
  • Troubleshooting with show route-map, show ip prefix-list detail, show ip protocols and route tags in the RIB

Route map anatomy

A route map is an ordered list of sequences. Each sequence has an action (permit or deny), zero or more match lines and zero or more set lines.

route-map EIGRP-TO-OSPF deny 10
 match ip address prefix-list LAB-NETS
route-map EIGRP-TO-OSPF permit 20
 match tag 50 60
 set metric 40
 set metric-type type-1
 set tag 90
route-map EIGRP-TO-OSPF permit 30
 set tag 90

The processing rules are short, and nearly every route map fault breaks one of them:

Rule Detail
Top to bottom by sequence number First matching sequence decides. Later sequences are not checked.
Separate match lines Logical AND. All must be true.
Several values on one match line Logical OR. match tag 50 60 matches tag 50 or 60.
No match line Matches everything. Used as a final "permit the rest" sequence.
permit + match Route is accepted (redistributed, advertised, installed) and set lines apply
deny + match Route is rejected. set lines in a deny sequence do nothing.
No sequence matched Implicit deny at the end
ACL or prefix list inside a match denies the route The route does not match that sequence. It is not rejected yet; it falls to the next sequence.
Default sequence number 10 if you omit it. Typing route-map X permit twice edits sequence 10 both times.
graph TB
  R["Route"] --> S10{"Seq 10 deny: in LAB-NETS?"}
  S10 -->|"yes"| X["Rejected"]
  S10 -->|"no"| S20{"Seq 20 permit: tag 50 or 60?"}
  S20 -->|"yes"| P20["Accepted. Metric 40, E1, tag 90"]
  S20 -->|"no"| S30{"Seq 30 permit: no match lines"}
  S30 --> P30["Accepted. Tag 90"]

Exam trap

The most common route map fault on ENARSI is a route map that contains only deny sequences. The author meant "block these and allow the rest", but without a final permit sequence with no match lines, every route falls to the implicit deny. The symptom is that nothing is redistributed or advertised, not just the routes you meant to block.

Exam trap

A prefix list with deny entries inside a permit route map sequence is a double negative. A route denied by the prefix list does not match the sequence and moves on. If the next sequence is a catch-all permit, the route you thought you blocked is accepted. To block a route, match it with a prefix list permit entry inside a route map deny sequence.

Prefix lists

Prefix lists match both the network bits and the prefix length, which ACLs do poorly. They are the preferred matching tool for routes.

ip prefix-list NAME [seq n] {permit | deny} network/len [ge x] [le y]
Entry Matches
10.1.0.0/16 Exactly 10.1.0.0/16, nothing else
10.1.0.0/16 le 24 First 16 bits are 10.1, length 16 to 24
10.1.0.0/16 ge 24 First 16 bits are 10.1, length 24 to 32
10.1.0.0/16 ge 20 le 24 First 16 bits are 10.1, length 20 to 24
0.0.0.0/0 The default route only
0.0.0.0/0 le 32 Every IPv4 prefix
0.0.0.0/0 ge 32 Every host route

Rules: the length must satisfy len < ge <= le <= 32. A prefix list ends with an implicit deny. A route map that references a prefix list name that was never created, or was created with a typo, is a configuration fault in its own right: always confirm the name with show ip prefix-list.

R2# show ip prefix-list detail LAB-NETS
ip prefix-list LAB-NETS:
   count: 1, range entries: 1, sequences: 5 - 5, refcount: 2
   seq 5 permit 172.16.0.0/22 ge 24 le 24 (hit count: 8, refcount: 1)

The hit count increases when the entry matches a route, which is a fast way to see whether your prefix list is even being consulted.

ACLs in route maps

A standard ACL in match ip address <acl> checks only the network address of the route, not its mask. access-list 10 permit 10.1.0.0 0.0.255.255 matches 10.1.0.0/16, 10.1.1.0/24 and 10.1.1.128/25 alike. Extended ACLs have special meanings in route filtering that depend on context, so on the exam, and in production, prefer a prefix list whenever the mask matters.

Exam trap

match ip address 10.1.1.0/24 is not valid syntax. Route maps match a prefix list with match ip address prefix-list NAME and an ACL with match ip address <number or name>. If an exhibit shows match ip address LAB-NETS and LAB-NETS is a prefix list, not an ACL, the match is looking for an ACL that does not exist.

Setting attributes

What you can usefully set depends on where the route map is applied and which protocol receives the route.

Receiving protocol Useful set commands Effect
EIGRP set metric <bw> <delay> <rel> <load> <mtu>, set tag Seed metric for external routes, administrative tag
OSPF set metric <cost>, set metric-type type-1\|type-2, set tag Cost and type of the external LSA, tag in the Type 5 or Type 7 LSA
RIP set metric <hops>, set tag Hop count seed metric
BGP set local-preference, set weight, set as-path prepend, set metric (MED), set community, set origin, set ip next-hop Path selection attributes

A metric set in the route map overrides the metric keyword on the redistribute command, which in turn overrides default-metric.

Tags

A tag is a 32-bit number carried with external routes. It means nothing to the routing protocol itself; it is a label for policy. EIGRP carries it in external route data, OSPF in Type 5 and Type 7 LSAs, and RIPv2 in each route entry. You set it on the way in (usually at redistribution) and match it later.

R4# show ip route 172.16.1.0
Routing entry for 172.16.1.0/24
  Known via "ospf 1", distance 110, metric 20
  Tag 90, type extern 2, forward metric 2
  Last update from 10.3.4.1 on GigabitEthernet0/1, 00:03:52 ago
  Routing Descriptor Blocks:
  * 10.3.4.1, from 10.255.255.3, 00:03:52 ago, via GigabitEthernet0/1
      Route metric is 20, traffic share count is 1
      Route tag 90

In EIGRP the tag appears in the topology entry as Administrator tag is 90 (0x0000005A). In OSPF it appears as External Route Tag: 90 in show ip ospf database external.

Typical uses: marking the origin of a route so it is not redistributed back (see loop prevention and redistribution), and selecting groups of routes for filtering further away without maintaining long prefix lists.

Where route maps are applied

Attachment point Command What it controls
Redistribution redistribute ospf 1 route-map NAME Which routes enter the protocol and their attributes
EIGRP or OSPF inbound filter distribute-list route-map NAME in [interface] Which received routes are installed
BGP neighbor neighbor 10.1.1.1 route-map NAME in\|out Which paths are accepted or advertised, and their attributes
BGP network or aggregate network ... route-map, aggregate-address ... attribute-map Attributes of locally originated routes
Default origination default-information originate route-map NAME Conditional default route
PBR ip policy route-map NAME on an interface Forwarding of packets (covered in 1.6)

Exam trap

The counters in show route-map read Policy routing matches: 0 packets, 0 bytes. Those counters belong to policy-based routing. A route map used only for redistribution or filtering will show zero there even when it is working perfectly, so do not treat a zero as proof of a fault. Use the RIB, the topology table or show ip prefix-list detail hit counts instead.

Distribute lists

A distribute list filters routing updates using an ACL, a prefix list or a route map. Its behaviour depends on the protocol.

router eigrp 100
 distribute-list prefix BLOCK-GUEST out GigabitEthernet0/1
 distribute-list route-map TAG-FILTER in GigabitEthernet0/0

Distance vector protocols filter what is sent and received, so filtering on one router changes what every router downstream learns. out without an interface applies to all interfaces. out <protocol> filters routes redistributed from that protocol.

router ospf 1
 distribute-list prefix NO-LAB in            ! RIB only
 distribute-list prefix EXT-OUT out eigrp 100 ! ASBR, redistributed routes only
 area 1 filter-list prefix NO-LAB in          ! ABR, Type 3 LSAs into area 1

OSPF routers in an area must share an identical LSDB, so OSPF cannot filter LSAs between neighbors in the same area. distribute-list in stops a route being installed in the local RIB, but the LSA stays in the database and is still flooded. distribute-list out only works on an ASBR for routes being redistributed. Real filtering between areas happens on the ABR with area <id> filter-list prefix or area <id> range ... not-advertise.

router bgp 65001
 address-family ipv4 unicast
  neighbor 203.0.113.1 prefix-list FROM-ISP in
  neighbor 203.0.113.1 route-map TO-ISP out
  neighbor 203.0.113.1 filter-list 10 out      ! AS path access list

BGP filters per neighbor. After changing a policy, the change applies to new updates only, so run clear ip bgp 203.0.113.1 soft in (or out) to apply it to routes already exchanged.

Exam trap

An OSPF distribute-list in on one router does not stop downstream routers learning the route. If the ticket says "R5 and everything behind it must not reach 10.9.0.0/16", a distribute list on R5 only fixes R5. The traffic from routers further away still arrives at R5 and is dropped there, or worse, R5 becomes a black hole for a route others still use.

Troubleshooting method for route maps

  1. Find where it is applied. show running-config | include route-map NAME lists every reference. show ip protocols shows redistribution and distribute lists in force.
  2. Read the sequences in order. show route-map NAME. Check for a missing final permit, sequences in the wrong order, and AND versus OR logic.
  3. Check every referenced list exists and matches. show ip prefix-list detail NAME, show access-lists NAME. Watch for a name typo between the route map and the list.
  4. Check the result, not the config. show ip route <prefix> for tag and type, show ip eigrp topology <prefix> for EIGRP external data, show ip ospf database external <prefix> for OSPF metric type and tag, show ip bgp <prefix> for BGP attributes.
  5. Apply the change. IGPs reprocess redistribution and distribute lists automatically. BGP needs a soft clear.
R3# show route-map BLOCK-GUEST
route-map BLOCK-GUEST, deny, sequence 10
  Match clauses:
    tag 200
  Set clauses:
  Policy routing matches: 0 packets, 0 bytes

That output has one sequence, a deny. Every route is dropped.

Lab: break and fix route maps and distribute lists

Topology: three IOSv routers running classic EIGRP AS 100. R1 has lab networks and a guest network on loopbacks and redistributes them as connected routes.

graph LR
  R1["R1<br/>Lo1-Lo4 172.16.0-3.0/24<br/>Lo20 192.168.20.0/24<br/>Lo99 192.168.99.0/24"] -- "Gi0/0 10.1.2.0/30" --- R2["R2"]
  R2 -- "Gi0/1 10.2.3.0/30" --- R3["R3<br/>Lo30 10.3.30.0/24"]

Requirements.

  1. R1 redistributes the four lab networks with tag 100 and the guest network 192.168.20.0/24 with tag 200. Lo99 (management) is never redistributed.
  2. R3 must not install any route tagged 200. It must keep every other route.

Step 1. Baseline.

! R1
interface Loopback1
 ip address 172.16.0.1 255.255.255.0
interface Loopback2
 ip address 172.16.1.1 255.255.255.0
interface Loopback3
 ip address 172.16.2.1 255.255.255.0
interface Loopback4
 ip address 172.16.3.1 255.255.255.0
interface Loopback20
 ip address 192.168.20.1 255.255.255.0
interface Loopback99
 ip address 192.168.99.1 255.255.255.0
interface GigabitEthernet0/0
 ip address 10.1.2.1 255.255.255.252
!
ip prefix-list LAB seq 5 permit 172.16.0.0/22 ge 24 le 24
ip prefix-list GUEST seq 5 permit 192.168.20.0/24
!
route-map CONN-TO-EIGRP permit 10
 match ip address prefix-list LAB
 set tag 100
route-map CONN-TO-EIGRP permit 20
 match ip address prefix-list GUEST
 set tag 200
!
router eigrp 100
 eigrp router-id 10.255.255.1
 network 10.1.2.0 0.0.0.3
 redistribute connected route-map CONN-TO-EIGRP
!
! R2
interface GigabitEthernet0/0
 ip address 10.1.2.2 255.255.255.252
interface GigabitEthernet0/1
 ip address 10.2.3.1 255.255.255.252
router eigrp 100
 eigrp router-id 10.255.255.2
 network 10.1.2.0 0.0.0.3
 network 10.2.3.0 0.0.0.3
!
! R3
interface Loopback30
 ip address 10.3.30.1 255.255.255.0
interface GigabitEthernet0/0
 ip address 10.2.3.2 255.255.255.252
route-map BLOCK-GUEST deny 10
 match tag 200
route-map BLOCK-GUEST permit 20
!
router eigrp 100
 eigrp router-id 10.255.255.3
 network 10.2.3.0 0.0.0.3
 network 10.3.30.0 0.0.0.255
 distribute-list route-map BLOCK-GUEST in GigabitEthernet0/0

Connected routes redistributed into EIGRP take their metric from the interface, so no seed metric is needed here.

Step 2. Verify the baseline. R2 shows four D EX 172.16.x.0/24 routes and D EX 192.168.20.0/24, and no 192.168.99.0/24. R3 shows the four lab routes and not the guest route. Check a tag:

R2# show ip eigrp topology 172.16.1.0/24
EIGRP-IPv4 Topology Entry for AS(100)/ID(10.255.255.2) for 172.16.1.0/24
  State is Passive, Query origin flag is 1, 1 Successor(s), FD is 130816
  Descriptor Blocks:
  10.1.2.1 (GigabitEthernet0/0), from 10.1.2.1, Send flag is 0x0
      Composite metric is (130816/128256), route is External
      Vector metric:
        Minimum bandwidth is 1000000 Kbit
        Total delay is 5010 microseconds
        Reliability is 255/255
        Load is 1/255
        Minimum MTU is 1500
        Hop count is 1
        Originating router is 10.255.255.1
      External data:
        AS number of route is 0
        External protocol is Connected, external metric is 0
        Administrator tag is 100 (0x00000064)

Save the baseline on all three routers.

Step 3. Inject the faults.

! R1
no ip prefix-list LAB
ip prefix-list LAB seq 5 permit 172.16.0.0/22
!
! R3
no route-map BLOCK-GUEST permit 20
router eigrp 100
 no distribute-list route-map BLOCK-GUEST in GigabitEthernet0/0
 distribute-list route-map BLOCK-GUEST in Loopback30

Step 4. Ticket. "Lab users behind R1 are unreachable from everywhere. Also, R3 can now reach the guest network, which security says it must not."

Step 5. Diagnose and fix, one fault at a time.

Fault 1, R1. R2 has no 172.16 routes at all. On R1:

R1# show ip prefix-list detail LAB
ip prefix-list LAB:
   count: 1, range entries: 0, sequences: 5 - 5, refcount: 2
   seq 5 permit 172.16.0.0/22 (hit count: 0, refcount: 1)

range entries: 0 and the missing ge/le mean the entry matches only an exact /22, which does not exist. The /24 loopbacks fail sequence 10, fail sequence 20, and hit the implicit deny. Fix:

R1(config)# no ip prefix-list LAB
R1(config)# ip prefix-list LAB seq 5 permit 172.16.0.0/22 ge 24 le 24

Fault 2, R3. R3 shows the guest route, so the filter is not doing its job. Check where it is applied:

R3# show running-config | section router eigrp
router eigrp 100
 eigrp router-id 10.255.255.3
 network 10.2.3.0 0.0.0.3
 network 10.3.30.0 0.0.0.255
 distribute-list route-map BLOCK-GUEST in Loopback30

A filter on Loopback30 never sees an update, because no neighbor sends updates on a loopback. Move it to the interface facing R2:

R3(config)# router eigrp 100
R3(config-router)# no distribute-list route-map BLOCK-GUEST in Loopback30
R3(config-router)# distribute-list route-map BLOCK-GUEST in GigabitEthernet0/0

Fault 3, R3. After moving the filter, R3 loses every EIGRP route, which is the classic signature of a missing permit sequence:

R3# show ip route eigrp
R3#

show route-map BLOCK-GUEST shows a single deny sequence. Restore the catch-all permit:

R3(config)# route-map BLOCK-GUEST permit 20

Step 6. Verify.

R3# show ip route eigrp | begin Gateway
Gateway of last resort is not set

      10.0.0.0/8 is variably subnetted, 5 subnets, 3 masks
D        10.1.2.0/30 [90/3072] via 10.2.3.1, 00:00:41, GigabitEthernet0/0
      172.16.0.0/24 is subnetted, 4 subnets
D EX     172.16.0.0 [170/131072] via 10.2.3.1, 00:00:41, GigabitEthernet0/0
D EX     172.16.1.0 [170/131072] via 10.2.3.1, 00:00:41, GigabitEthernet0/0
D EX     172.16.2.0 [170/131072] via 10.2.3.1, 00:00:41, GigabitEthernet0/0
D EX     172.16.3.0 [170/131072] via 10.2.3.1, 00:00:41, GigabitEthernet0/0

No 192.168.20.0/24 and no 192.168.99.0/24. On R2 the guest route is still present, which is correct: the requirement was only for R3.

Stretch. Replace R3's inbound filter with an outbound filter on R2 toward R3 using a prefix list (distribute-list prefix NO-GUEST out GigabitEthernet0/1). Compare: which approach still works if R1 later adds a second guest subnet with tag 200?

Quick check

A route map has match tag 10 and match ip address prefix-list P in sequence 10, and match tag 20 in sequence 20. A route has tag 10 and is not in prefix list P. Which sequence does it match?

Neither. Sequence 10 needs both conditions (AND), and the route fails the prefix list. Sequence 20 needs tag 20. The route hits the implicit deny unless a later catch-all sequence exists.

Which prefixes does ip prefix-list X permit 10.0.0.0/8 ge 30 match?

Any prefix whose first 8 bits are 10 with a length of 30, 31 or 32. For example 10.1.2.0/30 and 10.255.255.1/32, but not 10.1.2.0/24.

An OSPF router has distribute-list prefix DENY-10 in. Does its OSPF neighbor still learn the denied prefix?

Yes. The distribute list only stops the local router installing the route in its RIB. The LSA remains in the LSDB and is flooded normally, so neighbors are unaffected.

References

  • IP Routing: Protocol-Independent Configuration Guide, Cisco IOS XE 17, sections on route maps, prefix lists and filtering routing information (search on cisco.com)
  • IP Routing: EIGRP Configuration Guide, "EIGRP Route Tag Enhancements" (search on cisco.com)
  • IP Routing: OSPF Configuration Guide, "OSPF ABR Type 3 LSA Filtering" (search on cisco.com)
  • Cisco Live On-Demand Library: search "route maps" and "BGP policy"
  • Related: Diagram N04, route-map processing, Sim 05, Sim 07