Cisco Prefix-List and Route-Map Filtering for BGP - 夜莺博客

Cisco Prefix-List and Route-Map Filtering for BGP

Route filtering is where BGP policy actually lives: deciding which prefixes enter your table from a customer, and which of your prefixes you advertise upstream. On Cisco IOS the clean split is prefix-lists match routes (what is allowed or targeted) while route-maps take action (permit, deny, or modify attributes like local-preference and communities). This guide shows the pattern with real configurations, including the ge/le prefix-length logic and the safe route-map ordering that prevents accidental full-table drops.

Prefix-List Basics

ip prefix-list CUSTOMER-PREFIXES seq 10 permit 203.0.113.0/24
ip prefix-list CUSTOMER-PREFIXES seq 20 permit 198.51.100.0/24

Each entry matches an exact prefix — 203.0.113.0/25 does not match 203.0.113.0/24 unless you say so. Every prefix-list ends with an implicit deny.

Matching Prefix Length Ranges: ge and le

  • le — less-or-equal: sets the maximum prefix length.
  • ge — greater-or-equal: sets the minimum prefix length.
! accept the /24 and anything more specific up to /28
ip prefix-list CUSTOMER-PREFIXES seq 10 permit 203.0.113.0/24 le 28
! only /25 through /28 of this block
ip prefix-list MORESPECIFICS seq 10 permit 203.0.113.0/24 ge 25 le 28
! only the default route
ip prefix-list DEFAULT seq 10 permit 0.0.0.0/0
! any IPv4 prefix at all
ip prefix-list ANY seq 10 permit 0.0.0.0/0 le 32

Route-Map Evaluation Logic

Route-maps run top-down by sequence number; the first match wins and nothing after it is evaluated. Sequence design therefore matters: put denies before broad permits.

route-map CUSTOMER-IN permit 10
 match ip address prefix-list CUSTOMER-PREFIXES
route-map CUSTOMER-IN deny 20
 match ip address prefix-list BLOCKED-PREFIXES
route-map CUSTOMER-IN permit 30

A route matching sequence 10 is permitted immediately — the deny at 20 never sees it. A broad permit early overrides later denies, which is why the safe pattern below puts the explicit blocklist first.

Recommended Safe Pattern

route-map CUSTOMER-IN deny 5
 match ip address prefix-list BLOCKED-PREFIXES

route-map CUSTOMER-IN permit 10
 match ip address prefix-list CUSTOMER-PREFIXES

route-map CUSTOMER-IN permit 100

Sequence 5 always blocks known-bad prefixes first; sequence 10 admits only approved routes; sequence 100 is the catch-all permit that stops an accidental full-table drop when new prefixes appear. For a strict allowlist-only policy, change the last clause to deny 100.

Applying the Route-Map to a Neighbor

router bgp 64500
 neighbor 192.0.2.2 remote-as 65001
 neighbor 192.0.2.2 description CUSTOMER-NAME
 neighbor 192.0.2.2 route-map CUSTOMER-IN in

Inbound route-maps filter what enters your BGP table; outbound route-maps filter what you advertise. The same match/set mechanics drive redistribution — redistribute ospf 1 route-map OSPF-TO-BGP — and route-map set clauses can prepend AS paths, tag communities or set local preference on matched prefixes.

Verification

show ip prefix-list
show ip bgp neighbor 192.0.2.2 received-routes
show route-map

Check what the neighbor actually sent versus what survived the filter. Route filtering is central to BGP operations — combine with BGP route dampening for flapping peers and review selection logic in our BGP best path explainer.

原文链接:https://blog.j2sw.com/inetarch/bgp-filtering-prefix-lists-route-maps/

Why Filter BGP at All

An unfiltered eBGP session is an open door. Whatever a neighbour sends you lands in your BGP table, then in your forwarding table, then in the DFZ if you are a transit provider — and the reverse is just as dangerous: leaking a full table upstream is how a small misconfiguration becomes a global outage that gets written up for the next decade. Filtering performs three separate jobs, and it is worth keeping them distinct in your configuration and in your head:

  • Protecting your own table. Reject bogons, RFC 1918 space, unallocated blocks and anything longer than the prefix length you agreed to accept.
  • Protecting the neighbour. Advertise only the address space you own or are authorised to route. Never let redistributed internal prefixes or a default route escape by accident.
  • Expressing policy. Tag what arrives with communities, set local preference by class of peer, and prepend on the backup link.

