L2TP protocol extensibility - good or bad?

Fri 14 June 2013
By James Chapman

Did the L2TP protocol designers make a mistake when they allowed for vendor-specific extensions in protocol implementations? Could this lead to L2TP interoperability problems?

L2TP is an extensible protocol

The L2TP protocol was designed to be extensible. New message types could be defined or new parameters added to existing messages such that the additional features would be compatible with existing implementations; if the new message type or parameter is not understood by the peer, it can simply be ignored. The L2TP protocol specification defines a format for all message parameters called Attribute Value Pairs (AVPs). Each L2TP message carries one or more AVPs and each AVP contains a tuple of attribute type, length and data. The namespace for attribute type values allows vendors to add their own AVPs (so-called vendor-specific AVPs) and a flag to indicate whether support at the peer for the vendor-specific AVP is required or not (Mandatory flag). If the peer doesn't support an AVP which is marked as mandatory, the protocol mandates that the tunnel or session is torn down. Thus, the L2TP protocol framework could be extended for use cases which the protocol designers hadn't yet envisaged without breaking older implementations already deployed.

That was the theory.

In practice, some network equipment vendors took advantage of the ability to add vendor-specific AVPs into messages in an attempt to differentiate their L2TP features over the competition. Vendors defined their own AVPs to exchange information with peers implemented by the same vendor in order to implement a cool feature that their competitors would be unable to do. But some defined those AVPs with the Mandatory flag set. Suddenly we have a situation in which one vendor's box won't work properly with another vendor's box unless the peer also implements the vendor-specific AVPs. The dreaded vendor lock-in. Arghhh!!!

Frustrated by Vendor Lock In

The L2TP tunnel and session establishment procedure

Before talking about the specific problems that L2TP's vendor-specific AVPs bring to ProL2TP, it is useful to understand a bit about how tunnels and sessions are established in the L2TP world.

The L2TP tunnel setup procedure is a 3-way message exchange. The L2TP protocol defines standard AVPs to be included in each message, some of which are optional.

L2TPv3 Tunnel Setup Message Sequence

Similarly, the L2TP session setup procedure is another 3-way message exchange for each session established in the tunnel. There is one 3-way message exchange per session. Again, there is a set of AVPs which must be included in each message type.

L2TPv3 Session Setup Message Sequence

The diagrams do not show optional AVPs. An L2TP implementation ignores any optional AVP or vendor AVP that it doesn't support, provided it does not have the Mandatory flag set.

How Cisco use vendor AVPs in L2TPv3

Cisco were instrumental in the design of the L2TP protocol and they introduced L2TPv3 support in IOS 12.1 back in 2005 when the specification was still at draft stage. As a result, their early implementations are not fully compliant with the L2TP protocol specification since they were released before the specification was ratified. Indeed, some of the vendor AVPs used by Cisco are identical to similarly named AVPs in the protocol specification, perhaps because at the time, those AVPs were being proposed by Cisco and were not yet in the protocol standard. However, even Cisco's latest IOS 15.2 versions still require peers to implement some Cisco vendor-specific AVPs...

  1. IOS sends vendor-specific AVPs in tunnel setup messages with the Mandatory bit set. With Mandatory set, L2TP peers must reject the message if they don't support the Cisco vendor AVPs, tearing the tunnel down.

  2. IOS requires SCCRP tunnel setup response messages sent by the peer to include a Cisco draft_version vendor AVP. This is Cisco proprietary.

  3. IOS requires SCCRP messages to include a protocol_version AVP. This AVP is not a vendor AVP: it is defined in the L2TPv3 protocol specification. However, the specification does not list this as a valid AVP for SCCRP so a standard L2TP implementation will usually not send it. If the AVP is not present, IOS treats it as a protocol error and closes the tunnel.

  4. IOS requires ICRP session setup response messages to include a pseudowire_type AVP. Like the protocol_version AVP, this AVP is not one of the AVPs that should be included in ICRP messages so a standard L2TP implementation will not include it.

If the L2TP peer does not implement any of the behaviours outlined above, L2TPv3 connections to Cisco equipment won't work.

How we solved Cisco interoperability with ProL2TP

ProL2TP must be configured to modify its behaviour to implement all of the non-standard L2TPv3 behaviour quirks. Our first cut was to have ProL2TP just insert the extra Cisco vendor AVPs in our messages. Extra AVPs can't hurt as long as they don't have the Mandatory flag set, right? When testing our changes, we hit interoperability issues with other L2TP implementations which couldn't handle the extra AVPs. And even Cisco equipment refused to accept their vendor-specific AVPs unless we set the Mandatory flag in them. So we had no choice but to expose configuration parameters to selectively enable the interoperability features.

