BGP Extended Access-List Filtering

Nowadays we use prefix-lists to filter BGP prefixes. Prefix-lists are very convenient since they allow you to specify a network address with a specific prefix length or a range of prefix lengths. Back in the days, before prefix-lists existed on Cisco IOS you had to use extended access-lists for this.

You really don’t want to use these anymore since the prefix-list does the same thing and the configuration is much easier. However, when you face a CCIE lab it might be possible that a task requires you to filter certain prefixes but you are not allowed to use the prefix-list. The extended access-list will be your only option then…

Having said that, let’s take a look how extended access-list filtering works. The “behavior” of the extended access-list is different compared to when you use it for filtering IP packets.

When you use IP as the protocol, here’s what the extended access-list normally looks like:

Extended access-list filtering

Above you see the source address with the source wildcard bits and the destination address with destination wildcard bits. Now forget what you have seen above, this is how the extended access-list works for BGP filtering:

extended access list bgp filtering

Let me explain these fields:

  • The first field is for the network address, for example 10.0.0.0.
  • The second field is used to define what part of the network address to check. For example, when we specify 10.0.0.0 then we use wildcard bits to tell the router if we want to look for 10.0.0.0, 10.0.0.x, 10.0.x.x or 10.x.x.x.
  • The subnet mask and its wildcard bits are used to define the prefix length, we can use this to tell the router to look for /24, /25, /26 or a range like /24 to /32.

Using the extended access-list for BGP filtering is something that is best explained with some examples. I’ll use two routers and some prefixes and we’ll walk through some different filtering examples.

Configuration

I will use the following two routers for this:

R1 R2 AS1 AS2 filtering topology

R2 has a bunch of loopback interfaces with different networks, we’ll use these to play with filtering.




Here’s what R2 advertises to R1:

R2#show ip bgp neighbors 192.168.12.1 advertised-routes 
BGP table version is 35, local router ID is 192.168.7.25
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0/24      0.0.0.0                  0         32768 i
*> 10.1.0.0/24      0.0.0.0                  0         32768 i
*> 10.2.0.0/24      0.0.0.0                  0         32768 i
*> 10.3.0.0/25      0.0.0.0                  0         32768 i
*> 10.3.0.128/25    0.0.0.0                  0         32768 i
*> 10.4.0.0/25      0.0.0.0                  0         32768 i
*> 10.4.0.128/25    0.0.0.0                  0         32768 i
*> 10.5.0.0/26      0.0.0.0                  0         32768 i
*> 10.6.0.0/27      0.0.0.0                  0         32768 i
*> 10.7.0.0/28      0.0.0.0                  0         32768 i
*> 10.8.1.0/24      0.0.0.0                  0         32768 i
*> 10.8.2.0/24      0.0.0.0                  0         32768 i
*> 20.0.0.0         0.0.0.0                  0         32768 i
*> 30.0.0.0         0.0.0.0                  0         32768 i
*> 172.16.0.0/24    0.0.0.0                  0         32768 i
*> 172.16.1.0/24    0.0.0.0                  0         32768 i
*> 172.16.2.0/25    0.0.0.0                  0         32768 i
*> 172.16.3.0/25    0.0.0.0                  0         32768 i
*> 172.16.4.0/26    0.0.0.0                  0         32768 i
*> 172.16.5.0/27    0.0.0.0                  0         32768 i
*> 172.16.6.0/28    0.0.0.0                  0         32768 i
*> 172.16.7.0/29    0.0.0.0                  0         32768 i
*> 192.168.0.0      0.0.0.0                  0         32768 i
*> 192.168.1.0      0.0.0.0                  0         32768 i
*> 192.168.2.0/25   0.0.0.0                  0         32768 i
*> 192.168.3.0/25   0.0.0.0                  0         32768 i
*> 192.168.4.0/26   0.0.0.0                  0         32768 i
*> 192.168.5.0/27   0.0.0.0                  0         32768 i
*> 192.168.6.0/28   0.0.0.0                  0         32768 i
*> 192.168.7.0/29   0.0.0.0                  0         32768 i
*> 192.168.7.8/29   0.0.0.0                  0         32768 i
*> 192.168.7.16/29  0.0.0.0                  0         32768 i
*> 192.168.7.24/30  0.0.0.0                  0         32768 i
*> 192.168.12.0     0.0.0.0                  0         32768 i

