Introduction
In my previous post, I explored BGP route filtering using standard Access Control Lists (ACLs). While ACLs are powerful, they have limitations when it comes to matching based on prefix length. Enter prefix lists – a purpose-built tool for route filtering that offers superior control and readability for BGP route manipulation.
Prefix lists provide functionality that ACLs simply cannot match: the ability to filter routes based on both network address AND prefix length. This makes them the preferred choice for BGP route filtering in production networks.
In this post, I’ll demonstrate three practical scenarios using the same lab topology, but this time leveraging prefix lists to achieve more elegant and maintainable filtering solutions.
Why Prefix Lists Over ACLs?
Before diving into the examples, let’s understand why prefix lists are superior for BGP route filtering:
Advantages of Prefix Lists
- Prefix-length aware: Can match based on subnet mask (e.g., “only /24 networks”)
- More readable: Configuration clearly shows network and mask ranges
- Better performance: Optimized for route lookups
- Explicit sequences: Each entry has a sequence number for easy editing
- BGP-specific: Designed specifically for routing protocol filtering
Prefix List Operators
Prefix lists use three key operators:
- le (less than or equal): Matches prefix lengths up to and including specified value
- ge (greater than or equal): Matches prefix lengths from specified value and above
- Exact match: When neither ge nor le is specified
The syntax is: ip prefix-list NAME [seq #] {permit|deny} network/length [ge #] [le #]
Lab Topology
The topology remains identical to my ACL post:
- AS 100: R-1 (edge router)
- AS 200: R-2, R-3, R-4 (iBGP mesh)
- AS 500: R-5 (connected to R-3)
- AS 600: R-6 (connected to R-4)
Case 1: Blocking Entire Major Network (All 11.x.x.x Prefixes)
Scenario
R-1 in AS 100 is advertising multiple networks to R-2, including:
- 1.0.0.0/8
- 11.11.11.0/24
- 11.11.111.0/24
- 111.0.0.0/8
The requirement is to block ALL prefixes within the 11.0.0.0/8 major network from being advertised to R-2, regardless of their specific subnet mask.
Configuration
R-1’s loopback interfaces include networks in the 11.0.0.0 range:
interface Loopback101
ip address 11.11.11.11 255.255.255.0
interface Loopback102
ip address 11.11.111.111 255.255.255.0
interface Loopback103
ip address 111.111.111.111 255.255.255.0
R-1’s BGP configuration advertises these networks:
router bgp 100
network 1.0.0.0
network 11.11.11.0 mask 255.255.255.0
network 11.11.111.0 mask 255.255.255.0
network 111.0.0.0
neighbor 192.168.2.2 remote-as 200
neighbor 192.168.2.2 ebgp-multihop 255
neighbor 192.168.2.2 update-source Loopback99
Now, here’s the elegant prefix list solution on R-1:
ip prefix-list PL-1 seq 5 deny 11.0.0.0/8 le 32
ip prefix-list PL-1 seq 10 permit 0.0.0.0/0 le 32
router bgp 100
neighbor 192.168.2.2 prefix-list PL-1 out
Let me break down this prefix list:
Sequence 5: deny 11.0.0.0/8 le 32
- Matches the 11.0.0.0/8 network
le 32means “match prefix lengths from /8 up to and including /32”- This catches ALL possible subnets within 11.0.0.0/8 (11.0.0.0/8, 11.1.0.0/16, 11.11.11.0/24, 11.11.11.11/32, etc.)
Sequence 10: permit 0.0.0.0/0 le 32
- Matches any network (0.0.0.0/0)
le 32means “match any prefix length up to /32”- This is the “permit all” statement
Results
Before applying the prefix list, R-2 received all routes from R-1:
R-2#sh ip bgp
Network Next Hop Metric LocPrf Weight Path
*> 1.0.0.0 192.168.1.1 0 0 100 i
*> 2.0.0.0 0.0.0.0 0 32768 i
*>i 3.0.0.0 10.3.3.3 0 100 0 i
*>i 4.0.0.0 10.4.4.4 0 100 0 i
*>i 5.0.0.0 10.3.3.3 0 100 0 500 i
*>i 6.0.0.0 10.4.4.4 0 100 0 600 i
*> 11.11.11.0/24 192.168.1.1 0 0 100 i
*> 11.11.111.0/24 192.168.1.1 0 0 100 i
*> 22.2.2.0/24 0.0.0.0 0 32768 i
*> 111.0.0.0 192.168.1.1 0 0 100 i
After applying the prefix list on R-1 and performing a soft reset:
R-2#sh ip bgp
Network Next Hop Metric LocPrf Weight Path
*> 1.0.0.0 192.168.1.1 0 0 100 i
*> 2.0.0.0 0.0.0.0 0 32768 i
*>i 3.0.0.0 10.3.3.3 0 100 0 i
*>i 4.0.0.0 10.4.4.4 0 100 0 i
*>i 5.0.0.0 10.3.3.3 0 100 0 500 i
*>i 6.0.0.0 10.4.4.4 0 100 0 600 i
*> 22.2.2.0/24 0.0.0.0 0 32768 i
*> 111.0.0.0 192.168.1.1 0 0 100 i
Perfect! Both 11.11.11.0/24 and 11.11.111.0/24 were filtered out, while 111.0.0.0/8 (which doesn’t match 11.0.0.0/8) passed through.
Key Takeaway
With a single prefix-list entry using the le operator, we blocked an entire major network and all its possible subnets. Try doing that efficiently with ACLs – you’d need dozens of entries to cover all possible subnet combinations!
Case 2: Filtering Based on Prefix Length (Greater Than /27)
Scenario
R-5 in AS 500 is redistributing connected routes from multiple loopback interfaces in the 175.1.0.0/16 range:
- 175.1.1.0/24 (valid - /24)
- 175.1.2.16/28 (block - greater than /27)
- 175.1.3.32/27 (valid - exactly /27)
- 175.1.4.16/29 (block - greater than /27)
The requirement is to filter out any subnets of 175.1.0.0/16 with a prefix length greater than /27 (i.e., /28, /29, /30, /31, /32).
Configuration
R-5’s loopback configuration:
interface Loopback101
ip address 175.1.1.1 255.255.255.0
interface Loopback102
ip address 175.1.2.17 255.255.255.240
interface Loopback103
ip address 175.1.3.33 255.255.255.224
interface Loopback104
ip address 175.1.4.17 255.255.255.248
The route-map for redistribution (filters which connected routes get redistributed):
access-list 1 permit 175.1.0.0 0.0.255.255
route-map RC permit 10
match ip address 1
set origin igp
router bgp 500
redistribute connected route-map RC
Now, the prefix list to filter on prefix length:
ip prefix-list PL-1 seq 5 deny 175.1.0.0/16 ge 28
ip prefix-list PL-1 seq 10 permit 0.0.0.0/0 le 32
router bgp 500
neighbor 192.1.35.3 prefix-list PL-1 out
Breaking down this prefix list:
Sequence 5: deny 175.1.0.0/16 ge 28
- Matches the 175.1.0.0/16 network
ge 28means “greater than or equal to /28”- This denies 175.1.0.0/16 subnets with prefix lengths of /28, /29, /30, /31, or /32
- Networks with /24, /25, /26, or /27 will NOT match this entry
Sequence 10: permit 0.0.0.0/0 le 32
- Permits everything else
Results
Before applying the prefix list, R-3 received all four 175.1.x.x routes:
R-3#sh ip bgp | i 175.1.
*> 175.1.1.0/24 192.1.35.5 0 0 500 i
*> 175.1.2.16/28 192.1.35.5 0 0 500 i
*> 175.1.3.32/27 192.1.35.5 0 0 500 i
*> 175.1.4.16/29 192.1.35.5 0 0 500 i
After applying the prefix list on R-5:
R-3#sh ip bgp | i 175.1.
*> 175.1.1.0/24 192.1.35.5 0 0 500 i
*> 175.1.3.32/27 192.1.35.5 0 0 500 i
Exactly what we wanted! The /28 and /29 networks were filtered out, while the /24 and /27 networks passed through.
Key Takeaway
The ge (greater than or equal) operator allows precise filtering based on prefix length within a specific network range. This is impossible to achieve cleanly with standard ACLs.
Case 3: Global Prefix Length Filtering (Any Network > /24)
Scenario
Building on Case 2, we now have a more aggressive requirement: block ANY network from ANY address space that has a prefix length greater than /24.
This is a common real-world scenario where you want to:
- Prevent overly-specific routes from cluttering the BGP table
- Enforce routing policy that only accepts aggregate routes
- Reduce routing table size and improve stability
Configuration
The beauty of prefix lists shines here with an incredibly simple two-line configuration:
ip prefix-list PL-24 seq 5 deny 0.0.0.0/0 ge 25
ip prefix-list PL-24 seq 10 permit 0.0.0.0/0 le 32
router bgp 500
neighbor 192.1.35.3 prefix-list PL-24 out
Let’s analyze this prefix list:
Sequence 5: deny 0.0.0.0/0 ge 25
- Matches ANY network (0.0.0.0/0)
ge 25means “greater than or equal to /25”- This denies ALL routes with prefix lengths of /25 or longer
- Effectively blocks /25, /26, /27, /28, /29, /30, /31, and /32 networks from ANY address space
Sequence 10: permit 0.0.0.0/0 le 32
- Permits everything else (but only /0 through /24 will reach this statement)
Results
Before applying the global prefix length filter, R-3’s BGP table included routes with various prefix lengths:
R-3#sh ip bgp
Network Next Hop Metric LocPrf Weight Path
*>i 1.0.0.0 10.2.2.2 0 100 0 100 i
*>i 2.0.0.0 10.2.2.2 0 100 0 i
*> 3.0.0.0 0.0.0.0 0 32768 i
*>i 4.0.0.0 10.4.4.4 0 100 0 i
*> 5.0.0.0 192.1.35.5 0 0 500 i
*>i 6.0.0.0 10.4.4.4 0 100 0 600 i
*>i 111.0.0.0 10.2.2.2 0 100 0 100 i
*>i 150.1.70.0/24 10.4.4.4 0 100 0 600 i
*>i 150.1.80.0/24 10.4.4.4 0 100 0 600 i
*> 175.1.1.0/24 192.1.35.5 0 0 500 i
*> 175.1.3.32/27 192.1.35.5 0 0 500 i
*> 205.1.1.0 192.1.35.5 0 0 500 i
*> 205.1.2.0 192.1.35.5 0 0 500 i
After applying PL-24 on R-5:
R-3#sh ip bgp
Network Next Hop Metric LocPrf Weight Path
*>i 1.0.0.0 10.2.2.2 0 100 0 100 i
*>i 2.0.0.0 10.2.2.2 0 100 0 i
*> 3.0.0.0 0.0.0.0 0 32768 i
*>i 4.0.0.0 10.4.4.4 0 100 0 i
*> 5.0.0.0 192.1.35.5 0 0 500 i
*>i 6.0.0.0 10.4.4.4 0 100 0 600 i
*>i 111.0.0.0 10.2.2.2 0 100 0 100 i
*>i 150.1.70.0/24 10.4.4.4 0 100 0 600 i
*>i 150.1.80.0/24 10.4.4.4 0 100 0 600 i
*> 175.1.1.0/24 192.1.35.5 0 0 500 i
*> 205.1.1.0 192.1.35.5 0 0 500 i
*> 205.1.2.0 192.1.35.5 0 0 500 i
Notice that 175.1.3.32/27 disappeared! The global filter successfully removed all routes with prefix lengths greater than /24, regardless of the network address.
Key Takeaway
Using 0.0.0.0/0 ge 25 creates a universal filter that applies to all networks based purely on prefix length. This is incredibly powerful for enforcing routing policies across your entire network with just one statement.
Understanding ge and le: A Deep Dive
The ge (greater than or equal) and le (less than or equal) operators are what make prefix lists so powerful. Let’s break down the logic:
Prefix List Matching Logic
A prefix list entry matches if:
- The network portion matches the specified prefix
- The prefix length falls within the specified range
The range is determined by:
- Lower bound: The prefix length specified in the entry (e.g., /16 in
175.1.0.0/16) - Upper bound: Determined by
leoperator (or 32 if not specified) - Restricted by: The
geoperator, which sets a minimum prefix length
Examples with ge/le
ip prefix-list EXAMPLE deny 10.0.0.0/8 le 24
- Matches: 10.0.0.0/8 through 10.0.0.0/24
- Matches: 10.1.0.0/16, 10.1.1.0/24
- Does NOT match: 10.1.1.0/25 (greater than /24)
ip prefix-list EXAMPLE deny 10.0.0.0/8 ge 24
- Matches: 10.0.0.0/24 through 10.0.0.0/32
- Matches: 10.1.1.0/24, 10.1.1.1/32
- Does NOT match: 10.1.0.0/16 (less than /24)
ip prefix-list EXAMPLE deny 10.0.0.0/8 ge 16 le 24
- Matches: 10.0.0.0/16 through 10.0.0.0/24
- Matches: 10.1.0.0/16, 10.1.1.0/24
- Does NOT match: 10.0.0.0/8 (less than /16) or 10.1.1.0/25 (greater than /24)
ip prefix-list EXAMPLE deny 10.0.0.0/8
- Matches: ONLY 10.0.0.0/8 (exact match)
- Does NOT match: Any other prefix length
The “Permit Any” Statement
The universal permit statement in prefix lists:
ip prefix-list NAME permit 0.0.0.0/0 le 32
This matches:
- Any network (0.0.0.0/0 matches all addresses)
- Any prefix length from /0 to /32
Prefix Lists vs ACLs: Side-by-Side Comparison
Let’s compare the approaches for the same filtering requirements:
Filtering 11.0.0.0/8 and all subnets
ACL approach:
! Would need hundreds of entries to cover all possible subnets
access-list 1 deny 11.0.0.0 0.255.255.255
access-list 1 deny 11.0.0.0 0.0.255.255
access-list 1 deny 11.0.0.0 0.0.0.255
! ... and many more for /9, /10, /11, /12, /13, /14, etc.
access-list 1 permit any
Prefix list approach:
! Single entry does it all
ip prefix-list PL-1 deny 11.0.0.0/8 le 32
ip prefix-list PL-1 permit 0.0.0.0/0 le 32
Filtering routes greater than /24
ACL approach:
! Impossible to achieve cleanly with standard ACLs
! Would need extended ACL with packet length matching (not supported)
! Or would need to list every possible /25, /26, /27, /28, /29, /30, /31, /32
! network across all possible address spaces - billions of entries
Prefix list approach:
! Simple and elegant
ip prefix-list PL-24 deny 0.0.0.0/0 ge 25
ip prefix-list PL-24 permit 0.0.0.0/0 le 32
Best Practices for Prefix Lists
1. Use Descriptive Names
Instead of generic names like “PL-1”, use names that describe the purpose:
ip prefix-list BLOCK-11-NET deny 11.0.0.0/8 le 32
ip prefix-list BLOCK-11-NET permit 0.0.0.0/0 le 32
ip prefix-list MAX-PREFIX-24 deny 0.0.0.0/0 ge 25
ip prefix-list MAX-PREFIX-24 permit 0.0.0.0/0 le 32
2. Use Sequence Numbers for Easy Editing
Sequence numbers allow you to insert, delete, or modify individual entries:
! Initial configuration
ip prefix-list FILTER seq 5 deny 10.0.0.0/8 le 32
ip prefix-list FILTER seq 100 permit 0.0.0.0/0 le 32
! Need to add an entry? Use sequence numbers between existing ones
ip prefix-list FILTER seq 10 deny 172.16.0.0/12 le 32
! Final result:
! seq 5: deny 10.0.0.0/8 le 32
! seq 10: deny 172.16.0.0/12 le 32
! seq 100: permit 0.0.0.0/0 le 32
3. Always Include Explicit Permit
Unlike ACLs, prefix lists have an implicit “deny all” at the end. Always include an explicit permit statement:
ip prefix-list FILTER deny 10.0.0.0/8 le 32
ip prefix-list FILTER permit 0.0.0.0/0 le 32 ! Don't forget this!
4. Document Complex Logic
Add comments for complex prefix lists:
! Block all RFC1918 private networks
ip prefix-list NO-PRIVATE seq 5 deny 10.0.0.0/8 le 32
ip prefix-list NO-PRIVATE seq 10 deny 172.16.0.0/12 le 32
ip prefix-list NO-PRIVATE seq 15 deny 192.168.0.0/16 le 32
! Permit everything else
ip prefix-list NO-PRIVATE seq 100 permit 0.0.0.0/0 le 32
5. Test Before Deploying to Production
Use the show ip prefix-list detail command to verify your configuration, and test in a lab environment first:
R-5#show ip prefix-list detail PL-1
ip prefix-list PL-1:
count: 2, range entries: 1, sequences: 5 - 10, refcount: 2
seq 5 deny 175.1.0.0/16 ge 28 (hit count: 2)
seq 10 permit 0.0.0.0/0 le 32 (hit count: 12)
6. Use Soft Reset for BGP Changes
After modifying prefix lists, use soft reset to apply changes without disrupting the BGP session:
clear ip bgp * soft out
Or for both directions:
clear ip bgp * soft
Common Use Cases for Prefix Lists
1. Filtering Default Routes
! Block default route
ip prefix-list NO-DEFAULT deny 0.0.0.0/0
ip prefix-list NO-DEFAULT permit 0.0.0.0/0 le 32
2. Accepting Only Specific Prefix Lengths
! Accept only /24 networks
ip prefix-list ONLY-24 permit 0.0.0.0/0 ge 24 le 24
3. Filtering Private Address Space
! Block RFC1918 private addresses
ip prefix-list NO-PRIVATE deny 10.0.0.0/8 le 32
ip prefix-list NO-PRIVATE deny 172.16.0.0/12 le 32
ip prefix-list NO-PRIVATE deny 192.168.0.0/16 le 32
ip prefix-list NO-PRIVATE permit 0.0.0.0/0 le 32
4. Accepting Customer Routes Only
! Accept only routes from customer's assigned space
ip prefix-list CUSTOMER permit 203.0.113.0/24 le 32
5. Enforcing Aggregation Policy
! Accept only summary routes (/8 through /24)
ip prefix-list AGGREGATED-ONLY permit 0.0.0.0/0 ge 8 le 24
Troubleshooting Prefix Lists
Verify Configuration
show ip prefix-list [name]
show ip prefix-list [name] detail
The detail option shows hit counts, which is invaluable for troubleshooting:
R-5#show ip prefix-list detail PL-24
ip prefix-list PL-24:
count: 2, range entries: 1, sequences: 5 - 10, refcount: 1
seq 5 deny 0.0.0.0/0 ge 25 (hit count: 1)
seq 10 permit 0.0.0.0/0 le 32 (hit count: 14)
Test Prefix List Matching
You can test what a prefix list will match:
show ip prefix-list [name] network/length
Example:
R-5#show ip prefix-list PL-24 175.1.3.32/27
ip prefix-list PL-24:
seq 5 deny 0.0.0.0/0 ge 25 (hit count: 1) ← This entry matches!
Check BGP Neighbor Configuration
Verify that prefix lists are applied correctly:
show ip bgp neighbors [address] | include prefix-list
Common Issues and Solutions
Issue: Prefix list not working
- Solution: Check that it’s applied in the correct direction (in/out) and to the correct neighbor
Issue: Too many or too few routes being filtered
- Solution: Review your ge/le logic; test with
show ip prefix-list detail
Issue: Changes not taking effect
- Solution: Remember to perform soft reset:
clear ip bgp * soft
Performance Considerations
Prefix lists are optimized for route filtering and offer better performance than ACLs:
- Indexed lookups: Prefix lists use tree-based lookups, making them faster for large lists
- Memory efficient: Optimized data structures reduce memory footprint
- BGP-optimized: Designed specifically for route matching operations
For networks with thousands of routes, this performance difference becomes significant.
Conclusion
Prefix lists are the superior tool for BGP route filtering when you need to match based on network address and prefix length. The three scenarios we explored demonstrate:
- Network-based filtering: Blocking entire major networks and all their subnets with a single entry
- Length-specific filtering: Filtering routes based on prefix length within a specific network range
- Global length policies: Enforcing prefix-length policies across all networks
Key advantages of prefix lists over ACLs:
- Prefix-length awareness: Match based on subnet mask
- Simplicity: Achieve complex filtering with fewer entries
- Readability: Clear, intuitive syntax
- Performance: Optimized for route lookups
- Maintainability: Sequence numbers for easy editing
The ge and le operators provide powerful pattern-matching capabilities that are simply impossible with standard ACLs. While ACLs still have their place (packet filtering, for example), prefix lists should be your go-to tool for BGP route filtering.