Recently, I had to solve a rather simple problem: on a Cisco PE, I had to prevent a certain prefix from being advertised into the L3VPN associated with its VRF.
Well, if it's that simple, why do you need to talk about it? - I hear you asking. Well, it's because in a production network it's never as easy as it sounds.
Exporting from a VRF (in IOS) is done in two ways:
- by tagging all routes in that VRF with a certain RT -
route-target export 1:1
- by using an
export-map
(a route-map) that matches said prefixes and adds RTs to them -set extcommunity rt 1:1
The first method is easy and straightforward to implement, but has the downside of preventing any prefix filtering. All of your prefixes get that RT and there's no way around it.
The second method allows for full flexibility: in the export-map
you can match based on anything a route-map can match and then set various RTs (or multiple at the same time). It has the downside of additional configuration overhead, but it's well worth it in my opinion.
So what was the problem exactly?
I had to stop a prefix from being advertised in a L3VPN that was using the route-target export
command and the export-map
at the same time.
ip vrf SERVICE_A
rd 123:100
export map RM_SERVICE_A_EXPORT
route-target export 123:100
route-target import 123:100
!
route-map RM_SERVICE_A_EXPORT permit 10
match SOMETHING
set extcommunity rt 123:101 additive
route-map RM_SERVICE_A_EXPORT permit 20
...
The setting of RT 123:100 effectively prevented me from filtering that prefix - an export-map
can only be used for RT tagging prefixes, not for filtering.
The obvious solution here is to remove the route-target export
command and integrate it into the export-map
. In my case it was quite tricky and dangerous to do so.
In order to work around it, I had to reserve a new RT 123:1000 to be the "I want to filter this prefix so I'll send it to the place where bad prefixes go". Then I tagged the prefix I didn't want advertised with 123:1000 and nothing else.
route-map RM_SERVICE_A_EXPORT permit 5
match ip address prefix-list PL_NAUGHTY_PREFIX
set extcommunity rt 123:1000
Now, if nobody imports RT 123:1000, that prefix never leaves the PE (in a RR-less environment) and the result is, well, export filtering.
Job done.
But am I happy with it?
Sort of. While it solves the problem now, it is the kind of implementation that will make people scratch their heads some years down the line, even if you properly documented it.
In this case, better options would've arguably been:
- solving the underlying problem that required this prefix filtering in the first place
- replacing the
route-target export
with a carefully designedexport-map
In the end, it's up to you to find a simple solution and to make sure situations like this do not occur in the future.
And, as always, thanks for reading. (You can blame vsauce for this phrase.)