The first two are hygiene and belong in every template. The third is commercial and belongs in a documented policy that you can point a customer at when they ask why their prefix is not visible.

Prefix-List Mechanics in Detail

A prefix-list entry is a pair: a network and a length condition. The address portion is matched against the network address, and the length condition restricts the mask length separately. That separation is the whole point — it lets you say "the 203.0.113.0/24 block, and anything more specific inside it" in a single line.

ip prefix-list X seq 10 permit 203.0.113.0/24
ip prefix-list X seq 20 permit 203.0.113.0/24 ge 25 le 28
ip prefix-list X seq 30 permit 0.0.0.0/0 le 24
ip prefix-list X seq 40 deny 0.0.0.0/0 le 32

Read each line carefully, because the off-by-one cases are subtle:

  • No ge and no le means exact match only. 203.0.113.0/24 matches the /24 and nothing else — not the /25, not the /23.
  • le 28 without ge means "mask length between the stated length and 28 inclusive" → /24 through /28.
  • ge 25 le 28 means strictly between → /25 through /28, excluding the /24 itself. This is the line you want when a customer is allowed to aggregate but not to announce their own covering /24.
  • ge 25 without le means "25 or longer", up to /32.
  • The normalisation rule: if you write only le, the lower bound defaults to the stated length; if you write only ge, the upper bound defaults to /32 (IPv4).
  • 0.0.0.0/0 le 32 matches every IPv4 prefix — the standard "match anything" idiom.

One more rule that catches people doing prefix-list "arithmetic": the network address must be exactly on the stated boundary. 203.0.113.0/24 ge 25 is legal and matches subnets of that /24, but Cisco configuration parsing will reject a mask that does not align with the address you typed, so always write the block's true network address.

Route-Map Evaluation, Clause by Clause

A route-map is an ordered list of clauses, each with a sequence number, an action (permit or deny) and an optional set of match conditions. The rules that matter:

  • Clauses are evaluated in ascending sequence order, and the first clause whose match conditions are all true wins. Nothing after it is examined.
  • A clause with match statements is "true" only when every match statement is satisfied — match statements are ANDed within a clause. (The exception is match ip address, which ORs multiple prefix-lists or ACLs in the same statement.)
  • A clause with no match statement matches everything.
  • If no clause matches at all, the route-map result depends on context: for redistribution and for outbound/inbound neighbour policy, an unmatched route is denied.
  • deny in a route-map means "do not use this route" — it does not add a reject measure. There is no notion of an implicit deny in a route-map; the fall-through behaviour above is the only default.
route-map CUSTOMER-IN deny 5
 match ip address prefix-list BLOCKED-PREFIXES

route-map CUSTOMER-IN permit 10
 match ip address prefix-list CUSTOMER-PREFIXES
 set local-preference 200
 set community 64500:100

route-map CUSTOMER-IN permit 20
 match ip address prefix-list CUSTOMER-MORES

route-map CUSTOMER-IN permit 100

Sequence 100 exists for one reason: without a catch-all permit, any prefix the customer starts announcing that is not in your lists is silently dropped, which is exactly what you want for an allowlist — and exactly what you do not want for a template applied to forty peers where one missed entry blinds a customer. Decide deliberately which of the two you are building and document it.

Bogon and Hijack Filtering

Every eBGP template should begin with four prefix-lists. They are cheap, static and catch a surprising amount of real-world noise.

