BGP route filtering – Access lists vs Prefix lists

When filtering routes with BGP it’s very likely that you’ve used prefix lists.  Once again, this is just something that we’ve been taught to do and consider good practice.  On the flip side, there is the option within BGP to filter prefixes using both standard and extended ACLs.  Let’s review all 3 options to make sure we have a good handle on how each of them work.  We’ll start with this simple lab…


Let us assume that router1 and router2 are eBGP peered.  In addition, router1 has the above listed networks available in it’s BGP table to advertise to router2…


Assuming all is working in default manner, we should see these routes on router2 as well…


Looks like things are working as expected. 

Side Note: Do you notice that the prefixes for,, and do not list a subnet mask in either BGP table?  Care to wager why that is?  If you recall from our classful network post earlier, the mask of /24 is the natural or classful mask for all three of those networks.  Since this is implied, there’s no need to display it. 

Now let’s take a look at filtering the advertisements to router2 using all three methods.  We’ll start with the most common method…

Prefix Lists
Let’s assume that we only want to advertise the 192 networks to router2.  This could be accomplished in several ways using prefix lists.  Naturally, we could define a prefix list that has 4 entries, one that matches each exact prefix.  However, that’s not a lot of fun.  Let’s start off with this prefix list to make sure we’re all on the same page…


The prefix list in this case is permitting prefixes that match… /9 GE 24

The resulting BGP prefixes that get sent to router2 are…


Let’s quickly review prefix list syntax.  The prefix list is broken into three sections.  The prefix (or network), the mask (often called LEN), and the optional mask range (GE and LE).

When GE (Greater than or Equal to) and/or LE (Less than or equal to) are added to a prefix list entry they cause the behavior of the prefix list to change.  Without a GE or LE, the mask is used to determine the specific mask length for the prefix to match.  Take for example the following two prefixes… /24 /16

Given the above two prefixes, the prefix list entry of…

ip prefix-list test permit

will ONLY match the exact prefix of /16.  However, when you add a GE, LE, or both, the mask now turns into how much of the prefix you want to examine.  For instance, the prefix list entry of…

ip prefix-list test permit ge 16

would now match both of those prefixes.  The prefix and mask tell you that you are only interested in the first 15 bits of any prefix matching your defined network.  The GE tells you that the prefix also has to have a subnet mask greater than or equal to 16.

In our lab example, we told the prefix list to match the first 9 bits of the prefix.  In other words, the ‘/9’ tells the router to look at all of the prefixes, and find the ones whose first 9 bits match the prefix specified.  Looking at just the 192 prefixes, we can see that only the 192.129 and 192.128 prefixes are a match on the first 9 bits…


Since we specified the prefix was that implies that the first bit of the second octet needs to be a 1.  Only two prefixes match that so we only advertise two prefixes.  Let’s modify the prefix list slightly to see how it changes…


Here we’ve modified the prefix list to only care about the first 8 bits of the prefix.  This will match all of the 192 prefixes.  However, we’ve also told it that the subnet mask has to be less than or equal to 24 bits in length.  That means that the following prefixes get advertised to router2…


Let’s make one more change to the prefix list to show one final point…


The first thing we do is add three more routes.  Then we delete the prefix list and recreate it using the following statements…

PERMIT /24 GE 25

Looking at router2, we see the following prefixes arriving…


Let’s walk through all of the prefixes and see how this happened…


After the first entry is processed the results table looks like what is shown above.  If you are wondering why the table is blank it’s because the first entry in the prefix list does noting.  Recall that when you don’t specify GE or LE the mask (or LEN) field applies directly to the subnet mask of the specific prefix.  In this case, we don’t have a route for /8 so nothing happens. 


After the second entry is parsed we see that we now have three matches.  Since the 2nd entry specifies GE we know that the LEN of the prefix list entry should be used to determine how much of the prefix we want to match.  In this case, the LEN was 24 which is saying that the first 3 octets of the prefix (172.64.1) need to match.  In our case, there were 4 prefixes that meet that requirement.  However, only 3 of them have a subnet mask that was greater than or equal to 25.


