Wednesday, April 8, 2015

BGP Route Filtering using ACL, Prefix Lists and Route Maps

There are many options for filtering Network Layer Routing Information (NLRI) in BGP. Below is a diagram of a BGP network topology, that I will use to illustrate a few different ways to accomplish the same goal; filtering routes in BGP.

BGP Route Filtering Network Diagram
In the network above, the router R4 and R1 are eBGP neighbors and R4 advertises several networks of variable subnet lengths to R1, which in turn advertises it to its iBGP neighbors R2 and R3. I will be filtering the networks 22.1.0.0 /16, 23.128.0.0 /10 and 23.192.0.0 /10 on R1 using different methods, like applying a distribute list inbound, using a prefix list and also a method using a route map to do some trickery with the PA information as well.

We will do a lot of comparisons to the BGP table and I will therefore post the unfiltered BGP table below.
R1#show ip bgp
BGP table version is 1, local router ID is 140.1.14.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter,
              x best-external, a additional-path, c RIB-compressed,
Origin codes: i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found
     Network          Next Hop            Metric LocPrf Weight Path
 *   21.0.0.0          140.1.14.4               0             0        4.4 ?
 *   22.0.0.0/16     140.1.14.4               0             0        4.4 ?
 *   22.1.0.0/16     140.1.14.4               0             0        4.4 ?
 *   22.2.0.0/15     140.1.14.4               0             0        4.4 ?
 *   23.0.0.0/9       140.1.14.4               0             0        4.4 ?
 *   23.128.0.0/10 140.1.14.4               0             0        4.4 ?
 *   23.192.0.0/10 140.1.14.4               0             0        4.4 ?

Distribute list using Standard ACL
The distribute list is applied to filter inbound traffic using a standard access-list on R1. The configuration on R1 is shown below.
R1#show running-configuration | section ip access-list
ip access-list standard ACL_STD_BGP_DIST_LIST
 deny   22.1.0.0 0.0.255.255
 deny   23.128.0.0 0.63.255.255
 deny   23.192.0.0 0.63.255.255
 permit any
R1#show running-configuration | section router bgp
router bgp 1.23
 bgp asnotation dot
 bgp log-neighbor-changes
 neighbor 10.1.123.2 remote-as 1.23
 neighbor 10.1.123.3 remote-as 1.23
 neighbor 140.1.14.4 remote-as 4.4
 distribute-list ACL_STD_BGP_DIST_LIST in
After the inbound distribute list is applied the neighbor peering will need to be cleared for the changes to take effect.
R1#clear ip bgp 140.1.14.4 in
R1#show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>  21.0.0.0         140.1.14.4               0             0    4.4 ?
 *>  22.0.0.0/16    140.1.14.4               0             0    4.4 ?
 *>  22.2.0.0/15    140.1.14.4               0             0    4.4 ?
 *>  23.0.0.0/9      140.1.14.4               0             0    4.4 ?
The three desired subnets are now removed from the BGP table.

Distribute list using Extended ACL
The distribute list is applied to filter inbound traffic much like the standard access-list - actually, exactly like the standard access-list. The difference here being that the extended ACL will be able to act much like a prefix-list does (prefix list is covered next). This is how to build an extended ACL that will filter the desired networks.
R1#show running-configuration | section ip access-list
ip access-list extended ACL_EXT_BGP_DIST_LIST
 deny   ip host 22.1.0.0 host 255.255.0.0
 deny   ip 23.128.0.0 0.64.0.0 host 255.192.0.0
 permit ip any any
Here we have two deny entries compared to the three deny entries of the standard ACL. This is because we can do some nifty matching logic, when using an extended ACL as compared to the standard ACL.

Here's how it works. I will describe the matching logic using the second deny statement as it is used to match two networks with a single line (it could be used to match countless networks if needed - thus saving processor cycles and easing the configuration and maintaining of the ACL).

The first part of the source address is the address you want to match against, then comes the subnet mask, which is where you can do your wildcard matching. Here we use the source address of 23.128.0.0 with wildcard mask of 0.64.0.0. Then comes the destination address part of the extended ACL. This equates to the subnet mask of the prefix to be matched - here it is a subnet mask of 255.192.0.0 or a /10 ind CIDR notation. In this case the mask has to be exactly a /10.

The same result, in this case, could be accomplished by an entry like this one instead: deny ip 23.0.0.0 0.255.0.0 host 255.192.0.0. This will match any network 23.X.0.0 with a subnet mask of /10 exactly; resulting in the two 23.X.0.0 /10 networks being filtered and the 23.0.0.0 /9 left in the BGP table as shown below.
R1#show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>  21.0.0.0         140.1.14.4               0             0    4.4 ?
 *>  22.0.0.0/16    140.1.14.4               0             0    4.4 ?
 *>  22.2.0.0/15    140.1.14.4               0             0    4.4 ?
 *>  23.0.0.0/9      140.1.14.4               0             0    4.4 ?
