Tuesday, February 3, 2009

How OSPF transmit capability can prevent virtual-link routing loops

I ran into the command "capability transit" some time ago but never really understood how it worked. The explanation in the RFC and the DocCD may seem pretty vague unless you understand what issues cause it to be necessary or desirable. It is on by default so you probably will never have any issues with it, but I find it an interesting feature to look into. And by doing so, you tend to learn more about how OSPF works.

In this lab, I turn it off so we can see what issues arise. We will focus on R2's path to R4's loopback of Each router's interface IP address ends ends with the router number so we can tell easily where traffic is flowing. Here is the topology:

I disabled capability transit on all routers, but I found that in this lab R2 is where the action is, so that might be only place we need to do it:

router ospf 1
no capability transit

Now we begin...

R1 has a virtual link to R3 in order to connect area 234 to area 0. This works fine. R3 has become an ABR and R2 will use R3 to get to R4's loopback:

R2#sho ip route
Routing entry for
Known via "ospf 1", distance 110, metric 66, type inter area
Last update from on Serial1/0, 00:00:07 ago
Routing Descriptor Blocks:
*, from, 00:00:07 ago, via Serial1/0
Route metric is 66, traffic share count is 1

Now let's say R2 needs to add a network to area 2 as follows

R2(config)#int lo 0
R2(config-if)#ip address
R2(config-if)#ip ospf 1 area 2

Since R2 does not have an interface in area 0 we can build a virtual-link to R1:

R2(config)#router ospf 1
R2(config-router)#area 123 virtual-link

R1(config)#router ospf 1
R1(config-router)#area 123 virtual-link
*Mar 1 00:59:19.191: %OSPF-5-ADJCHG: Process 1, Nbr on
OSPF_VL3 from LOADING to FULL, Loading Done

Perfect, right?

Let's take a look at that route towards R4 again:

R2#sho ip route
Routing entry for
Known via "ospf 1", distance 110, metric 194, type inter area
Last update from on Serial1/1, 00:00:04 ago
Routing Descriptor Blocks:
*, from, 00:00:04 ago, via Serial1/1
Route metric is 194, traffic share count is 1

Oh-no...Let's trace:


Type escape sequence to abort.
Tracing the route to

1 72 msec 24 msec 8 msec
2 56 msec 20 msec 84 msec
3 * * *
4 * * *

We have a loop all-right.To fix it, on R2:

R2(config)#router ospf 1
R2(config-router)#capability transit

R2#clear ip ospf process
Reset ALL OSPF processes? [no]: yes

Few moments later:

R2#sho ip route
Routing entry for
Known via "ospf 1", distance 110, metric 66, type inter area
Last update from on Serial1/0, 00:00:18 ago
Routing Descriptor Blocks:
*, from, 00:00:18 ago, via Serial1/0
Route metric is 66, traffic share count is 1

From cisco.com

"The OSPF Area Transit Capability feature provides an OSPF Area Border Router (ABR) with the ability to discover shorter paths through the transit area for forwarding traffic that would normally need to travel through the virtual-link path."

OSPF Area Transit Capability

So in this case, we have allowed R2 to use it direct path to R3 instead of it's own path through the backbone area. We have basically made area 123 a transit area that can carry traffic to destinations not in it's own area. We are flowing from Area 0 (R2 is an ABR now) to Area 123 to Area 234!

Since this command is enabled by default on recent IOS versions, I am not sure you would ever run into this issue in the lab. However, it is still an interesting feature and it is always good to know what's really going on under the hood :-)


  1. Hi Tassos,

    I have sniffed the wire while the virtual link session is established and LS updates are sent.
    Looks like it's just a hack where the area ID in ospf header is changed to the backbone area and the IOS check routine should not be very hard.

    Did you seen other stuff that is changing over the wire ? yeah, wireshark is not very good at dissecting ospf :/

    Best regards

  2. Hello Francois, I am not Tassos :)

    This is my understanding of the issue:

    The problem we face without "transit" capability is that without it, all packets destined for an area that is not its own, must pass through the backbone. With a VL between R1 and R2, R2 must use the VL to get out of area 0. (Because R2 and R3 do not form an adjacency in Area 0) Thus, it installs the route to R4 from R1's summary LSA.

    Two ways around this are to put another VL between R2 and R3 or simple enable Area 123 to be a transit area, which is now the default behavior in recent IOS.

    I am not not sure when this change was made but I was doing some research in GS archives and it looked the past solution was to usually make a VL between R2 and R3. I think this was before transit capability was well-known or widely implemented.

    Please let me know if you have any comments. I am sure this use to be quite the bugger back in the day :)

  3. Hi Deadhead blues,

    Sorry for the confusion! your 2 blogs are dark and you know what it is when you read blogs and labs practice in the same time :/

    Yeah I'm ok with the transit cap workaround as use of a VL between R2 and R3 if we can call this like it. Indeed virtual-link has a good name for describing it :)

    Transit capability is really transparent useful for ospf routing.

    Best regards

  4. Hehe, no problem. I know what you mean :)

    I'm not sure if we would ever see this on the lab, but maybe if they pre-configure an OSPF router with no transit capability, it would be something to look out for! In addition this was a very simple scenario, I imagine they could get extremely more complex.

  5. Hey man, good post !!

    Just a question: Never saw this command to add the interface in the ospf routing process "ip ospf 1 area 2"

    i tried it using a 3620(12.3(21)) and it didn't work, any idea?

    congrats for the blog, really cool!

    cheers from brazil

  6. Hello,

    Thank you for the comment! It was started in 12.3(11)T according to the command ref:


    This has been the way to enable routing protocols in IPv6 so I guess they decided to use it in IPv4 since some people see it as a more logical way to enable it.

  7. Late comment, but I feel its worth putting it. This is a great explanation of the issue we face when transit capability is not enabled. I was wondering what is the use of this command and after reading this blog I know its usage.

    Great work, thanks for the post


Note: Only a member of this blog may post a comment.