Total number of prefixes 34

Let’s start with some simple examples…

Filter specific prefixes

Let’s say that we to filter some specific prefixes, let’s pick:

  • 20.0.0.0 /8
  • 172.16.0.0 /24
  • 192.168.1.0 /24

Here’s what the access-list will look like:

R1(config)#access-list 100 permit ip 20.0.0.0 0.0.0.0 255.0.0.0 0.0.0.0
R1(config)#access-list 100 permit ip 172.16.0.0 0.0.0.0 255.255.255.0 0.0.0.0
R1(config)#access-list 100 permit ip 192.168.1.0 0.0.0.0 255.255.255.0 0.0.0.0         

R1(config)#router bgp 1
R1(config-router)#distribute-list 100 in

R1#clear ip bgp *

Before we check the result, let me explain the access-list:

  • In the first entry we want an exact match for “20.0.0.0” so we use network 20.0.0.0 with wildcard 0.0.0.0. The prefix-length has to be exactly /8 so we use subnet mask 255.0.0.0 with wildcard 0.0.0.0.
  • In the second entry we want an exact match for “172.16.0.0” so we use network 172.16.0.0 with wildcard 0.0.0.0. The prefix-length has to be exactly /24 so we use subnet mask 255.255.255.0 with wildcard 0.0.0.0.
  • In the last entry we want an exact match for “192.168.1.0” so we use network 192.168.1.0 with wildcard 0.0.0.0. The prefix-length has to be exactly /24 so we use subnet mask 255.255.255.0 with wildcard 0.0.0.0.

Let’s see what we get:

R1#show ip bgp 
BGP table version is 4, local router ID is 192.168.12.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
r> 20.0.0.0         192.168.12.2             0             0 2 i
r> 172.16.0.0/24    192.168.12.2             0             0 2 i
r> 192.168.1.0      192.168.12.2             0             0 2 i

Great, we only see our three specific prefixes.

In my BGP table, you can see R1 is unable to install these prefixes because of a RIB-failure. This seems to occur because the router refuses to use the next hop IP address unless you permit it. I couldn’t find anything about this in the Cisco documentation but you can solve it by adding this statement to access-list 100: permit ip host 192.168.12.2 any

One little “extra” that the access-list offers us that the prefix-list doesn’t is that it shows matches:

R1#show access-lists 100
Extended IP access list 100
    10 permit ip host 20.0.0.0 host 255.0.0.0 (2 matches)
    20 permit ip host 172.16.0.0 host 255.255.255.0 (1 match)
    30 permit ip host 192.168.1.0 host 255.255.255.0 (2 matches)

Let’s try something else now!

Filter all 192.168.x.0 networks with a /24 prefix length

Let’s say that we want to filter all networks in the 192.168.x.0 range that have a /24 prefix length. R2 is currently advertising these networks:

R2#show ip bgp neighbors 192.168.12.1 advertised-routes | include 192.168.
BGP table version is 36, local router ID is 192.168.7.17
*> 192.168.0.0      0.0.0.0                  0         32768 i
*> 192.168.1.0      0.0.0.0                  0         32768 i
*> 192.168.2.0/25   0.0.0.0                  0         32768 i
*> 192.168.3.0/25   0.0.0.0                  0         32768 i
*> 192.168.4.0/26   0.0.0.0                  0         32768 i
*> 192.168.5.0/27   0.0.0.0                  0         32768 i
*> 192.168.6.0/28   0.0.0.0                  0         32768 i
*> 192.168.7.0/29   0.0.0.0                  0         32768 i
*> 192.168.7.8/29   0.0.0.0                  0         32768 i
*> 192.168.7.16/29  0.0.0.0                  0         32768 i
*> 192.168.7.24/30  0.0.0.0                  0         32768 i
*> 192.168.12.0     0.0.0.0                  0         32768 i

We only want to see 192.168.0.0 /24, 192.168.1.0 /24 and 192.168.12.0 /24 on R1. Here’s the access-list we will create:

R1(config)#access-list 101 permit ip 192.168.0.0 0.0.255.0 255.255.255.0 0.0.0.0
   
R1(config)#router bgp 1
R1(config-router)#distribute-list 101 in

R1#clear ip bgp *

Let me explain the access-list:

  • The network address we want to check is 192.168.0.0.
  • The wildcard is 0.0.255.0 which means the 1st, 2nd and 4th octet have to match. We don’t care about the 3rd octet.
  • The subnet mask is 255.255.255.0 and this has to match exactly which is why we use a 0.0.0.0 wildcard.

Here’s the result:

R1#show ip bgp 
BGP table version is 4, local router ID is 192.168.12.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
r> 192.168.0.0      192.168.12.2             0             0 2 i
r> 192.168.1.0      192.168.12.2             0             0 2 i
r> 192.168.12.0     192.168.12.2             0             0 2 i

Great, these are the only 192.168.x.0 /24 networks that we have. Time for the next example…

Filter all 10.x.x.0 networks with a /24 prefix length

This one is similar to the previous example but this time we check the 10.x.x.0 range. Here are the networks that R2 is advertising:

R2#show ip bgp neighbors 192.168.12.1 advertised-routes | include 10.
*> 10.0.0.0/24      0.0.0.0                  0         32768 i
*> 10.1.0.0/24      0.0.0.0                  0         32768 i
*> 10.2.0.0/24      0.0.0.0                  0         32768 i
*> 10.3.0.0/25      0.0.0.0                  0         32768 i
*> 10.3.0.128/25    0.0.0.0                  0         32768 i
*> 10.4.0.0/25      0.0.0.0                  0         32768 i
*> 10.4.0.128/25    0.0.0.0                  0         32768 i
*> 10.5.0.0/26      0.0.0.0                  0         32768 i
*> 10.6.0.0/27      0.0.0.0                  0         32768 i
*> 10.7.0.0/28      0.0.0.0                  0         32768 i
*> 10.8.1.0/24      0.0.0.0                  0         32768 i
*> 10.8.2.0/24      0.0.0.0                  0         32768 i

Let’s build an access-list:

R1(config)#access-list 102 permit ip 10.0.0.0 0.255.255.0 255.255.255.0 0.0.0.0

R1(config)#router bgp 1
R1(config-router)#distribute-list 102 in

R1#clear ip bgp *

Let me explain the access-list:

  • The network we want to check is 10.0.0.0 but we only care about the 1st and 4th octet, the 2nd and 3rd octet can be everything so we use wildcard 0.255.255.0.
  • We want all networks with a /24 prefix length so we use 255.255.255.0 as the subnet mask. This has to be an exact match so we use 0.0.0.0 as the wildcard.

Here’s what we get:

R1#show ip bgp 
BGP table version is 6, local router ID is 192.168.12.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
r> 10.0.0.0/24      192.168.12.2             0             0 2 i
r> 10.1.0.0/24      192.168.12.2             0             0 2 i
r> 10.2.0.0/24      192.168.12.2             0             0 2 i
r> 10.8.1.0/24      192.168.12.2             0             0 2 i
r> 10.8.2.0/24      192.168.12.2             0             0 2 i

Great, these are all networks in the 10.x.x.0 range with a /24 prefix length. Let’s try something else…

Filter all 10.x.x.x networks with a /25 prefix length

This time I want to see all networks in the 10.x.x.x range with a /25 prefix length. Here are all 10.x.x.x networks that R2 is advertising again:

R2#show ip bgp neighbors 192.168.12.1 advertised-routes | include 10.
*> 10.0.0.0/24      0.0.0.0                  0         32768 i
*> 10.1.0.0/24      0.0.0.0                  0         32768 i
*> 10.2.0.0/24      0.0.0.0                  0         32768 i
*> 10.3.0.0/25      0.0.0.0                  0         32768 i
*> 10.3.0.128/25    0.0.0.0                  0         32768 i
*> 10.4.0.0/25      0.0.0.0                  0         32768 i
*> 10.4.0.128/25    0.0.0.0                  0         32768 i
*> 10.5.0.0/26      0.0.0.0                  0         32768 i
*> 10.6.0.0/27      0.0.0.0                  0         32768 i
*> 10.7.0.0/28      0.0.0.0                  0         32768 i
*> 10.8.1.0/24      0.0.0.0                  0         32768 i
*> 10.8.2.0/24      0.0.0.0                  0         32768 i

