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.

As a baseline, here are the BGP tables of both R3 and R4.

R3#sh ip bgp
BGP table version is 3, local router ID is 3.3.3.3
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
*> 3.3.3.3/32       0.0.0.0                  0         32768 i
*>i4.4.4.4/32       1.1.1.1                  0    100      0 2 4 i

R3#

R4#sh ip bgp
BGP table version is 11, local router ID is 4.4.4.4
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
*> 3.3.3.3/32       10.2.4.2                               0 2 13 i
*> 4.4.4.4/32       0.0.0.0                  0         32768 i

R4#

Everything here looks as it should.  Nothing fancy at all.

Our first step will be to add our command with only the local-as keyword (abbreviated IOS help shown for information)

R1(config-router)#neigh 10.1.2.2 ?
 local-as                 Specify a local-as number

R1(config-router)#neigh 10.1.2.2 local-as 1
R1(config-router)#
*Feb 27 02:22:11.991: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.2 IPv4 Unicast topology base removed from session  Local AS change
*Feb 27 02:22:11.991: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Down Local AS change
*Feb 27 02:22:12.255: %BGP-3-NOTIFICATION: received from neighbor 10.1.2.2 active 2/2 (peer in wrong AS) 2 bytes 0001
R1(config-router)#
*Feb 27 02:22:12.255: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.2 IPv4 Unicast topology base removed from session  Unknown path error
R1(config-router)#
*Feb 27 02:22:17.375: %BGP-3-NOTIFICATION: received from neighbor 10.1.2.2 passive 2/2 (peer in wrong AS) 2 bytes 0001
R1(config-router)#


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.

R2(config)#router bgp 2
R2(config-router)#neigh 10.1.2.1 remote-as 1
R2(config-router)#
*Feb 27 02:29:25.598: %BGP-5-ADJCHANGE: neighbor 10.1.2.1 Up
R2(config-router)#


That's better!  Ok, so R1 is faking out R2...  What else happened when we did this?  Let's refer back to our baseline and compare how R3 and R4 view the paths to each other's loopbacks now.

R3#sh ip bgp
BGP table version is 5, local router ID is 3.3.3.3
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
*> 3.3.3.3/32       0.0.0.0                  0         32768 i
*>i4.4.4.4/32       1.1.1.1                  0    100      0 1 2 4 i
R3#

R4#
R4#sh ip bgp
BGP table version is 13, local router ID is 4.4.4.4
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
*> 3.3.3.3/32       10.2.4.2                               0 2 1 13 i
*> 4.4.4.4/32       0.0.0.0                  0         32768 i

R4#


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.

R1(config-router)#neighbor 10.1.2.2 local-as 1 ?
  no-prepend  Do not prepend local-as to updates from ebgp peers
 

R1(config-router)#neighbor 10.1.2.2 local-as 1 no-prepend
R1(config-router)#
*Feb 27 02:39:32.582: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.2 IPv4 Unicast topology base removed from session  Local AS change
*Feb 27 02:39:32.582: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Down Local AS change
*Feb 27 02:39:33.370: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Up
R1(config-router)#


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.

R3#sh ip bgp
BGP table version is 11, local router ID is 3.3.3.3
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
*> 3.3.3.3/32       0.0.0.0                  0         32768 i
*>i4.4.4.4/32       1.1.1.1                  0    100      0 2 4 i
R3#


R4#sh ip bgp
BGP table version is 17, local router ID is 4.4.4.4
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
*> 3.3.3.3/32       10.2.4.2                               0 2 1 13 i
*> 4.4.4.4/32       0.0.0.0                  0         32768 i
R4#


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
 

R1(config-router)#neighbor 10.1.2.2 local-as 1 no-prepend replace-as
R1(config-router)#
*Feb 27 02:52:28.534: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.2 IPv4 Unicast topology base removed from session  Local AS change
*Feb 27 02:52:28.534: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Down Local AS change
*Feb 27 02:52:29.562: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Up
R1(config-router)#


Again, IOS help speaks about eBGP updates...  But this time it's referring to the update TO the eBGP peer, and not FROM an eBGP peer, as the no-prepend keyword did.

Let's jump right to our BGP tables on R3 and R4 to see what changed.

R3#sh ip bgp
BGP table version is 13, local router ID is 3.3.3.3
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
*> 3.3.3.3/32       0.0.0.0                  0         32768 i
*>i4.4.4.4/32       1.1.1.1                  0    100      0 2 4 i

R3#

R4#sh ip bgp
BGP table version is 19, local router ID is 4.4.4.4
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
*> 3.3.3.3/32       10.2.4.2                               0 2 1 i
*> 4.4.4.4/32       0.0.0.0                  0         32768 i
R4#


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
 

R1(config-router)#neighbor 10.1.2.2 local-as 1 no-prepend replace-as dual-as
R1(config-router)#
*Feb 27 03:02:31.834: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.2 IPv4 Unicast topology base removed from session  Local AS change
*Feb 27 03:02:31.834: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Down Local AS change
*Feb 27 03:02:32.298: %BGP-3-NOTIFICATION: received from neighbor 10.1.2.2 active 2/2 (peer in wrong AS) 2 bytes 000D
R1(config-router)#
*Feb 27 03:02:32.298: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.2 IPv4 Unicast topology base removed from session  Unknown path error
R1(config-router)#
*Feb 27 03:02:37.750: %BGP-5-ADJCHANGE: neighbor 10.1.2.2 Up
R1(config-router)#


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:

R2(config-router)#do sh run | i neighbor 10.1.2.1
 neighbor 10.1.2.1 remote-as 1
R2(config-router)#neig
R2(config-router)#neighbor 10.1.2.1 remote-as 13
R2(config-router)#
*Feb 27 03:10:14.250: %BGP_SESSION-5-ADJCHANGE: neighbor 10.1.2.1 IPv4 Unicast topology base removed from session  Remote AS changed
*Feb 27 03:10:14.250: %BGP-5-ADJCHANGE: neighbor 10.1.2.1 Down Remote AS changed
*Feb 27 03:10:14.850: %BGP-5-ADJCHANGE: neighbor 10.1.2.1 Up
R2(config-router)#


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#sh ip bgp
BGP table version is 17, local router ID is 3.3.3.3
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
*> 3.3.3.3/32       0.0.0.0                  0         32768 i
*>i4.4.4.4/32       1.1.1.1                  0    100      0 2 4 i

R3#

R4#sh ip bgp
BGP table version is 23, local router ID is 4.4.4.4
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
*> 3.3.3.3/32       10.2.4.2                               0 2 13 i
*> 4.4.4.4/32       0.0.0.0                  0         32768 i

R4#


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!

4 comments:

  1. What a great write up on a very confusing topic for a lot of people.

    ReplyDelete
  2. Great post! TO be honest, I've never used it before. What are some use cases for this command? Or do I just need to know how to use it for the CCIE exam? :)

    Thanks - Jon

    ReplyDelete
  3. Thanks Jon.

    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?

    Beats me really.

    ReplyDelete