A new interop_flags config file parameter was introduced to allow behaviour quirks to be selectively enabled per tunnel. The Cisco vendor AVPs are supported by a ProL2TP plugin: cisco_avp.so. This is enabled by adding -p cisco_avp.so to the startup arguments. On debian systems, this is achieved by editing /etc/default/prol2tp.

With the interop_flags setting and cisco_avp.so plugin, prol2tpd will accept L2TPv3 connections from Cisco routers and send its messages in a form that they will accept.

The sample ProL2TP configuration below will accept L2TPv3 tunnels from Cisco peers.

Configuration file for prol2tp, enabling Cisco workarounds

system {
    listen 192.168.1.15
}

tunnel profile "default" {
    proto_version 3
    auth_mode none
    mtu 1500

    # Cisco uses ip encapsulation only
    encap_type ip

    # enable Cisco L2TP protocol quirks
    interop_flags 3
}

session profile "default" {
    pseudowire_type eth
}

ethernet profile "default" {
    bridge_name "br0"
    mtu 1500
}

Cisco L2TPv3 configuration

The corresponding Cisco configuration fragment to establish a single L2TPv3 Ethernet pseudowire to the ProL2TP server at 192.168.1.15, bridged to the Cisco's FastEthernet0/1 interface, is below.

!
ip cef
!
no ip domain lookup
!
l2tp-class l2tp-noauth
!
pseudowire-class ether-pw-dynamic
 encapsulation l2tpv3
 protocol l2tpv3 l2tp-noauth
 ip local interface fastethernet 0/0
!
interface FastEthernet0/0
 ip address 192.168.1.254 255.255.255.0
 duplex auto
 speed auto
 no cdp enable
!
interface FastEthernet0/1
 no ip address
 no ip directed-broadcast
 no shutdown
 duplex auto
 speed auto
 no cdp enable
 xconnect 192.168.1.15 1 encapsulation l2tpv3 pw-class ether-pw-dynamic
!

Is the L2TP protocol too complicated, then?

One might conclude that allowing network vendors flexibility to define and implement their own data parameter blocks inside L2TP messages is just asking for trouble. The problem described in this article would have been avoided had the L2TP protocol specification not allowed for vendor-specific AVPs. But that is being too simplistic.

Vendor AVPs are a great way for vendors to implement features without having to go through a long specification review process that would otherwise be needed to add new parameters to a standard protocol. If used appropriately, vendors can add value while not breaking interoperability with other vendors. They offer a great way to exchange information during L2TP tunnel and/or session setup which is only pertinent to the vendor. Perhaps the mistake made by the L2TP protocol designers was allowing the Mandatory flag in vendor AVPs to indicate that the vendor AVP had to be supported by the peer. Had Cisco not set the Mandatory bit in their vendor-specific AVPs, there would not be an interoperability problem - we could have simply ignored those AVPs. Their requirement for protocol_version and pseudowire_type AVPs in the SCCRP and ICRP messages is probably just a bug.

But there is another use for vendor-specific AVPs. L2TP's vendor AVPs have also allowed other bodies to define protocol extensions outside the IETF. A good example is a Cable Labs protocol used by the Cable TV industry, in which L2TP is used as a framework to implement a control protocol for a specific environment. If you have Cable TV, your Set Top Box is probably using L2TP vendor-specific AVPs right now. A number of new message types and AVPs were defined by Cable Labs, all using a vendor ID assigned to Cable Labs. Had the L2TP protocol designers not allowed for vendor-specific AVPs, L2TP could not have been used because the Cable Labs protocol extensions would have had to pass through the IETF who designed the L2TP protocol; they would probably have designed an all-new, custom protocol instead. And if we take a closer look at the Cable Labs protocol extensions, they define some AVPs to be Mandatory. In their case, the vendor is Cable Labs, not the equipment vendor, so they can use the Mandatory flag much like the flag is used for AVPs defined by the core L2TP protocol - to identify AVPs which must be handled by the peer in order for the protocol to work.

Now I've come full circle - having suggested that vendor AVPs with the Mandatory flag set should not have been allowed by the L2TP protocol designers, I've shown how that feature allowed L2TP to be extended and used in another environment. Hats off to the L2TP protocol designers - they did a great job! If only some L2TP vendor implementations didn't abuse it.