Here’s the access-list:

R1(config)#access-list 103 permit ip 10.0.0.0 0.255.255.255 255.255.255.128 0.0.0.0

R1(config)#router bgp 1
R1(config-router)#distribute-list 103 in

R1#clear ip bgp *

Let me explain the access-list:

  • We want to check the 10.0.0.0 network but we don’t care about the 2nd, 3th or 4th octet. That’s why we use a 0.255.255.255 wildcard.
  • The subnet mask is 255.255.255.128 which equals /25. It has to be an exact match so we use wildcard 0.0.0.0.

Here’s what you will find:

R1#show ip bgp 
BGP table version is 5, local router ID is 192.168.12.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
r> 10.3.0.0/25      192.168.12.2             0             0 2 i
r> 10.3.0.128/25    192.168.12.2             0             0 2 i
r> 10.4.0.0/25      192.168.12.2             0             0 2 i
r> 10.4.0.128/25    192.168.12.2             0             0 2 i

Excellent, these are all 10.x.x.x networks with a /25 prefix length.

Filter all 192.168.7.x networks with any prefix length

This example will be a bit different. This time I want to filter all networks that start with 192.168.7.x but I don’t care about the prefix length. We are talking about the following prefixes:

R2#show ip bgp neighbors 192.168.12.1 advertised-routes | incl 192.168.7
BGP table version is 36, local router ID is 192.168.7.17
*> 192.168.7.0/29   0.0.0.0                  0         32768 i
*> 192.168.7.8/29   0.0.0.0                  0         32768 i
*> 192.168.7.16/29  0.0.0.0                  0         32768 i
*> 192.168.7.24/30  0.0.0.0                  0         32768 i

Here’s the access-list:

R1(config)#access-list 104 permit ip 192.168.7.0 0.0.0.255 255.255.255.0 0.0.0.255

R1(config)#router bgp 1
R1(config-router)#distribute-list 104 in

R1#clear ip bgp *

Let me walk you through the access-list:

  • We are looking for network 192.168.7.0 but we only want to check the first three octets, that’s why we use wildcard 0.0.0.255.
  • We don’t care about the prefix length, it should be at least a /24 since we are looking at the 192.168.7.x range but it doesn’t matter if it’s a /25, /26, etc. This is why we use subnet mask 255.255.255.0 with wildcard 0.0.0.255. It means that we don’t care about the prefix length in the 4th octet.

Here’s the result:

R1#show ip bgp 
BGP table version is 5, local router ID is 192.168.12.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
r> 192.168.7.0/29   192.168.12.2             0             0 2 i
r> 192.168.7.8/29   192.168.12.2             0             0 2 i
r> 192.168.7.16/29  192.168.12.2             0             0 2 i
r> 192.168.7.24/30  192.168.12.2             0             0 2 i

R1 will only have these networks in its BGP table now, everything else will be filtered.

Filter anything with a /24 to /32 prefix length

Time for something different, we don’t care about the network address but we only want to see networks with a prefix length between /24 and /32. Let’s take a look again what R2 is advertising to us:

R2#show ip bgp neighbors 192.168.12.1 advertised-routes
BGP table version is 35, local router ID is 192.168.7.25
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, x best-external, f RT-Filter
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0/24      0.0.0.0                  0         32768 i
*> 10.1.0.0/24      0.0.0.0                  0         32768 i
*> 10.2.0.0/24      0.0.0.0                  0         32768 i
*> 10.3.0.0/25      0.0.0.0                  0         32768 i
*> 10.3.0.128/25    0.0.0.0                  0         32768 i
*> 10.4.0.0/25      0.0.0.0                  0         32768 i
*> 10.4.0.128/25    0.0.0.0                  0         32768 i
*> 10.5.0.0/26      0.0.0.0                  0         32768 i
*> 10.6.0.0/27      0.0.0.0                  0         32768 i
*> 10.7.0.0/28      0.0.0.0                  0         32768 i
*> 10.8.1.0/24      0.0.0.0                  0         32768 i
*> 10.8.2.0/24      0.0.0.0                  0         32768 i
*> 20.0.0.0         0.0.0.0                  0         32768 i
*> 30.0.0.0         0.0.0.0                  0         32768 i
*> 172.16.0.0/24    0.0.0.0                  0         32768 i
   Network          Next Hop            Metric LocPrf Weight Path