ip prefix-list BOGONS seq 10 permit 0.0.0.0/8 le 32
ip prefix-list BOGONS seq 20 permit 10.0.0.0/8 le 32
ip prefix-list BOGONS seq 30 permit 127.0.0.0/8 le 32
ip prefix-list BOGONS seq 40 permit 169.254.0.0/16 le 32
ip prefix-list BOGONS seq 50 permit 172.16.0.0/12 le 32
ip prefix-list BOGONS seq 60 permit 192.0.2.0/24 le 32
ip prefix-list BOGONS seq 70 permit 192.168.0.0/16 le 32
ip prefix-list BOGONS seq 80 permit 198.51.100.0/24 le 32
ip prefix-list BOGONS seq 90 permit 203.0.113.0/24 le 32
ip prefix-list BOGONS seq 100 permit 224.0.0.0/3 le 32
!
ip prefix-list MARTIANS deny 10.0.0.0/8 le 32
ip prefix-list MARTIANS deny 172.16.0.0/12 le 32
ip prefix-list MARTIANS deny 192.168.0.0/16 le 32
ip prefix-list MARTIANS permit 0.0.0.0/0 le 32
!
route-map PEER-IN deny 5
 match ip address prefix-list BOGONS

Note the inversion: the bogon list permits the bad ranges so that a following deny clause can act on them, while the Martian list denys them and permits the rest. Both idioms are common; pick one per template and be consistent, because mixing them across peers is how you end up permitting RFC 1918 by accident. For the newest versions of the global bogon list, subscribe to a public feed and regenerate the prefix-list from a script rather than editing it by hand.

Outbound Filtering — the Half Everyone Skips

Inbound filtering protects you; outbound filtering protects the internet. The safest outbound pattern is an explicit allowlist with a final deny.

ip prefix-list OUR-AGGREGATES seq 10 permit 198.51.100.0/22
ip prefix-list OUR-AGGREGATES seq 20 deny 0.0.0.0/0 le 32
!
router bgp 64500
 neighbor 192.0.2.2 route-map CUSTOMER-OUT out
!
route-map CUSTOMER-OUT permit 10
 match ip address prefix-list OUR-AGGREGATES

If you are a transit provider the list will instead be built from the customer's registered objects — an IRR-based filter generation, ideally automated so it stays in sync with what the customer is actually authorised to announce. Never rely on distribute-list out against the full BGP table; it is far too easy to omit a clause and leak.

Applying Policy at Scale: Peer Groups and Templates

Per-neighbour route-maps do not scale. Group the peers that share a policy, attach the route-map to the group, and override only where a peer genuinely differs.

router bgp 64500
 neighbor CUSTOMERS peer-group
 neighbor CUSTOMERS route-map CUSTOMER-IN in
 neighbor CUSTOMERS route-map CUSTOMER-OUT out
 neighbor CUSTOMERS maximum-prefix 500 90 restart 30
 neighbor 192.0.2.2 remote-as 65001
 neighbor 192.0.2.2 peer-group CUSTOMERS
 neighbor 192.0.2.3 remote-as 65002
 neighbor 192.0.2.3 peer-group CUSTOMERS

Pair the peer group with maximum-prefix as a backstop. Prefix-lists are static, so they cannot stop a peer that starts announcing two hundred thousand routes that are all individually legal under your filter; the prefix counter can, and the restart keyword makes the peer come back automatically once it settles down.

Verification Recipes

show ip prefix-list CUSTOMER-PREFIXES
show ip prefix-list CUSTOMER-PREFIXES 203.0.113.0/24
show route-map CUSTOMER-IN
show ip bgp neighbors 192.0.2.2 policy
show ip bgp neighbors 192.0.2.2 received-routes
show ip bgp neighbors 192.0.2.2 routes
show ip bgp neighbors 192.0.2.2 advertised-routes

received-routes shows what the peer sent before your inbound policy was applied, and it only works when inbound soft reconfiguration is enabled (neighbor x soft-reconfiguration inbound) or when the peer supports route refresh. routes shows what survived the filter and made it into the BGP table. Diffing the two outputs is the fastest way to answer "did the customer send it, or did we drop it?" — and show ip bgp neighbors x policy prints the actual filter chains in order, which is invaluable when a route disappears for reasons the configuration does not obviously explain.

Finally, remember the interaction with route selection: a filter that permits everything but sets no attributes leaves the decision entirely to the path-comparison cascade described in our BGP best path explainer. If you are also filtering at an IXP peering session with an AS-path filter, see BGP communities and AS-path filtering on IOS-XE. And if routes are entering and leaving your table repeatedly rather than being cleanly rejected, the problem may be dampening rather than filtering — review BGP route dampening before assuming your prefix-lists are wrong.