The third entry again uses GE and the LEN tells us to examine only the first octet (or first 8 bits) of the prefix to see if it’s a match.  There are 5 prefixes that match that requirement but only 2 of them match the GE requirement of having a mask longer than or equal to 30. 


What is not shown in the prefix list is the implicit deny that occurs after the last permit sequence.  Note that no other prefixes showed up in router2’s BGP table. 

So that was a sort of long overview of prefix lists but it’s crucial that you understand how they work. 

Standard Access Lists
Standard ACLs are a more generic means to replicate the LEN function when it is used with GE or LE.  That is, using a standard ACL to filter routes just tells the router how much of the prefix bits to look at.  Let’s take a look at a quick example…


Here I configure a standard ACL that’s looking for 172.64.1.X.  I then apply it as a distribute list to the BGP neighbor and do a soft clear on the BGP peering.  The result on router2 is shown below…


As stated, it looked at all of the prefixes and sent the ones whose first three octets match 172.64.1.  In that case, that was all four of these…


You can see that in this case, we weren’t at all interested in the subnet mask length.  Only the first three octets of the prefix.  Let’s do another quick example to prove the point…


Now if we look at router2, we see these prefixes in the BGP table…


Confused?  Let’s walk through it on the graph so you can see…


Let’s break down the ACL.  The first chunk was  Let’s focus on the first octet.  In binary, that would be…


The second part of the ACL is the mask which is  As I recall from my early days of networking, the wild card mask is sometimes called the ”don’t care bits”.  In this case the 2nd through 4th octet is all 1’s so we don’t care at all about any of those octets.  The first octet though is a decimal 127 which in Binary would be…


So what we’re showing here is that because of this standard ACL we ONLY care whether or not the first bit of the first octet is a 1 which would include any number from 128 to 255.  Put together you see that the only bit we care about is the ‘128’ bit in the first octet…


Since the prefix has a 1 in the only ‘I care spot’ any prefix that is going to match this ACL also has to have a binary 1 in the 128 spot. 

This sort of matching can be sort of interesting.  Take for instance this example…


Here I add another route and then change the standard ACL to permit  Comparing the prefix and mask we can tell that the prefix needs to start with 192.1.  The fourth octet can be anything and the third octet tells us that we don’t care about anything except for the last bit of the third octet which happens to be the spot for ‘1’. 

This ACL will give us all of the prefixes that start with 192.1 and have an odd number in the third octet…


Taken a step further, we could say something like this…


Can you work out what this will give us?  Any prefix that has an odd number in the third octet regardless of what’s in the 1st, 2nd, or 4th octet…


To make it more clear, let’s change it to an even number in the 2nd octet…


And router2 sees…


Pretty cool huh?  Not sure where you’d ever need to redistribute odd or even prefixes but it is certainly another way to filter prefixes. 

Extended Access Lists
Extended ACLs allow you a little more granularity over standard ACLs since you can once again specify the mask you are looking for.  In fact, you can specify a range of masks as well.  Let’s do something similar to what we did above with the standard ACLs by specifying we only want routes with an odd third octet.  I’m going to add some more static routes to give us more to play with…


I started by adding three more static routes to use later on.  Then I removed the distribute list for ACL 1 and replaced it with the extended ACL 100.  Lastly, I created the extended ACL 100 and used the following syntax…


Let’s break this down.  Much like we did on the standard ACL, the first chunk of the extended ACL tells us to look for the ‘1’ bit being marked in the third octet.  This would imply that the third octet is odd.  The second part of the extended ACL tells us what kind of mask to look for.  In this case, we only want ones that have a mask of /24.  Looking at our chart, I would then expect to see the following routes on router2…


Note: I hope you’ve caught on but each time I use this table I highlight the pieces of the table that were used to make the permit decision in red.  It may be confusing to you as to why the first two octets above are all red but then the third octet has the far right bit red with the rest black.  Keep in mind that we are using wild card masks here.  Wildcards are essentially the inverse of the actual mask specifying which bits should not be taking into account.  In this case, we don’t want to account for anything except the ‘1’ bit so we specify 254 which equates to 11111110 in binary. 