I would like to note a small difference in applying the distribute list, that differs from the standard ACL example. When attempting to apply a distribute list under the bgp routing process (like with the standard ACL distribute list) an error will occur.
R1(config-router)#distribute-list ACL_EXT_BGP_DIST_LIST in
% The ACL cannot be created or an ACL with the same name but incompatible type already exists.
The problem here is not immediately apparent from the output of this error. The error is somewhat different (better?) in IOS 12.X, but this is the error received on an IOS 15.X device. The problem is that extended ACL configured is a named ACL, which is not supported by the distribute-list command under the bgp routing process. However, it is supported, when applying the distribute-list for an individual peer like so.
R1(config-router)#neighbor 140.1.14.4 distribute-list ACL_EXT_BGP_DIST_LIST in
And, again, the neighbor peering will have to be cleared for the filtering to take effect.
R1#clear ip bgp 140.1.14.4 in
R1#show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>  21.0.0.0         140.1.14.4               0             0    4.4 ?
 *>  22.0.0.0/16    140.1.14.4               0             0    4.4 ?
 *>  22.2.0.0/15    140.1.14.4               0             0    4.4 ?
 *>  23.0.0.0/9      140.1.14.4               0             0    4.4 ?
There are only 4 networks received from the peer 140.1.14.4. The rest are filtered using an extended ACL distribute-list. Below is a verification of the matches on the ACL.
R1#show ip access-list ACL_EXT_BGP_DIST_LIST
Extended IP access list ACL_EXT_BGP_DIST_LIST
    10 deny ip host 22.1.0.0 host 255.255.0.0 (1 match)
    11 deny ip 23.0.0.0 0.255.0.0 host 255.192.0.0 (2 matches)
    40 permit ip any any (4 matches)
So 3 total matches on deny statements and 4 matches on the permit statement - this should give us a total of 4 prefixes in our BGP table from our peer R4.
R1#show ip bgp nexthops | include (#|140.1.14.4)
 # Paths   Nexthop Address
       4   140.1.14.4
Prefix list
So, the logic with the extended ACL must be able to be done a bit easier, you'd think... so true. The ip prefix-list command will allow you to do, what we did with the extended ACL, only a lot easier and more intuitive. This is how to do it.
R1#show running-config | section ip prefix-list
ip prefix-list PFX_BGP_DIST_LIST seq 5 deny 22.1.0.0/16
ip prefix-list PFX_BGP_DIST_LIST seq 10 deny 23.128.0.0/9 ge 10 le 10
ip prefix-list PFX_BGP_DIST_LIST seq 15 permit 0.0.0.0/0 le 32
The prefix-list seq 5 matches 22.1.0.0/16 exactly, which is denied and therefore filtered, and seq 15 matches any other network; meaning the networks want to allow into our BGP table. Then comes seq 10. This matches 23.128.0.0/9, which is the range 23.128.0.0 to 23.255.255.255 and the mask must be greater-than-or-equal-to (ge) 10 and less-than-or-equal-to (le) 10. So the first part denotes the networks to match and the ge/le will allow for a range of masks to match against - here we only match networks in the range that have a subnet mask of 255.192.0.0.

The prefix list can be applied from the router process for global distribution list or on a peer by peer basis.
R1#show running-config | include (router bgp|distribute-list)
router bgp 1.23
 distribute-list prefix PFX_BGP_DIST_LIST in
Route map
The route map is where the power really comes into play. Below I have an example of a route map configuration, that filters the same subnets as before, but also adds the last AS to the path - twice - before adding it to its own BGP table.

This does not change much in this particular scenario, but imagine a setup with multiple eBGP peerings and you want to make one path considerably more desirable - just add more hops to the AS path and the other routes will most likely start to look a lot better in terms of the BGP best path selection mechanism.
R1#show running-config | section route-map
 <output omitted>
route-map RMAP_BGP_FILTER_IN permit 10
 match ip address prefix-list PFX_BGP_DIST_LIST
 set as-path prepend last-as 2
The prefix list used to match the traffic is the same as in the previous example and denies the 22.1.0.0/16 and the two 23.X.0.0/10 networks, while allowing any other route to be entered into the BGP table of the router R1.

The route map is applied using the command neighbor 140.1.14.4 route-map RMAP_BGP_FILTER_IN in under the BGP router process.

This is the BGP table on R2 before the route map is applied.
R2#show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>i 21.0.0.0          140.1.14.4               0    100      0      4.4 ?
 *>i 22.0.0.0/16     140.1.14.4               0    100      0      4.4 ?
 *>i 22.1.0.0/16     140.1.14.4               0    100      0      4.4 ?
 *>i 22.2.0.0/15     140.1.14.4               0    100      0      4.4 ?
 *>i 23.0.0.0/9       140.1.14.4               0    100      0      4.4 ?
 *>i 23.128.0.0/10 140.1.14.4               0    100      0      4.4 ?
 *>i 23.192.0.0/10 140.1.14.4               0    100      0      4.4 ?
And below is the BGP table on R2 after the route map is applied to R1.
R2#show ip bgp | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
 *>i 21.0.0.0         140.1.14.4               0    100      0      4.4 4.4 4.4 ?
 *>i 22.0.0.0/16    140.1.14.4               0    100      0      4.4 4.4 4.4 ?
 *>i 22.2.0.0/15    140.1.14.4               0    100      0      4.4 4.4 4.4 ?
 *>i 23.0.0.0/9      140.1.14.4               0    100      0      4.4 4.4 4.4 ?
Notice the last part of the output stating the path. The AS 4.4 has been prepended twice making it look like the AS path would be 3 hops. Imagine a second eBGP neighbor having the 2 AS path route to AS 4.4 - then that would be the desired path.

These are just three examples of how to configure route filtering in BGP - there are other ways to do this and I plan on doing some more posts on the matter in the near future.

No comments:

Post a Comment