*> 172.16.1.0/24    0.0.0.0                  0         32768 i
*> 172.16.2.0/25    0.0.0.0                  0         32768 i
*> 172.16.3.0/25    0.0.0.0                  0         32768 i
*> 172.16.4.0/26    0.0.0.0                  0         32768 i
*> 172.16.5.0/27    0.0.0.0                  0         32768 i
*> 172.16.6.0/28    0.0.0.0                  0         32768 i
*> 172.16.7.0/29    0.0.0.0                  0         32768 i
*> 192.168.0.0      0.0.0.0                  0         32768 i
*> 192.168.1.0      0.0.0.0                  0         32768 i
*> 192.168.2.0/25   0.0.0.0                  0         32768 i
*> 192.168.3.0/25   0.0.0.0                  0         32768 i
*> 192.168.4.0/26   0.0.0.0                  0         32768 i
*> 192.168.5.0/27   0.0.0.0                  0         32768 i
*> 192.168.6.0/28   0.0.0.0                  0         32768 i
*> 192.168.7.0/29   0.0.0.0                  0         32768 i
*> 192.168.7.8/29   0.0.0.0                  0         32768 i
*> 192.168.7.16/29  0.0.0.0                  0         32768 i
*> 192.168.7.24/30  0.0.0.0                  0         32768 i
*> 192.168.12.0     0.0.0.0                  0         32768 i

Total number of prefixes 34 

We have a big list with prefixes, most of them have a prefix length that is larger than /24. We do have 20.0.0.0 /8 and 30.0.0.0 /8 that will be gone when we create this filter. Time to find out:

We're Sorry, Full Content Access is for Members Only...

If you like to keep on reading, Become a Member Now! Here is why:

  • Learn any CCNA, CCNP and CCIE R&S Topic. Explained As Simple As Possible.
  • Try for Just $1. The Best Dollar You’ve Ever Spent on Your Cisco Career!
  • Full Access to our 799 Lessons. More Lessons Added Every Week!
  • Content created by Rene Molenaar (CCIE #41726)

591 Sign Ups in the last 30 days

satisfaction-guaranteed
100% Satisfaction Guaranteed!
You may cancel your monthly membership at any time.
No Questions Asked!

Tags:


Forum Replies

  1. awesome lessons! didnt know you can use extended access-list like this!

    correct me if im wrong, the difference i see here is that, its working like a prefix-list but you can only use “greater than or equal to”?

    on your examples, it only shows like:

    -/24 to /32

    -/25 to /32

    -/26 to /32

    is it possible to have /24 to /30 only? /26 to /29? what will be your subnet and subnet wild card?

     

    thanks!

  2. Hi John,

    Good question, it can’t be done…let’s look at an example:

    00000000 /24
    10000000 /25
    11000000 /26
    11100000 /27
    11110000 /28
    11111000 /29
    11111100 /30
    11111110 /31
    11111111 /32

    Let’s say you want to match /26 up to /29, the problem is that they don’t have a lot of bits in common…only the first two bits are the same:

    11000000 /26
    11100000 /27
    11110000 /28
    11111000 /29

    Now if you would use wildcard 00111111 (63 in decimal) then it matches /26, /27, /28, /29 but also /30, /31 and /32.

    It can’t be done in one statement but of course you can use multiple stat

    ... Continue reading in our forum

  3. thanks Rene for the detailed explanation.

  4. — “We want to match all subnet masks from /27 to /32 so we use a wildcard of 0.0.0.31. This means the first three octets have to match and the last four bits of the 4th octet. This will allow subnet mask 255.255.255.192, 255.255.255.224, 255.255.255.240, 255.255.255.248, 255.255.255.252, 255.255.255.254 and 255.255.255.255.”

    In the above, 255.255.255.192 should be included? Thanks

53 more replies! Ask a question or join the discussion by visiting our Community Forum