Taking a look at router2, we can see that our assumptions are correct…


At this point, the extended ACL has given us the same ability as the standard ACL but also allowed us to check the subnet mask of the prefix.  Let’s change things up a bit to see what else we can do…


The result on router2 is…


Our table now looks like this…


Did you catch what happened?  Let’s walk through it once again to make sure.  The extended access list entry looked like this…


The first half of the ACL functions just like the standard ACL allowing us to find prefixes that have an odd third octet.  The second half of the ACL ( requires a little more explaining. 

As we saw in the first extended ACL example, you can simply specify the mask you want the matching prefixes to have.  In this case, that would be /24 or  So far so good. Now what’s going on with the piece of this?  Much like how you can wild card the prefix, you can also wild card the subnet mask.  In this case, we specify that the first three octets of the mask need to match by using 0.0.0.  AKA, 255.255.255 will be the first three mask octets.  The fourth octet, we say that we want the decimal of 243.  In binary, that gives us…

243 = 11110011

So let’s look at the fourth octet for some of the other prefixes…

0     = 00000000
243 = 11110011
248 = 11111000
240 = 11110000

Recall that with wild cards masks the ‘1’s are the “don’t care” bits.  As you can see, the 0’s are the “care” bits.  The mask itself has a decimal 0 for the fourth octet which would be ‘00000000’ in binary.  This wild card mask is saying that this extended ACL needs the fourth octet to have binary 0s in the 4 and 8 bit positions.  Since the mask for a /29 is, the 8 bit position in the fourth octet is a 1.  So as you can see, the /28 networks pass just fine since there 4 and 8 bits are already ‘0’.  The /29 networks have an issue since their ‘8 bit is a ‘1’. 

If we change the ACL to say…


we would start seeing the /29 prefixes on router2…



Wrap Up
So as you can see there are some interesting use cases for using ACLs rather than prefix lists when filtering BGP routes.  I must admit, I don’t see an uber valid use case for ACLs over prefix lists though and I do recall hearing that using ACLs are more processor intensive.

Either way it’s some interesting material to dwell on!


9 thoughts on “BGP route filtering – Access lists vs Prefix lists

  1. Rajesh

    How to

    I liked your way of explaining things and I was trying to work out by breaking the octets to 0’s and 1’s. Can you please explain how to interpret the following ACL??

    permit ip any


    Will the above ACL will check the first 4 digits which are 0’s at the 4th Octet?? Will it care any thing on the 3rd Octet??


    1. Jon Langemak Post author

      With an extended ACL the ‘0’ bits are the ‘care’ bits. That being said, I would expect that the example you listed would expect 10 in the first octet, 27 in the second octet, anything in the third octet, and a number made up of the 4 higher order bits (16,32,64, or 128) in the fourth octet. I would also suspect that you could have any mask that you like in this scenario.

      Have you labbed it?

      1. Jeff Clarke

        Exact Match of “10” in the 1st Octet
        Exact Match of “27” in the 2nd Octet
        Any value in the 3rd Octet
        “224” thru “239” in the 4th Octet

        The last 4 bits of the 4th Octet are “Don’t Cares”, so if you mask the 4th Octet value “224” in the ACL with “0000 1111” you actually get “224”, as you will with “225”, “226”…….”239″.

  2. Rajesh

    Thanks Mate.

    This ACL is from a production box and it’s working. I was trying to understand the logic behind this ACL.

  3. RS

    Hi – It was a very good comparison of prefix lists with ACLs. Appreciate if you can also explain with an extended ACL example to cover equivalent of prefix list with GE and both LE & GE options.
    Cheers /RS

  4. Pingback: BGP route filtering – Access lists vs Prefix lists – skminhaj

Leave a Reply

Your email address will not be published. Required fields are marked *