The main purpose of this post is to show how prefix lists work and how to decipher them vs regular access lists. Access-lists do a great job on Cisco devices, not just for security but all kinds of route filtering, QoS, and so on.

A prefix list is a bit different form an access-list, and it’s important to know the differences and when to use either.

I’ve created the following simple topology to illustrate what I’m going to be doing. There are 2 routers, both running BGP. Router1 will have numerous loopbacks with IP addresses that will be advertised into the BGP process. On router2 I’ll use various access-lists and prefix-lists to see what kind of results I get. Remember though that prefix-lists can be used with other routing protocols and not just BGP.

This is the topology: R1 and R2

This is the config on each:

R1#sh run | begin bgp
router bgp 100
 no synchronization
 bgp log-neighbor-changes
 network 1.1.1.1 mask 255.255.255.255
 neighbor 10.1.1.10 remote-as 200
 no auto-summary
R2#sh run | begin bgp
router bgp 200
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.1.1.9 remote-as 100
 no auto-summary

I’ll put the following subnets on R1 and advertise them in BGP:

  • 192.168.1.1/24
  • 192.168.2.1/24
  • 192.168.3.1/25
  • 192.168.3.129/25
  • 192.168.4.1/25
  • 192.168.4.129/26
  • 192.168.4.193/26
#R1
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
!
interface Loopback1
 ip address 192.168.1.1 255.255.255.0
!
interface Loopback2
 ip address 192.168.2.1 255.255.255.0
!
interface Loopback3
 ip address 192.168.3.1 255.255.255.128
!
interface Loopback4
 ip address 192.168.3.129 255.255.255.128
!
interface Loopback5
 ip address 192.168.4.1 255.255.255.128
!         
interface Loopback7
 ip address 192.168.4.129 255.255.255.192
!         
interface Loopback8
 ip address 192.168.4.193 255.255.255.192

This is R1’s BGP config now:

R1#sh run | begin bgp
router bgp 100
 no synchronization
 bgp log-neighbor-changes
 network 1.1.1.1 mask 255.255.255.255
 network 192.168.1.0
 network 192.168.2.0
 network 192.168.3.0 mask 255.255.255.128
 network 192.168.3.128 mask 255.255.255.128
 network 192.168.4.0 mask 255.255.255.128
 network 192.168.4.128 mask 255.255.255.192
 network 192.168.4.192 mask 255.255.255.192
 neighbor 10.1.1.10 remote-as 200
 no auto-summary

On Router2, we can see the routes advertised:

R2#sh ip bgp 
BGP table version is 10, local router ID is 2.2.2.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 1.1.1.1/32       10.1.1.9                 0             0 100 i
*> 192.168.1.0      10.1.1.9                 0             0 100 i
*> 192.168.2.0      10.1.1.9                 0             0 100 i
*> 192.168.3.0/25   10.1.1.9                 0             0 100 i
*> 192.168.3.128/25 10.1.1.9                 0             0 100 i
*> 192.168.4.0/25   10.1.1.9                 0             0 100 i
*> 192.168.4.128/26 10.1.1.9                 0             0 100 i
*> 192.168.4.192/26 10.1.1.9                 0             0 100 i

Let’s say I want to filter out the network 192.168.4.0/25. If I use an access-list I need to do it as follows. Create the access list:

R2#conf t
R2(config)#access-list 5 deny   192.168.4.0 0.0.0.127
R2(config)#access-list 5 permit any

Add a rule to the BGP config:

R2#sh run | begin bgp
router bgp 200
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.1.1.9 remote-as 100
 neighbor 10.1.1.9 distribute-list 5 in
 no auto-summary

You can see that the 192.168.4.0/25 route has now been filtered out:

R2#sh ip bgp
   Network          Next Hop            Metric LocPrf Weight Path
*> 1.1.1.1/32       10.1.1.9                 0             0 100 i
*> 192.168.1.0      10.1.1.9                 0             0 100 i
*> 192.168.2.0      10.1.1.9                 0             0 100 i
*> 192.168.3.0/25   10.1.1.9                 0             0 100 i
*> 192.168.3.128/25 10.1.1.9                 0             0 100 i
*> 192.168.4.128/26 10.1.1.9                 0             0 100 i
*> 192.168.4.192/26 10.1.1.9                 0             0 100 i

Let’s say I wanted to filter out the 192.168.4.x/26’s as well. In order to do so I’d have to add another line for each network in my access-list. With a prefix-list it’s much easier to do this. Let’s remove the access-list and start again. NB: Prefix-lists, like access-lists, have a implicit DENY at the end. In an ACL you’ll place a permit any at the end. The prefix-list version of this is to permit 0.0.0.0/0 le 32

First I’ll create the prefix-list:

R2(config)#ip prefix-list exclude_4 seq 5 deny 192.168.4.0/24 ge 25 le 26
R2(config)#ip prefix-list exclude_4 seq 10 permit 0.0.0.0/0 le 32

Now I’ll apply it to the BGP process:

router bgp 200
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.1.1.9 remote-as 100
 neighbor 10.1.1.9 prefix-list exclude_4 in
 no auto-summary

When checking the BGP table I see the following:

R2#sh ip bgp
   Network          Next Hop            Metric LocPrf Weight Path
*> 1.1.1.1/32       10.1.1.9                 0             0 100 i
*> 192.168.1.0      10.1.1.9                 0             0 100 i
*> 192.168.2.0      10.1.1.9                 0             0 100 i
*> 192.168.3.0/25   10.1.1.9                 0             0 100 i
*> 192.168.3.128/25 10.1.1.9                 0             0 100 i

You can see that all the 192.168.4.1/25 and /26s are gone thanks to the prefix-list.

The basics of the prefix list is as follows. If I write

ip prefix-list exclude_4 seq 5 deny 192.168.4.0/24 ge 25 le 26

The /24 tells the IOS to match only the first 24 bits. i.e. 192.168.4 – I then tell the IOS to match only those prefixes that have a subnet mask of /25 or /26. i.e. If I had another network advertised which was 192.168.4.200/27 it would NOT match as even though the 192.168.4 part matches, it has a subnet mask of /27

Let’s say I wanted to now match 192.168.x.x/25 but I wanted to leave the /26’s in place. This would be easy with a prefix list as follows:

R2(config)#ip prefix-list exclude_4 seq 5 deny 192.168.3.0/16 ge 25 le 25 
R2(config)#ip prefix-list exclude_4 seq 10 permit 0.0.0.0/0 le 32

I’ve told IOS to only match on the first 16 bits, i.e. 192.168 – I then told IOS to only match those prefixes that have a subnet mask of /25. If I apply this to my BGP process I can see that it works as expected:

R2#sh ip bgp          
   Network          Next Hop            Metric LocPrf Weight Path
*> 1.1.1.1/32       10.1.1.9                 0             0 100 i
*> 192.168.1.0      10.1.1.9                 0             0 100 i
*> 192.168.2.0      10.1.1.9                 0             0 100 i
*> 192.168.4.128/26 10.1.1.9                 0             0 100 i
*> 192.168.4.192/26 10.1.1.9                 0             0 100 i

Only the 3 /25’s have disappeared, everything else is still there.

You can also do all of this with extended access-lists, but it’s so much more work, why make life difficult? Once you understand the context of prefix-lists it becomes very easy.

Originally publish with link https://mellowd.co.uk/ccie/?p=447