BGP Route Filtering in Practice

Introduction

Access Control Lists (ACLs) are one of the most fundamental tools in a network engineer’s toolkit. While they’re commonly associated with security and packet filtering, ACLs play an equally critical role in route filtering and manipulation. In this post, I’ll walk through three real-world scenarios from my lab environment where I used standard access lists with BGP distribute-lists to control route propagation between autonomous systems.

Lab Topology

My lab consists of six routers spanning multiple autonomous systems:

  • 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)

The topology demonstrates both eBGP peering between autonomous systems and iBGP relationships within AS 200. R-1 peers with R-2 using loopback interfaces and eBGP multihop, making this an ideal environment to test various filtering scenarios.

Topology

Understanding Distribute-Lists

Before diving into the examples, let’s clarify what distribute-lists do. A distribute-list applies an access list to filter routing updates in or out of a routing process. When used with BGP:

  • Inbound distribute-list: Filters routes received from a neighbor before installing them in the BGP table
  • Outbound distribute-list: Filters routes advertised to a neighbor

The key point is that distribute-lists affect route advertisements, not packet forwarding. This makes them perfect for controlling routing policy without impacting data plane traffic.

Case 1: Blocking Specific Prefix from BGP Neighbor

Scenario

R-1 in AS 100 is advertising multiple prefixes to R-2 in AS 200, including:

  • 1.0.0.0/8
  • 11.11.11.0/24
  • 11.11.111.0/24
  • 111.0.0.0/8

The goal is to prevent R-2 from accepting the 11.11.111.0/24 prefix while allowing all other routes.

Configuration

On R-1, I configured three loopback interfaces to simulate different networks:

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

On R-2, I created a standard access list and applied it inbound:

access-list 1 deny   11.11.111.0 0.0.0.255
access-list 1 permit any

router bgp 200
 neighbor 192.168.1.1 distribute-list 1 in

Results

Before applying the distribute-list, R-2’s BGP table showed all routes:

R-2#sh ip bgp          
     Network          Next Hop            Metric LocPrf Weight Path
 *>   1.0.0.0          192.168.1.1              0             0 100 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
 *>   111.0.0.0        192.168.1.1              0             0 100 i

After applying the distribute-list and performing a soft reset:

R-2#clear ip bgp * soft
R-2#sh ip bgp          
     Network          Next Hop            Metric LocPrf Weight Path
 *>   1.0.0.0          192.168.1.1              0             0 100 i
 *>   11.11.11.0/24    192.168.1.1              0             0 100 i
 *>   111.0.0.0        192.168.1.1              0             0 100 i

The 11.11.111.0/24 route was successfully filtered out. Checking the access list statistics confirms the filter is working:

R-2#sh access-lists 
Standard IP access list 1
    10 deny   11.11.111.0, wildcard bits 0.0.0.255 (1 match)
    20 permit any (3 matches)

Key Takeaway

This demonstrates a basic but crucial concept: you can selectively filter specific prefixes from a BGP neighbor without disrupting the entire peering relationship. The match counter in the ACL proves the filter is actively working.

Case 2: Filtering Odd Networks Using Wildcard Masks

Scenario

R-5 in AS 500 is advertising eight networks in the 205.1.x.0/24 range to R-3:

  • 205.1.1.0/24 through 205.1.8.0/24

The goal is to filter out only the odd-numbered networks (205.1.1.0, 205.1.3.0, 205.1.5.0, 205.1.7.0) while allowing even-numbered networks through.

Configuration

R-5’s loopback interfaces:

interface Loopback201
 ip address 205.1.1.1 255.255.255.0
interface Loopback202
 ip address 205.1.2.1 255.255.255.0
interface Loopback203
 ip address 205.1.3.1 255.255.255.0
interface Loopback204
 ip address 205.1.4.1 255.255.255.0
interface Loopback205
 ip address 205.1.5.1 255.255.255.0
interface Loopback206
 ip address 205.1.6.1 255.255.255.0
interface Loopback207
 ip address 205.1.7.1 255.255.255.0
interface Loopback208
 ip address 205.1.8.1 255.255.255.0

The magic happens in the wildcard mask. To match odd numbers in the third octet, I used:

access-list 1 deny   205.1.1.0 0.0.254.255
access-list 1 permit any

Let me break down this wildcard mask:

  • 0.0.254.255 → Binary: 00000000.00000000.11111110.11111111
  • The third octet has all bits set to 1 except the least significant bit
  • This means: “match if bit 0 of the third octet is 0 (odd numbers)”

Applying this outbound on R-5:

router bgp 500
 neighbor 192.1.35.3 distribute-list 1 out

Results

Before applying the filter, R-3 received all eight routes:

R-3#sh ip bgp | i 205
 *>   205.1.1.0        192.1.35.5               0             0 500 i
 *>   205.1.2.0        192.1.35.5               0             0 500 i
 *>   205.1.3.0        192.1.35.5               0             0 500 i
 *>   205.1.4.0        192.1.35.5               0             0 500 i
 *>   205.1.5.0        192.1.35.5               0             0 500 i
 *>   205.1.6.0        192.1.35.5               0             0 500 i
 *>   205.1.7.0        192.1.35.5               0             0 500 i
 *>   205.1.8.0        192.1.35.5               0             0 500 i

After applying the filter:

R-3#sh ip bgp | i 205
 *>   205.1.2.0        192.1.35.5               0             0 500 i
 *>   205.1.4.0        192.1.35.5               0             0 500 i
 *>   205.1.6.0        192.1.35.5               0             0 500 i
 *>   205.1.8.0        192.1.35.5               0             0 500 i

Perfect! Only even-numbered networks made it through. The ACL statistics show:

R-5#sh access-lists 
Standard IP access list 1
    10 deny   205.1.1.0, wildcard bits 0.0.254.255 (4 matches)
    20 permit any (5 matches)

Key Takeaway

Wildcard masks are incredibly powerful for pattern matching in ACLs. By carefully crafting the wildcard mask, you can filter based on binary patterns in IP addresses, enabling sophisticated filtering that would require multiple ACL entries otherwise. This technique is especially useful when dealing with subnetting schemes that follow specific patterns.

Case 3: Filtering Multiple Specific Networks

Scenario

R-6 in AS 600 is redistributing connected routes from 10 loopback interfaces in the 150.1.0.0/16 range to R-4. The requirement is to block these specific networks:

  • 150.1.74.0/24
  • 150.1.90.0/24
  • 150.1.202.0/24
  • 150.1.218.0/24

While allowing all others through.

Configuration

R-6’s loopback configuration spans a wide range:

interface Loopback101
 ip address 150.1.70.1 255.255.255.0
interface Loopback102
 ip address 150.1.74.1 255.255.255.0
interface Loopback103
 ip address 150.1.80.1 255.255.255.0
interface Loopback104
 ip address 150.1.90.1 255.255.255.0
interface Loopback105
 ip address 150.1.120.1 255.255.255.0
interface Loopback106
 ip address 150.1.150.1 255.255.255.0
interface Loopback107
 ip address 150.1.200.1 255.255.255.0
interface Loopback108
 ip address 150.1.202.1 255.255.255.0
interface Loopback109
 ip address 150.1.210.1 255.255.255.0
interface Loopback110
 ip address 150.1.218.1 255.255.255.0

Instead of creating four separate ACL entries, I looked for a pattern. Notice that all four blocked networks fall within a specific range when looking at the binary representation of the third octet:

  • 74 = 01001010
  • 90 = 01011010
  • 202 = 11001010
  • 218 = 11011010

After analysis, I crafted a wildcard mask that matches all four:

access-list 1 deny   150.1.74.0 0.0.144.255
access-list 1 permit any

The wildcard mask 0.0.144.255 (binary: 00000000.00000000.10010000.11111111) captures the bit pattern common to these four networks.

Additionally, I used a route-map with an access list to filter which connected routes get redistributed:

access-list 9 permit 150.1.0.0 0.0.255.255

route-map RC permit 10
 match ip address 9

router bgp 600
 redistribute connected route-map RC
 neighbor 192.1.46.4 distribute-list 1 out

Results

Before applying the distribute-list, R-4 received all 10 routes:

R-4#sh ip route bgp | i 150.1.
      150.1.0.0/24 is subnetted, 10 subnets
B        150.1.70.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.74.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.80.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.90.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.120.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.150.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.200.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.202.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.210.0 [20/0] via 192.1.46.6, 00:00:31
B        150.1.218.0 [20/0] via 192.1.46.6, 00:00:31

After applying the distribute-list and clearing the BGP session:

R-4#sh ip route bgp | i 150.1.
      150.1.0.0/24 is subnetted, 6 subnets
B        150.1.70.0 [20/0] via 192.1.46.6, 00:08:08
B        150.1.80.0 [20/0] via 192.1.46.6, 00:08:08
B        150.1.120.0 [20/0] via 192.1.46.6, 00:08:08
B        150.1.150.0 [20/0] via 192.1.46.6, 00:08:08
B        150.1.200.0 [20/0] via 192.1.46.6, 00:08:08
B        150.1.210.0 [20/0] via 192.1.46.6, 00:08:08

Exactly four routes were filtered out! The ACL statistics verify this:

R-6#sh access-lists 
Standard IP access list 1
    10 deny   150.1.74.0, wildcard bits 0.0.144.255 (4 matches)
    20 permit any (7 matches)
Standard IP access list 9
    10 permit 150.1.0.0, wildcard bits 0.0.255.255 (20 matches)

Key Takeaway

When you need to filter multiple specific networks, don’t immediately resort to multiple ACL entries. Analyze the binary patterns to see if a single wildcard mask can capture all targets. This not only reduces ACL size but also improves processing efficiency and maintainability.

Wildcard Mask Cheat Sheet

Understanding wildcard masks is critical for effective ACL usage. Here’s a quick reference:

Mask Meaning
0.0.0.0 Exact match
0.0.0.255 Match /24 network
0.0.255.255 Match /16 network
0.255.255.255 Match /8 network
0.0.0.254 Match even addresses in last octet
0.0.0.1 Match pairs (e.g., .0/.1, .2/.3)

Remember: 0 = must match, 1 = don’t care

To calculate wildcards for subnet ranges:

  1. Convert to binary
  2. Set bits to 0 that must match
  3. Set bits to 1 for “don’t care”
  4. Convert back to decimal

Conclusion

Access lists combined with BGP distribute-lists provide powerful, granular control over route propagation between autonomous systems. The three scenarios covered here demonstrate:

  1. Simple prefix filtering for blocking specific routes
  2. Pattern-based filtering using clever wildcard masks to match groups of routes
  3. Efficient filtering of multiple specific routes with a single ACL entry

These techniques are essential skills for any network engineer working with BGP. While prefix-lists and route-maps offer more features for complex scenarios, understanding standard ACLs and wildcard masks provides a solid foundation that translates to other networking contexts as well.

The key to mastering ACLs is practice. Set up your own lab, experiment with different scenarios, and always verify your results. The match counters in show access-lists and the BGP table in show ip bgp are your best friends for validation.

my DevOps Odyssey

“Σα βγεις στον πηγαιμό για την Ιθάκη, να εύχεσαι να ‘ναι μακρύς ο δρόμος, γεμάτος περιπέτειες, γεμάτος γνώσεις.” - Kavafis’ Ithaka.