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.

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


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 657 Lessons. More Lessons Added Every Week!
  • Content created by Rene Molenaar (CCIE #41726)

551 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. Hi, Rene.

    I’m replicating this same scenario in GNS3 and even applying the filters to some specific routes, I lose all routes from the routing table and in the BGP table. Why is this so?

  2. Hi @stlourenco,

    It is difficult to tell without seeing your prefix-list or the configuration. There might be an error in your prefix-list or you refer to the wrong one in your BGP configuration (which will deny everything).

  3. Hi Rene,

    can you explain the reason that the result of “show ip bgp” on R1 is giving the symbol ‘r’ beside the received prefixes from R2?

    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> 
    ... Continue reading in our forum

  4. Hi Walid,

    I just labbed this up again and I’m getting the same RIB failures. If you enable a debug, you can see the reason:

    R1#debug ip routing 
    IP routing debugging is on
    

    This shows up when you clear the routing table or clear the BGP neighbor adjacency:

    RT: rib validate nexthop return code: 3
    RT: rib validate nexthop return code: 3
    RT: rib validate nexthop return code: 3
    

    Return code 3 means the prefix is filtered because of an access-list. This one got me scratching my head for a bit…

    The weird thing is, the access-list seems to be correct. They use the exa

    ... Continue reading in our forum

  5. Hi Dmitriy,

    You are correct, this is a type. A wildcard of 0.0.0.63 means the last six bits match and we ignore the first two bits.

    Thanks! Just fixed this.

    Rene

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