Tidbit: IOS-XR BGP Allocate Label + Some Inter-AS VPNv4

I ran into a problem while doing an INE mock lab this morning…. it basically kicked my ass, so I figured I’d post about it!

The overall scenario is that there are two BGP domains, AS 1000 and AS 2000. Within each AS, there is some standard IGP routing, and IPv4 BGP — including eBGP between the two domains. There is also some route reflection and some other fun stuff, but that’s mostly irrelevant for the purposes of this post. Below is the INE topology drawing.


After the tasks that setup the basics, the lab rolls into some inter-AS VPN. Essentially, the routers in AS 1000 and 2000 also have loopbacks that are in the same VRF that AS 3000 lives in. The initial VPNv4 task basically is asking to configure the domains so that loopbacks in this VRF are reachable from both of the domains.

So the first thing to consider is that BGP labels will need to be sent between the domains. Thats pretty simple, just send-label in IOS or labeled-unicast in IOS-XR. In addition to that, IOS will require the “mpls bgp forwarding” command on the interfaces between the domains in order to send the labels. For IOS-XR, since the neighbor is on a physical interface, and it’s not a /32 (obviously), a static host route to the neighbor pointing out the connected interface is required. This is because IOS-XR will not install any labels into the forwarding table that have a next hop of something other than a /32.

After this, we need to ensure that each domain has reachability to the ‘PE’ routers loopbacks. This is to ensure that we have a label switched path the whole way through to the end. We also need to make sure that however we learn about the ‘PE’ (which is basically every router since they all have a loopback in the ‘customer’ VRF) loopbacks, and that we get some labels for those. There is an important piece here that basically says that however we learn about that prefix (/32 for the PE), we must also get a label from the same mechanism. IF we were to learn about those /32s via BGP, we would need a BGP label. If we learn the PE loopbacks via IGP, we need to have a label for that via IGP/LDP.

This leads us to the point of the post! In the course of the lab, I was advertising the loopback of each of the PE devices into BGP on each router individually — i.e. on R5 I advertised (loopback0) into BGP locally, and advertised R2s loopback locally, etc. This totally worked — R5  and XR1 both had these prefixes in BGP and while things were configured for normal IPv4 unicast (not labeled) they were advertised across to AS 2000.

Things got a little dicey for me though when I moved the eBGP to labeled unicast. R5 was sending prefixes and labels across to AS 2000, but when shutting down that peering session to test that the inter-AS VPNv4 setup was working across XR1/R3 as well, I was met with crushing defeat!!

Thankfully somebody on the IEOC forums (INEs forum) had this same problem, and Mr. Brian McGahan was there to save the day… here’s what he said:

Only the originator of the BGP route can allocate the label.  This means that whoever you have the network statement or the redistribute statement on you need to do the allocation there.  In your case if you don’t originate the network on XR1 you’d have to go to R5 and then send-label to XR1, and on XR1 send label back to R5.  That’s why in most designs you just have your edge routers originate the BGP networks on behalf of the IGP network, because then you have a single point of control for them.  You can do it either way but it’s good to know that the problem exists in the first place.

So basically IOS-XR, which was configured for ‘allocate-label all’ in order to send BGP labels across to AS 2000, was NOT actually sending any labels!! This was due to the way I was getting the loopback prefixes piped into BGP. Killing the advertisements on the other routers, and then advertising them into BGP on XR1 instead allowed XR1 to send the labels across.

So lesson learned! I’m pretty glad that I ‘messed’ up and was able to come across this because I could totally see Cisco doing something like this on the lab — guess I’ll find out in a few weeks when I sit my first attempt!! 😀

IOS-XR Route-Policy

I said when I started this blog that I would write about some cool IOS-XR stuff that I’d been learning, and I’ve totally 100% failed to do that yet. So here we go!

I’m going to use this post to basically just annotate a cleaned up RPL that I’m using at a current customer. The following RPL is being used at the Internet edge at their peering to ISPs. This customer is actually a colo, so it’s maybe a bit different from you’d see at a typical enterprise.

route-policy RPL_[ISP1]_Inbound
 apply RPL_Deny_Bogons
 apply RPL_All_Provider_Inbound
 apply RPL_[ISP1]_All_Prefixes
 apply RPL_[ISP1]_Provider_Local_Prefixes

Hah! Look easy as that, just name route-policies something that sounds like it would do something cool, then it magically does it!! Okay, more seriously, route-policies can easily call other route-policies. The whole approach is far more programatic than in ‘regular’ IOS. Lets take a look at the first RPL that we are calling ‘RPL_Deny_Bogons’ which does as you would suspect — denies bogons in incoming BGP updates (shouldn’t have any, but just in case!):

route-policy RPL_Deny_Bogons
 if destination in PS_Bogons then

So obviously this is way different from IOS. As I said, it’s basically just programing what you want to do. IF/THEN statements are now your friend! In this policy, IF the destination is in prefix-set (XR prefix list syntax), THEN ‘drop.’ Drop is of course the same as deny. ELSE, as in if prefixes do not match the IF statement, pass, which does as expected also — passes the prefixes on for further examination.

For reference, here is what a prefix-set looks like in XR:

prefix-set PS_Bogons, le 32, le 32, le 32, le 32, le 32, le 32, le 32, le 32, le 32, le 32, le 32, le 32

Moving onto our next called policy ‘RPL_All_Provider_Inbound’; this is a generic type policy to be applied to all provider peering sessions. The intent here is to strip any inbound communities (which I believe does not apply to well-known communities) from prefixes, then apply a community that can be used internally to reference any provider learned prefixes. Finally, the local-preference is set to 90. This last bit is just to ensure that routes learned via colo customers are preferred locally instead of from providers (even though AS-path *should* take care of this — just in case!!).

route-policy RPL_All_Provider_Inbound
 delete community all
 set community COMM_Any_Provider additive
 set local-preference 90

This one doesn’t show us much of the ‘programatic’ style of XR, but does show that it is pretty easy to understand if you are used to route-maps in IOS. Community-lists are also pretty similar to IOS, here’s an example as used above:

community-set COMM_Any_Provider

Wrapping up the policies, these last two assign communities to all routes learned form a particular provider, and another community to routes local to the provider (Provider ASN + 1 hop). The logic for these are just to allow as much granularity in matching prefixes as possible in as simple a possible way in the future.

route-policy RPL_[ISP1]_All_Prefixes
 set community COMM_[ISP1]_All_Prefixes additive
 route-policy RPL_[ISP1]_Provider_Local_Prefixes
 if as-path in AS_[ISP1]_Local then
 set community COMM_[ISP1]_Provider_Local additive

Pretty cut and dry here. Note that the ‘additive’ keyword is just like IOS, use that if you don’t want to overwrite all the communities on a prefix. The second policy above matches an as-path just like you can in a route-map. Heres a basic as-path-set:

as-path-set AS_[ISP1]_Local
 ios-regex '^65535_[0-9]*$’

Above we just match an AS-path of ’65535’ plus one hop (as an example). RPLs also give some cool functionality such as matching a prefix that ‘passes-through’ an ASN. You can also match things inline — instead of calling prefix-sets etc. Hopefully I will get to write about some more of that later!