As a followup to my previous post on Regular Expression Basics, I wanted to give a few examples on using them on Cisco IOS. Obviously, with a topic as large as regular expressions, there are a limited number of examples I can give. You imagination and of course necessity are the best tools you have for exploring them on your own.
Our first examples use Regular Expressions (regexes) on the CLI. Every engineer should know that you can pipe output from the cli and run it through filters, including exclude, include, section, and begin. These can be very handy when you’re looking for specific information.
router#sh ip int br | ex un Interface IP-Address OK? Method Status Protocol FastEthernet0/0 192.168.8.9 YES NVRAM up up FastEthernet0/0.2 10.1.8.1 YES NVRAM up up
But what if this device had hundreds of ports with assigned IP address, and you were only interested in a specific block of IPs? Thankfully, regex can help! The following will match lines containing IPs within 192.168.8.0/22 — very handy indeed.
router#sh ip int br | i 192\.168\.[8-11]\. FastEthernet1/0/2 192.168.8.9 YES NVRAM up up
Another example could be looking specific configuration entires. In this example, we’re looking for any lines that start with ‘ip ‘ notice the space which we will match using the _ character. (Ensure you don’t include a space after the _ character, or you will return 0 matches!)
router#sh run | i ^ip_ ip cef ip domain name mattke.net ip name-server 4.2.2.2
Notice that no ip addresses were matched in this output since they’re part of the interface config, they’re indented using whitespace. To include them in the matches, I’d normally use ^_*ip_ which states, match beginning of the line, followed by whitespace, or not, followed by ip and a space. But.. IOS doesn’t like that. So you have to use the following…
router#sh run | i ^ *ip_ ip cef ip domain name mattke.net ip name-server 4.2.2.2 ip address 192.168.8.9 255.255.255.0 ip address 10.1.8.1 255.255.255.0
Now that we have the general idea, lets get to the point. Most of you will at some point, run across a config that uses regexes as an as-path access-list. So lets start with some scenarios. You only want to accept routes from this particular peer, if and only if they’ve traveled through ASN 3356 ( Level3 ).
ip as-path access-list 1 permit _3356_
Ok, now, lets specificly deny those routes if they were originated from TWTC (Time Warner AS 4323)..
ip as-path access-list 1 deny ^4323_ ip as-path access-list 1 permit _3356_
You can see how quickly this can get real fun! So, what if we wanted to ensure that our upstream peers ASN (lets say, AT&T… aka as 7018) is the next hop for any routes we were accepting…
ip as-path access-list 1 permit ^7018_[0-9]*$ ip as-path access-list 1 deny .*
One of the methods I use for extreme route balancing in data centers is checking AS Path… Obviously this is done in the path selection algorithm but can be overridden by local preference. So in cases, I’ll set local preference based on AS Path!
ip as-path access-list 1 permit ^([0-9]+)$ ip as-path access-list 2 permit ^([0-9]+)_([0-9]+)$ ! route-map foo permit 10 match as-path 1 set local-preference 150 ! route-map foo permit 20 match as-path 2 set local-preference 140 !
One last trick I’d like to show you is testing your regex’s before applying them in a route-map. Cisco has actually made this quite simple for you to test applying these against your current BGP table. Lets go ahead and test this on the AT&T route server.
route-server>show ip bgp regexp ^([0-9]+)_([0-9]+)$
BGP table version is 32693826, local router ID is 12.0.1.28
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
* 4.0.0.0/9 12.123.37.250 0 7018 3356 i
* 12.123.134.124 0 7018 3356 i
* 12.123.29.249 0 7018 3356 i
* 12.123.142.124 0 7018 3356 i
* 12.123.137.124 0 7018 3356 i
* 12.123.25.245 0 7018 3356 i
* 12.123.17.244 0 7018 3356 i
* 12.123.41.250 0 7018 3356 i
( and so on...... )
I hope this has given you some ideas of your own, or at least cleared up any confusion you have about regular expressions. As always, if you have any suggestions, comments, or questions please feel free to leave a comment below. I always appreciate the feedback. Thanks!


{ 10 comments… read them below or add one }
Hello,
I've trying to setup a filter to local pref a particular AS # on my routers with your examples and have not had any success. After implementing them I did a soft and hard bgp config. Even reloaded the entire session via session shutdown. Any assistance you can give would be much appreciated.
router bgp 1234
no synchronization
bgp default local-preference 0
bgp log-neighbor-changes
bgp bestpath as-path multipath-relax
neighbor 1.1.1.1 remote-as 3356
neighbor 1.1.1.1 soft-reconfiguration inbound
neighbor 1.1.1.1 route-map Provider in
ip as-path access-list 1 permit _1111_
route-map Provider permit 10
set metric 1
!
route-map Provider permit 5
match as-path 1
set local-preference 200
!
Hi,
Is it possible to use regexp to find different octet value of the IP address? Thanks.
Regards,
Angela
It really depends on what exactly you're trying to do, and if there is a way to insert regex in that function. If you can give me more detail about what you're trying to accomplish, I'd be more than happy to try and help you out.
I'm trying to create an EEM script, and part of the goal I'm trying to accomplish is to strip out the value of different octets and store them in different variables for future use. Now, EEM scripting using CLI doesn't have a substring function, so I have to use regex.
So, I have an IP address. I need to use regex to stripe out other octet value by considering them "don't care", just like subnet masks and wildcard masks. The problem is, I don't even have a clue on how to start. So, what would you suggest?
Regards,
Angela
Unless you write a full blown TCL script, I don't think there is going to be a way to do this within EEM. I'm not up to speed on TCL programming as of yet, so unfortunately I'm not sure where to point you for additional information.
Switch# tclsh
Switch(tcl)# set octet {(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])}
Switch(tcl)# set RE “[join [list $octet $octet $octet $octet] {.}]”
Switch(tcl)# regexp $RE [exec "sho ip int bri | i Loop"] all o1 o2 o3 o4
Switch(tcl)# puts $all
10.20.255.16
Switch(tcl)# puts $o1
10
Switch(tcl)# puts $o2
20
Switch(tcl)# puts $o3
255
Switch(tcl)# puts $o4
16
Shamelessly stolen from http://wiki.tcl.tk/989 with some editing
Actually, I think what I want to know is, how can I make the regex to return only an octet rather than the entire IP address.
LOL, and there you go… You ask, and luckily my readers shall help join in!!! Thank you Nathan!
Ugh, the site ate the backslashes in the first regex. Replace each instance of ‘d’ with ‘d’ (hope that works).
(Updated by Tony: I fixed the original post for you… )
Thanks for the information, Nathan, but unfortunately, I needed to accomplish this task in CLI, not Tcl. Still researching on my options though. I might end up using Tcl anyway :)
Regards,
Angela