Sunday, February 26, 2012

The Ridiculously Long and Complicated BGP Command 'neighbor local-as'

Few commands in IOS are as seemingly long and as confusing to me as what the BGP command 'neighbor local-as' command can be. This command can extend a further 3 more keywords that each change the behavior quite a bit. I've studied this before, and I always think I have it down, then after some time I come back to it and sit there staring at my screen with a stupid look on my face and a little bit of drool coming out the corner of my mouth while I re-learn it again. Here's to hoping that a little blog action finally once and for all gets this one into my head.
To start let's go right to the end of this one and see what this command looks like its full extended glory. Then I'll work through the keywords, one at a time, in order and give examples of how they affect things.

Our command:

neighbor x.x.x.x local-as # no-prepend replace-as dual-as

In case you're keeping count, that's 4 dashes in the full command. That must be a record...

So what does this bad boy do? Well, to illustrate all this nonsense I'm going to use to following basic topology:

I've configured OSPF between R1 and R3 to provide loopback reachability, but that isn't really relevant to this demonstration. I've also set up BGP according to the diagram. AS 13 peers over loopbacks, the other peerings are using directly connected interfaces. Finally, I've added the loopbacks of R3 and R4 into BGP.

Well... That didn't go well for us. Almost instantly the peering between R1 and R2 was torn down due to a "Local AS change", and then we see the router complaining that R2 is sending a notification about R1 being in the wrong AS.

So far this command sucks...

What happened here is that by adding the neighbor local-as command we told R1 to pretend as if it actually is a part of AS 1 instead of AS 13 when establishing a peering with 10.1.2.2. Because of this the configuration on R2 is now incorrect as it's configured to connect to R1 in AS 13. Let's fix R2 and see if everything comes back up.

Well would you look at that! Our imaginary AS has been added to the AS_PATH attributes for both routes as they crossed R1 (note this example doesn't really prove it was added by R1 at this point, but as we go further you'll see this is true). At this point, with this simple topology, this change doesn't actually have an impact on anything. However, in the wild the addition of an AS in the AS_PATH could certainly have repercussions depending on how the routers are configured. Something to keep in the back of your head as you're setting this up.

At this point we have R2 faked out, and we have an additional AS in our AS_PATH. Let's move to the next keyword and see what happens.

The IOS help here mentions that it will not prepend the local-as to updates received from eBGP peers, which is exactly what happens. This is where the first point of confusion usually comes in for me.

See, while we are working with the neighbor command it usually has an effect on that can be seen on the neighbor for which the command is configured for. That's not really the case here. To see the effects of the no-prepend keyword you have to look at either R1 itself, or its downstream neighbors from the neighbor used in this command.

All clear? Yeh... It's not clear here either.

Let's go back to out baseline again and look at R3 and R4's BGP tables. This should clear things up.

Ahh! Now we're getting somewhere. R3 no longer sees our local-as in the AS_PATH for 4.4.4.4/32. What did IOS help say?

Do not prepend local-as to updates from ebgp peers

So do not prepend the local-as to updates sent to other neighbors on routes learned from the neighbor we are configuring the command on. As the 3.3.3.3 route was not learned from 10.1.2.2 R4 still sees the local-as in the AS_PATH.

Got it.

Next up is the replace-as keyword.

R1(config-router)#neighbor 10.1.2.2 local-as 1 no-prepend ? replace-as Replace real AS with local AS in the EBGP updates

R3 is the same as it was before, but now R4 no longer has AS 13 in the AS_PATH. As the IOS help says, the real AS (13) has been "replaced" by the local AS (1).

I find that this keyword is slightly misleading. In my mind the real AS is not being replaced by the local AS because previously both were present. Instead I think that 'remove-as' would be a more appropriate keyword.

But who the hell am I? Certainly not someone who's opinion will actually get this command changed.

Finally, we come to the dual-as keyword.

R1(config-router)#neighbor 10.1.2.2 local-as 1 no-prepend replace-as ? dual-as Accept either real AS or local AS from the ebgp peer

After a little bit of complaining the peering seems to have sorted itself out. What does this get us? Well, again I'll elaborate on what IOS help says:

Accept either real AS or local AS from the ebgp peer

This means that R1 will form a peering with R2 if R2 is configured to have R1 in either the real AS or the local AS. In our example this means R2 can have the neighbor remote-as line for R1 set as either 1 or 13. Let's illustrate:

We can what the current setting was at, then the remote-as is changed. The established peering drops, and then comes right back up again with the new AS number. That's actually pretty cool, and a handy trick if some wording on a certain exam ever made mention of conflicting AS numbers...

To wrap this up let's take one last look at our BGP tables on R3 and R4 to see where we've ended up after all these shenanigans.

R3 is holding steady, but notice that R4 no longer has our local AS in the AS_PATH for 3.3.3.3/32. Instead we're back to seeing AS 13, which jives with how R2 is currently configured. Incidentally, if you compare this last look at the BGP tables to our baseline at the top you'll notice that they're exactly the same. After all this mumbo jumbo we're right back to where we started!

The only use cases I can think of are if you're an MPLS provider and you wanted to either hide you AS, or just not use your own AS, for a BGP peering with your customer. Otherwise... Transition mechanism?