In the last article we began considering common regular expressions used to build BGP AS_PATH access lists. In this article, we will continue with our examples leading to more complex regular expressions. Remember that we are using the article by Brian McGahan as the foundation on which we are building upon.
For this article, our network diagram has added two more routers as shown below:
For this article, we will be removing all the previous AS_PATH filters that we configured in the last article so we have only normal BGP peering sessions between the different ASs.
Example #4: Send only routes learned from a particular AS
In this 4th example (we did three examples in the last article), we will configure R5 to send towards R6 only the routes it learned directly from AS3. If we look at R6’s BGP table, we see the routes it received from R5.
We can determine which path R5 prefers for the different routes by looking at the AS_PATH list. The 1st three routes have AS3 in the AS_PATH so we know R5 prefers R3 to reach those networks even though it can also reach those networks via R4 as shown below:
Note: BGP peers will only advertise their best paths to a particular destination even if they have multiple paths in their BGP table. That is why R6 only has one path to the routes in its BGP table even though R5 has multiple paths for those same destinations.
The only route which R5 is using R4 as its best path is the 22.214.171.124/32 route. By looking at the BGP table of R5, we can see that all the routes learned from R3 have “3” at the leftmost part of the AS_PATH list. Likewise, all the routes learned from R4 have “4” in the leftmost part of the AS_PATH. Thus we can conclude that the AS number of the neighbor from which a route was learned will always be the first (leftmost part) in the AS_PATH attribute. Therefore, the regex to match routes learned directly from AS3 will be “^3_”.
The configuration to be applied on R5 is as follows:
ip as-path access-list 1 permit ^3_ router bgp 5 neighbor 192.168.56.6 filter-list 1 out
When we check R6 now, we will see the only routes that are in its BGP table are those that R5 learned directly from AS3.
Note: The next example should have been one that matches routes that have transited a particular AS but the results will be the same as this example so I have decided to skip it. In case you need it, the regex to match such is “_ASN_”.
Example #5: Receive only routes originated by directly connected ASs
Things begin to get a bit interesting from this point. We want to configure R5 to receive routes originated by its directly connected neighbors. First, I will advertise the loopback interface address of R6 (126.96.36.199/32) into BGP. Currently, R5 is receiving routes from AS1, AS3, AS4 and AS6.
At the end of our configuration we should not see 188.8.131.52/32 and 184.108.40.206/32 in R5’s BGP table. Let’s break it down:
To filter routes originated in AS3, the regex we will use is simply ^3$
To filter routes originated in AS4, the regex we will use is ^4$
To filter routes originated in AS6, the regex we will use is ^6$
Combining all these together, we can form a regex such as “^$” or “^(3|4|6)$”. Notice below that both of these regex give the same output:
But what happens if in future R5 peers with a neighbor in another AS, say AS9? The regex above will not work for this neighbor except if we edit the regex and add “9”. A more flexible approach is to match all the numerals that we can possibly have (i.e. 0 to 9). Therefore our regex becomes ^[0-9]$ and the output is still the same:
Yet again, this regex is “shortsighted.” What happens to neighbors that have AS numbers greater than 9? One way will be to match the entire AS number range (i.e. 0 to 65535) so that the regex becomes ^[0-65535]$. However, AS numbers that used to be made up of 16 bits before are now up to 32 bits. Therefore, the best approach will be to use the “+” regex character that matches one or more instances of a character. As such, the most flexible regex to use is ^[0-9]+$. This will match such AS numbers as 1, 11, 111, 1111 and so on.
Note: The reason we chose + over * is because * will match zero or more instances of a character meaning “locally originated routes” will also be matched.
The configuration on R5 will be as follows:
ip as-path access-list 2 permit ^[0-9]+$ router bgp 5 neighbor 192.168.35.3 filter-list 2 in neighbor 192.168.45.4 filter-list 2 in neighbor 192.168.56.6 filter-list 2 in
When our configuration has taken effect, the BGP table of R5 as shown below:
Example #6: Receive routes originated by directly connected ASs and SOME neighbors of those directly connected ASs
This is the last example we will be considering for this topic. What we want to achieve is for R6 to receives routes originated by its directly connected neighbors (only R5 in our case) and routes originated by R5’s directly connected neighbors except those from AS4 (i.e. only AS3 in our case). First, I will advertise the loopback interface address of R5 into BGP. Also, I will remove all previously configured filter lists on R5 as follows:
router bgp 5 network 220.127.116.11 mask 255.255.255.255 no neighbor 192.168.35.3 filter-list 2 in no neighbor 192.168.45.4 filter-list 2 in no neighbor 192.168.56.6 filter-list 1 out no neighbor 192.168.56.6 filter-list 2 in
The BGP table of R6 has all the routes in it as shown below:
At the end of this configuration, we only want to see the 18.104.22.168/32 and 22.214.171.124/32 routes (and of course, the 126.96.36.199/32 locally originated route). We won’t see 188.8.131.52/32 and 184.108.40.206/32 because those routes were originated three neighbors away; our limit is two. Also, we won’t see the 220.127.116.11/32 route because it was originated by AS4.
From the previous example, we already know how to match routes originated by directly connected neighbors; we just need to extend this to the neighbors of our directly connected neighbors. Let’s break it down again:
Routes originated by our directly connected neighbors are matched by the regex ^[0-9]+$
Therefore, routes originated by the neighbors of our directly connected neighbors will just be a multiple of the one above (i.e. ^[0-9]+_[0-9]+$ (the _ represents a space and I could have excluded it).
To match those two routes, we know the first part “[0-9]+” will always be present. However, the second part “_[0-9]+” may or may not be present; therefore, we can match that part with a “?” meaning zero or one occurrence. The full regex to match routes originated by our neighbors and their own neighbors then becomes ^[0-9]+(_[0-9]+)?$. We can test this out to see:
Hint: If you type “?” normally, the IOS will think you want help. You need to first enter the sequence CTRL+V or ESC+Q before typing the “?”.
This example wants us to accept all routes from neighbors of neighbors except AS4. One way to do this will be to first deny routes originated in AS4 of your directly connected neighbors (i.e. ^[0-9]+_4$). Then you can now permit all other routes originated by neighbors and neighbors of neighbors.
Another way to go is to match it all in one statement like this: ^[0-9]+(_[^4])?$. Using the “^” character inside braces is a way to exclude what is in that brace. Therefore, the regex expression matches routes originated by directly connected neighbors and neighbors of those directly connected neighbor with the exception of AS4. We can confirm this works by testing it out on R6:
Therefore, the configuration on R6 is as follows:
ip as-path access-list 1 permit ^[0-9]+(_[^4])?$ router bgp 6 neighbor 192.168.56.5 filter-list 1 in
After thought: This regex does not work well when you have ASNs greater than 9 – You will have to use a regex like “^[0-9]+(_[^4 ]+)?$” for that. Also, it will match all ASNs that begin with “4”. In summary, the use of caret within square brackets as we have done gives unexpected results and you may be better off using the first option (i.e. a deny statement and then another permit statement). If you have a better solution, please post in the comments section.
To conclude this article, I will advise you to telnet/SSH into publicly available route servers and test out your regular expressions. There is a list of route servers here.
In this article, we have continued with our understanding of regular expressions used in BGP. I hope you now have enough courage to take on more complex regular expressions. I look forward to the next article in the BGP series.
References and further reading
Cisco IOS Terminal Services Configuration Guide, Release 12.2: Regular Expressions: http://www.cisco.com/c/en/us/td/docs/ios/12_2/termserv/configuration/guide/ftersv_c/tcfaapre.html#wp1022889
Understanding BGP regular expressions: http://blog.ine.com/2008/01/06/understanding-bgp-regular-expressions/
Using Regular Expressions in BGP: http://www.cisco.com/c/en/us/support/docs/ip/border-gateway-protocol-bgp/13754-26.html