RFC 3931
Layer Two Tunneling Protocol - Version 3 (L2TPv3)
Status of This Memo ๐
Okay bestie, first things first: this document is an Internet standards track protocol spec ๐. It's basically asking the Internet community for discussion and suggestions for improvements ๐ . If you want to know where it stands officially, check the current edition of "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited, so share it with everyone ๐ธ.
Copyright Notice ๐ฆ
This one belongs to The Internet Society, and it's dated 2005 ๐.
Abstract โจ
This doc describes "version 3" of the Layer Two Tunneling Protocol (L2TPv3) ๐ง. L2TPv3 defines the base control protocol and encapsulation for tunneling multiple Layer 2 connections between two IP nodes ๐ฅ. Other documents go into the details for each data link type being emulated, so this one is the foundation ๐ซถ.
Table of Contents ๐
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Changes from RFC 2661. . . . . . . . . . . . . . . . . . 4
1.2. Specification of Requirements. . . . . . . . . . . . . . 4
1.3. Terminology. . . . . . . . . . . . . . . . . . . . . . . 5
2. Topology . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3. Protocol Overview. . . . . . . . . . . . . . . . . . . . . . . 9
3.1. Control Message Types. . . . . . . . . . . . . . . . . . 10
3.2. L2TP Header Formats. . . . . . . . . . . . . . . . . . . 11
3.2.1. L2TP Control Message Header. . . . . . . . . . . 11
3.2.2. L2TP Data Message. . . . . . . . . . . . . . . . 12
3.3. Control Connection Management. . . . . . . . . . . . . . 13
3.3.1. Control Connection Establishment . . . . . . . . 14
3.3.2. Control Connection Teardown. . . . . . . . . . . 14
3.4. Session Management . . . . . . . . . . . . . . . . . . . 15
3.4.1. Session Establishment for an Incoming Call . . . 15
3.4.2. Session Establishment for an Outgoing Call . . . 15
3.4.3. Session Teardown . . . . . . . . . . . . . . . . 16
4. Protocol Operation . . . . . . . . . . . . . . . . . . . . . . 16
4.1. L2TP Over Specific Packet-Switched Networks (PSNs) . . . 16
4.1.1. L2TPv3 over IP . . . . . . . . . . . . . . . . . 17
4.1.2. L2TP over UDP. . . . . . . . . . . . . . . . . . 18
4.1.3. L2TP and IPsec . . . . . . . . . . . . . . . . . 20
4.1.4. IP Fragmentation Issues. . . . . . . . . . . . . 21
4.2. Reliable Delivery of Control Messages. . . . . . . . . . 23
4.3. Control Message Authentication . . . . . . . . . . . . . 25
4.4. Keepalive (Hello). . . . . . . . . . . . . . . . . . . . 26
4.5. Forwarding Session Data Frames . . . . . . . . . . . . . 26
4.6. Default L2-Specific Sublayer . . . . . . . . . . . . . . 27
4.6.1. Sequencing Data Packets. . . . . . . . . . . . . 28
4.7. L2TPv2/v3 Interoperability and Migration . . . . . . . . 28
4.7.1. L2TPv3 over IP . . . . . . . . . . . . . . . . . 29
4.7.2. L2TPv3 over UDP. . . . . . . . . . . . . . . . . 29
4.7.3. Automatic L2TPv2 Fallback. . . . . . . . . . . . 29
5. Control Message Attribute Value Pairs. . . . . . . . . . . . . 30
5.1. AVP Format . . . . . . . . . . . . . . . . . . . . . . . 30
5.2. Mandatory AVPs and Setting the M Bit . . . . . . . . . . 32
5.3. Hiding of AVP Attribute Values . . . . . . . . . . . . . 33
5.4. AVP Summary. . . . . . . . . . . . . . . . . . . . . . . 36
5.4.1. General Control Message AVPs . . . . . . . . . . 36
5.4.2. Result and Error Codes . . . . . . . . . . . . . 40
5.4.3. Control Connection Management AVPs . . . . . . . 43
5.4.4. Session Management AVPs. . . . . . . . . . . . . 48
5.4.5. Circuit Status AVPs. . . . . . . . . . . . . . . 57
6. Control Connection Protocol Specification. . . . . . . . . . . 59
6.1. Start-Control-Connection-Request (SCCRQ) . . . . . . . . 60
6.2. Start-Control-Connection-Reply (SCCRP) . . . . . . . . . 60
6.3. Start-Control-Connection-Connected (SCCCN) . . . . . . . 61
6.4. Stop-Control-Connection-Notification (StopCCN) . . . . . 61
6.5. Hello (HELLO). . . . . . . . . . . . . . . . . . . . . . 61
6.6. Incoming-Call-Request (ICRQ) . . . . . . . . . . . . . . 62
6.7. Incoming-Call-Reply (ICRP) . . . . . . . . . . . . . . . 63
6.8. Incoming-Call-Connected (ICCN) . . . . . . . . . . . . . 63
6.9. Outgoing-Call-Request (OCRQ) . . . . . . . . . . . . . . 64
6.10. Outgoing-Call-Reply (OCRP) . . . . . . . . . . . . . . . 65
6.11. Outgoing-Call-Connected (OCCN) . . . . . . . . . . . . . 65
6.12. Call-Disconnect-Notify (CDN) . . . . . . . . . . . . . . 66
6.13. WAN-Error-Notify (WEN) . . . . . . . . . . . . . . . . . 66
6.14. Set-Link-Info (SLI). . . . . . . . . . . . . . . . . . . 67
6.15. Explicit-Acknowledgement (ACK) . . . . . . . . . . . . . 67
7. Control Connection State Machines. . . . . . . . . . . . . . . 68
7.1. Malformed AVPs and Control Messages. . . . . . . . . . . 68
7.2. Control Connection States. . . . . . . . . . . . . . . . 69
7.3. Incoming Calls . . . . . . . . . . . . . . . . . . . . . 71
7.3.1. ICRQ Sender States . . . . . . . . . . . . . . . 72
7.3.2. ICRQ Recipient States. . . . . . . . . . . . . . 73
7.4. Outgoing Calls . . . . . . . . . . . . . . . . . . . . . 74
7.4.1. OCRQ Sender States . . . . . . . . . . . . . . . 75
7.4.2. OCRQ Recipient (LAC) States. . . . . . . . . . . 76
7.5. Termination of a Control Connection. . . . . . . . . . . 77
8. Security Considerations. . . . . . . . . . . . . . . . . . . . 78
8.1. Control Connection Endpoint and Message Security . . . . 78
8.2. Data Packet Spoofing . . . . . . . . . . . . . . . . . . 78
9. Internationalization Considerations. . . . . . . . . . . . . . 79
10. IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 80
10.1. Control Message Attribute Value Pairs (AVPs) . . . . . . 80
10.2. Message Type AVP Values. . . . . . . . . . . . . . . . . 81
10.3. Result Code AVP Values . . . . . . . . . . . . . . . . . 81
10.4. AVP Header Bits. . . . . . . . . . . . . . . . . . . . . 82
10.5. L2TP Control Message Header Bits . . . . . . . . . . . . 82
10.6. Pseudowire Types . . . . . . . . . . . . . . . . . . . . 83
10.7. Circuit Status Bits. . . . . . . . . . . . . . . . . . . 83
10.8. Default L2-Specific Sublayer bits. . . . . . . . . . . . 84
10.9. L2-Specific Sublayer Type. . . . . . . . . . . . . . . . 84
10.10 Data Sequencing Level. . . . . . . . . . . . . . . . . . 84
11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 85
11.1. Normative References . . . . . . . . . . . . . . . . . . 85
11.2. Informative References . . . . . . . . . . . . . . . . . 85
12. Acknowledgments. . . . . . . . . . . . . . . . . . . . . . . . 87
Appendix A: Control Slow Start and Congestion Avoidance. . . . . . 89
Appendix B: Control Message Examples . . . . . . . . . . . . . . . 90
Appendix C: Processing Sequence Numbers. . . . . . . . . . . . . . 91
Editors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 93
Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 94
Title Block ๐
Network Working Group ๐ is where this one lives, and it's RFC 3931, titled Layer Two Tunneling Protocol - Version 3 (L2TPv3) ๐.
The editors are J. Lau (Ed.), M. Townsley (Ed.), and I. Goyret (Ed.) ๐ซถ. Lau and Townsley are from Cisco Systems, and Goyret is from Lucent Technologies ๐.
It's a Standards Track doc, dated March 2005 ๐ . The title block doesn't list anything it obsoletes or updates, so there's nothing to add there ๐.
1. Introduction โจ
Okay so the Layer Two Tunneling Protocol (L2TP) gives you a dynamic way to tunnel Layer 2 (L2) "circuits" across a packet-oriented data network, like over IP ๐ฆ. L2TP, as first defined in RFC 2661, is a standard method for tunneling Point-to-Point Protocol (PPP) [RFC1661] sessions ๐. Since then it's been adopted for tunneling a bunch of other L2 protocols, which is iconic ๐. To get more modularity, this document describes the base L2TP protocol on its own, separate from whatever L2 payload is being tunneled ๐ .
The base L2TP protocol in this document has two parts ๐ง. First, there's the control protocol for dynamic creation, maintenance, and teardown of L2TP sessions ๐ฅ. Second, there's the L2TP data encapsulation, which multiplexes and demultiplexes L2 data streams between two L2TP nodes across an IP network ๐ธ. Additional documents are expected for each L2 data link emulation type (a.k.a. pseudowire-type) that L2TP supports, like PPP, Ethernet, Frame Relay, etc. โญ Those docs will hold any pseudowire-type specific details that are outside the scope of this base spec ๐.
When you need to tell L2TPv2 and L2TPv3 apart, L2TP as defined in RFC 2661 is called "L2TPv2", which matches the value in the Version field of an L2TP header ๐. (Layer 2 Forwarding, L2F, [RFC2341] was defined as "version 1" ๐.) Sometimes L2TP as defined in this document is called "L2TPv3" ๐ฆ. Otherwise, the acronym "L2TP" refers to L2TPv3 or to L2TP in general ๐.
1.1. Changes from RFC 2661
Lots of the protocol constructs in this document are carried over from RFC 2661 ๐. The changes include clarifications based on years of interoperability and deployment experience, plus modifications that either improve protocol operation or give a clearer separation from PPP ๐ฅ. The whole goal is a healthy balance between code reuse, interoperability experience, and a directed evolution of L2TP as it gets applied to new tasks ๐ โจ.
Here are the notable differences between L2TPv2 and L2TPv3 ๐:
- Separation of all PPP-related AVPs, references, etc., including a portion of the L2TP data header that was specific to the needs of PPP. The PPP-specific constructs are described in a companion document ๐.
- Transition from a 16-bit Session ID and Tunnel ID to a 32-bit Session ID and Control Connection ID, respectively ๐ข.
- Extension of the Tunnel Authentication mechanism to cover the entire control message rather than just a portion of certain messages ๐.
The details of these changes, plus a recommendation for transitioning to L2TPv3, are covered in Section 4.7 ๐ซถ.
1.2. Specification of Requirements
Here's the key word part, so pay attention bestie ๐. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐ ๐ฅ.
1.3. Terminology โจ
okay so before we dive in, we need the vocab down bestie ๐ these terms show up everywhere in L2TP, so let's get them straight ๐
Attribute Value Pair (AVP) ๐ The variable-length concatenation of a unique Attribute (represented by an integer), a length field, and a Value containing the actual value identified by the attribute. Zero or more AVPs make up the body of control messages, which are used in the establishment, maintenance, and teardown of control connections. This basic construct is sometimes referred to as a Type-Length-Value (TLV) in some specifications. (See also: Control Connection, Control Message.)
Call (Circuit Up) ๐ The action of transitioning a circuit on an L2TP Access Concentrator (LAC) to an "up" or "active" state. A call may be dynamically established through signaling properties (e.g., an incoming or outgoing call through the Public Switched Telephone Network (PSTN)) or statically configured (e.g., provisioning a Virtual Circuit on an interface). A call is defined by its properties (e.g., type of call, called number, etc.) and its data traffic. (See also: Circuit, Session, Incoming Call, Outgoing Call, Outgoing Call Request.)
Circuit ๐ A general term identifying any one of a wide range of L2 connections. A circuit may be virtual in nature (e.g., an ATM PVC, an IEEE 802 VLAN, or an L2TP session), or it may have direct correlation to a physical layer (e.g., an RS-232 serial line). Circuits may be statically configured with a relatively long-lived uptime, or dynamically established with signaling to govern the establishment, maintenance, and teardown of the circuit. For the purposes of this document, a statically configured circuit is considered to be essentially the same as a very simple, long-lived, dynamic circuit. (See also: Call, Remote System.)
Client ๐ซถ (See Remote System.)
Control Connection ๐ก๏ธ An L2TP control connection is a reliable control channel that is used to establish, maintain, and release individual L2TP sessions as well as the control connection itself. (See also: Control Message, Data Channel.)
Control Message ๐จ An L2TP message used by the control connection. (See also: Control Connection.)
Data Message ๐ฆ Message used by the data channel. (a.k.a. Data Packet, See also: Data Channel.)
Data Channel ๐ The channel for L2TP-encapsulated data traffic that passes between two LCCEs over a Packet-Switched Network (i.e., IP). (See also: Control Connection, Data Message.)
Incoming Call ๐ฒ The action of receiving a call (circuit up event) on an LAC. The call may have been placed by a remote system (e.g., a phone call over a PSTN), or it may have been triggered by a local event (e.g., interesting traffic routed to a virtual interface). An incoming call that needs to be tunneled (as determined by the LAC) results in the generation of an L2TP ICRQ message. (See also: Call, Outgoing Call, Outgoing Call Request.)
L2TP Access Concentrator (LAC) ๐ช If an L2TP Control Connection Endpoint (LCCE) is being used to cross-connect an L2TP session directly to a data link, we refer to it as an L2TP Access Concentrator (LAC). An LCCE may act as both an L2TP Network Server (LNS) for some sessions and an LAC for others, so these terms must only be used within the context of a given set of sessions unless the LCCE is in fact single purpose for a given topology. (See also: LCCE, LNS.)
L2TP Control Connection Endpoint (LCCE) ๐ An L2TP node that exists at either end of an L2TP control connection. May also be referred to as an LAC or LNS, depending on whether tunneled frames are processed at the data link (LAC) or network layer (LNS). (See also: LAC, LNS.)
L2TP Network Server (LNS) ๐ฅ๏ธ If a given L2TP session is terminated at the L2TP node and the encapsulated network layer (L3) packet processed on a virtual interface, we refer to this L2TP node as an L2TP Network Server (LNS). A given LCCE may act as both an LNS for some sessions and an LAC for others, so these terms must only be used within the context of a given set of sessions unless the LCCE is in fact single purpose for a given topology. (See also: LCCE, LAC.)
Outgoing Call ๐ค The action of placing a call by an LAC, typically in response to policy directed by the peer in an Outgoing Call Request. (See also: Call, Incoming Call, Outgoing Call Request.)
Outgoing Call Request ๐ A request sent to an LAC to place an outgoing call. The request contains specific information not known a priori by the LAC (e.g., a number to dial). (See also: Call, Incoming Call, Outgoing Call.)
Packet-Switched Network (PSN) ๐ธ๏ธ A network that uses packet switching technology for data delivery. For L2TPv3, this layer is principally IP. Other examples include MPLS, Frame Relay, and ATM.
Peer ๐ฏ When used in context with L2TP, Peer refers to the far end of an L2TP control connection (i.e., the remote LCCE). An LAC's peer may be either an LNS or another LAC. Similarly, an LNS's peer may be either an LAC or another LNS. (See also: LAC, LCCE, LNS.)
Pseudowire (PW) ๐ฆ An emulated circuit as it traverses a PSN. There is one Pseudowire per L2TP Session. (See also: Packet-Switched Network, Session.)
Pseudowire Type ๐จ The payload type being carried within an L2TP session. Examples include PPP, Ethernet, and Frame Relay. (See also: Session.)
Remote System ๐ป An end system or router connected by a circuit to an LAC.
Session โจ An L2TP session is the entity that is created between two LCCEs in order to exchange parameters for and maintain an emulated L2 connection. Multiple sessions may be associated with a single Control Connection.
Zero-Length Body (ZLB) Message ๐ A control message with only an L2TP header. ZLB messages are used only to acknowledge messages on the L2TP reliable control connection. (See also: Control Message.)
2. Topology ๐บ๏ธ
okay now the fun part, the map ๐ง L2TP operates between two L2TP Control Connection Endpoints (LCCEs), tunneling traffic across a packet network. There are three predominant tunneling models in which L2TP operates: LAC-LNS (or vice versa), LAC-LAC, and LNS-LNS. These models are diagrammed below. (Dotted lines designate network connections. Solid lines designate circuit connections.)
Figure 2.0: L2TP Reference Models ๐ธ
(a) LAC-LNS Reference Model: so on one side, the LAC receives traffic from an L2 circuit, which it forwards via L2TP across an IP or other packet-based network. on the other side, an LNS logically terminates the L2 circuit locally and routes network traffic to the home network. the action of session establishment is driven by the LAC (as an incoming call) or the LNS (as an outgoing call).
+-----+ L2 +-----+ +-----+
| |------| LAC |.........[ IP ].........| LNS |...[home network]
+-----+ +-----+ +-----+
remote
system
|<-- emulated service -->|
|<----------- L2 service ------------>|
(b) LAC-LAC Reference Model: in this model, both LCCEs are LACs. Each LAC forwards circuit traffic from the remote system to the peer LAC using L2TP, and vice versa. in its simplest form, an LAC acts as a simple cross-connect between a circuit to a remote system and an L2TP session. this model typically involves symmetric establishment; that is, either side of the connection may initiate a session at any time (or simultaneously, in which a tie breaking mechanism is utilized). ๐
+-----+ L2 +-----+ +-----+ L2 +-----+
| |------| LAC |........[ IP ]........| LAC |------| |
+-----+ +-----+ +-----+ +-----+
remote remote
system system
|<- emulated service ->|
|<----------------- L2 service ----------------->|
(c) LNS-LNS Reference Model: this model has two LNSs as the LCCEs. A user-level, traffic-generated, or signaled event typically drives session establishment from one side of the tunnel. for example, a tunnel generated from a PC by a user, or automatically by customer premises equipment. ๐
+-----+ +-----+
[home network]...| LNS |........[ IP ]........| LNS |...[home network]
+-----+ +-----+
|<- emulated service ->|
|<---- L2 service ---->|
Note: In L2TPv2, user-driven tunneling of this type is often referred to as "voluntary tunneling" [RFC2809]. Further, an LNS acting as part of a software package on a host is sometimes referred to as an "LAC Client" [RFC2661]. ๐
3. Protocol Overview โจ
okay so L2TP has two kinds of messages: control messages and data messages (sometimes called "control packets" and "data packets" ๐). Control messages handle the setup, maintenance, and clearing of control connections and sessions. They use a reliable control channel inside L2TP to guarantee delivery (see Section 4.2 for the deets ๐ซถ). Data messages are the ones that encapsulate the L2 traffic riding on the L2TP session, and unlike control messages, they are not retransmitted when packet loss happens. no do-overs for data, periodt ๐
The L2TPv3 control message format borrows a lot from L2TPv2 ๐. These control messages work hand in hand with the protocol state machines that govern how L2TP sessions get set up, maintained, and torn down. The data message format for tunneling data packets can be used with or without the L2TP control channel. That could be through manual configuration, or through other signaling methods that pre-configure or distribute L2TP session info. Using the L2TP data message format with those other signaling methods is outside the scope of this document ๐
Figure 3.0: L2TPv3 Structure
+-------------------+ +-----------------------+
| Tunneled Frame | | L2TP Control Message |
+-------------------+ +-----------------------+
| L2TP Data Header | | L2TP Control Header |
+-------------------+ +-----------------------+
| L2TP Data Channel | | L2TP Control Channel |
| (unreliable) | | (reliable) |
+-------------------+----+-----------------------+
| Packet-Switched Network (IP, FR, MPLS, etc.) |
+------------------------------------------------+
Figure 3.0 shows how control messages and data messages sit over the L2TP control and data channels, respectively. Data messages go over an unreliable data channel, get wrapped in an L2TP header, and are sent across a Packet-Switched Network (PSN) like IP, UDP, Frame Relay, ATM, MPLS, etc. Control messages go over a reliable L2TP control channel, which runs over that same PSN ๐ฆ
Setting up a tunneled session with L2TP is a two-step process: (1) establish the control connection, then (2) establish a session, which gets triggered by either an incoming call or an outgoing call ๐. An L2TP session MUST be established before L2TP can begin to forward session frames. One control connection can have multiple sessions bound to it, and the same two LCCEs can have multiple control connections between them. so many options, bestie ๐
3.1. Control Message Types
The Message Type AVP (see Section 5.4.1) is what defines the specific type of control message being sent ๐ท๏ธ
This document defines the following control message types (see Sections 6.1 through 6.15 for details on the construction and use of each message) ๐
Control Connection Management
0 (reserved)
1 (SCCRQ) Start-Control-Connection-Request
2 (SCCRP) Start-Control-Connection-Reply
3 (SCCCN) Start-Control-Connection-Connected
4 (StopCCN) Stop-Control-Connection-Notification
5 (reserved)
6 (HELLO) Hello
20 (ACK) Explicit Acknowledgement
Call Management
7 (OCRQ) Outgoing-Call-Request
8 (OCRP) Outgoing-Call-Reply
9 (OCCN) Outgoing-Call-Connected
10 (ICRQ) Incoming-Call-Request
11 (ICRP) Incoming-Call-Reply
12 (ICCN) Incoming-Call-Connected
13 (reserved)
14 (CDN) Call-Disconnect-Notify
Error Reporting
15 (WEN) WAN-Error-Notify
Link Status Change Reporting
16 (SLI) Set-Link-Info
3.2. L2TP Header Formats
This section defines the header formats for L2TP control messages and L2TP data messages ๐ง All values get placed into their respective fields and sent in network order (high-order octets first), so the big end goes first, always ๐ธ
3.2.1. L2TP Control Message Header
The L2TP control message header is the info that keeps reliable transport going for messages that handle the establishment, maintenance, and teardown of L2TP sessions โจ By default, control messages go over the underlying media in-band with L2TP data messages.
The L2TP control message header is formatted like this:
Figure 3.2.1: L2TP Control Message Header
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|L|x|x|S|x|x|x|x|x|x|x| Ver | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Control Connection ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Ns | Nr |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The T bit MUST be set to 1, which tells you this is a control message ๐โโ๏ธ
The L and S bits MUST be set to 1, which means the Length field and sequence numbers are present ๐ข
The x bits are reserved for future extensions. All reserved bits MUST be set to 0 on outgoing messages and ignored on incoming messages ๐คซ
The Ver field tells you which version of the L2TP control message header is described in this document. On sending, this field MUST be set to 3 for all messages. The exception is when you're operating in an environment that also includes L2TPv2 [RFC2661] and/or L2F [RFC2341], see Section 4.1 for the details on that ๐
The Length field is the total length of the message in octets. It's always calculated from the start of the control message header itself, beginning with the T bit ๐
The Control Connection ID field holds the identifier for the control connection ๐ L2TP control connections are named by identifiers that only have local significance. So the same control connection gets its own unique Control Connection IDs from each LCCE, out of each endpoint's own Control Connection ID number space. Because of that, the Control Connection ID in each message is the intended recipient's, not the sender's ๐ฌ Non-zero Control Connection IDs get selected and exchanged as Assigned Control Connection ID AVPs when the control connection is created.
Ns is the sequence number for this control message. It starts at zero and goes up by one (modulo 2**16) for each message sent. See Section 4.2 for more on using this field ๐
Nr is the sequence number expected in the next control message to be received. So Nr gets set to the Ns of the last in-order message received, plus one (modulo 2**16). See Section 4.2 for more on using this field too ๐
3.2.2. L2TP Data Message
In general, an L2TP data message is made up of (1) a Session Header, (2) an optional L2-Specific Sublayer, and (3) the Tunnel Payload, as shown below ๐
Figure 3.2.2: L2TP Data Message Header
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| L2TP Session Header |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| L2-Specific Sublayer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Tunnel Payload ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The L2TP Session Header is specific to the encapsulating PSN that the L2TP traffic gets delivered over ๐ The Session Header MUST provide (1) a way to tell apart traffic across multiple L2TP data sessions, and (2) a way to tell data messages apart from control messages. That's the core job of the header, basically ๐ต๏ธโโ๏ธ
Each type of encapsulating PSN MUST define its own session header, clearly spelling out the header's format and the parameters needed to set up the session. Section 4.1 defines two session headers, one for transport over UDP and one for transport over IP ๐งฉ
The L2-Specific Sublayer sits between the L2TP session header and the start of the tunneled frame. It holds control fields that help with tunneling each frame, like sequence numbers or flags ๐ฉ The Default L2-Specific Sublayer for L2TPv3 is defined in Section 4.6.
After the Data Message Header comes the Tunnel Payload, including any necessary L2 framing as defined in the payload-specific companion documents ๐ซง
3.3. Control Connection Management
The L2TP control connection handles the dynamic establishment, teardown, and maintenance of L2TP sessions, and of the control connection itself ๐ The reliable delivery of control messages is described in Section 4.2.
This section walks through the typical control connection establishment and teardown exchanges. Important note: in the diagrams that follow, the reliable control message delivery mechanism exists independently of the L2TP state machine. For instance, Explicit Acknowledgement (ACK) messages may be sent after any of the control messages shown in the exchanges below, if an acknowledgment isn't piggybacked on a later control message ๐ค
LCCEs get identified during control connection establishment by the Host Name AVP, the Router ID AVP, or a combination of the two (see Section 5.4.3). Knowing who your peer LCCE is matters a LOT, because it's central to picking the right configuration parameters (like Hello interval, window size, etc.) for a control connection ๐ฏ It also decides how to set up the associated sessions inside that control connection, how to look up passwords for control connection authentication, how control connection level tie breaking works, and more ๐
3.3.1. Control Connection Establishment
Establishing the control connection involves an exchange of AVPs that identifies the peer and its capabilities ๐ชช
A three-message exchange is used to establish the control connection. Here's a typical message exchange:
LCCE A LCCE B
------ ------
SCCRQ ->
<- SCCRP
SCCCN ->
3.3.2. Control Connection Teardown
Control connection teardown can be initiated by either LCCE, and it's accomplished by sending a single StopCCN control message ๐ As part of the reliable control message delivery mechanism, the recipient of a StopCCN MUST send an ACK message to acknowledge receipt of the message. It also has to maintain enough control connection state to properly accept StopCCN retransmissions over at least a full retransmission cycle, just in case the ACK message gets lost ๐ The recommended time for a full retransmission cycle is at least 31 seconds (see Section 4.2). Here's an example of a typical control message exchange:
LCCE A LCCE B
------ ------
StopCCN ->
(Clean up)
(Wait)
(Clean up)
An implementation may shut down an entire control connection, and all sessions associated with it, by sending the StopCCN. So it's not necessary to clear each session individually when tearing down the whole control connection, which is a big time saver ๐งน
3.4. Session Management
After successful control connection establishment, individual sessions can be created ๐ Each session corresponds to a single data stream between the two LCCEs. This section describes the typical call establishment and teardown exchanges ๐๐
3.4.1. Session Establishment for an Incoming Call โจ
Okay bestie, session setup only takes three messages ๐ Here's the typical vibe:
LCCE A LCCE B
------ ------
(Call
Detected)
ICRQ ->
<- ICRP
(Call
Accepted)
ICCN ->
3.4.2. Session Establishment for an Outgoing Call ๐ฆ
Same energy, just flipped. It's another three-message exchange to get the session set up, and here's how it usually goes:
LCCE A LCCE B
------ ------
<- OCRQ
OCRP ->
(Perform
Call
Operation)
OCCN ->
(Call Operation
Completed
Successfully)
3.4.3. Session Teardown ๐ซง
Either the LAC or the LNS can start a session teardown, and it's done by sending a CDN control message. Once the last session is cleared, the control connection MAY be torn down too (and it typically is). Here's an example of a typical control message exchange:
LCCE A LCCE B
------ ------
CDN ->
(Clean up)
(Clean up)
4. Protocol Operation ๐ธ
4.1. L2TP Over Specific Packet-Switched Networks (PSNs) ๐
L2TP can run over a bunch of different PSNs. There are two modes described for running over IP: L2TP directly over IP (see Section 4.1.1) and L2TP over UDP (see Section 4.1.2). L2TPv3 implementations MUST support L2TP over IP, and SHOULD support L2TP over UDP for better NAT and firewall traversal, and for easier migration from L2TPv2. ๐ซถ
L2TP over other PSNs may be defined, but the specifics are outside the scope of this document. Examples of L2TPv2 over other PSNs include [RFC3070] and [RFC3355].
The following field definitions apply to all L2TP Session Header encapsulations. ๐ง
Session ID
A 32-bit field containing a non-zero identifier for a session. L2TP sessions are named by identifiers that have local significance only. That means the same logical session will be given different Session IDs by each end of the control connection for the life of the session. When the L2TP control connection is used for session establishment, Session IDs are selected and exchanged as Local Session ID AVPs during the creation of a session. The Session ID alone provides the necessary context for all further packet processing, including the presence, size, and value of the Cookie, the type of L2-Specific Sublayer, and the type of payload being tunneled. โจ
Cookie
The optional Cookie field contains a variable-length value (maximum 64 bits) used to check the association of a received data message with the session identified by the Session ID. The Cookie MUST be set to the configured or signaled random value for this session. It gives an extra layer of guarantee that a data message was directed to the proper session by the Session ID. A well-chosen Cookie may prevent inadvertent misdirection of stray packets with recently reused Session IDs, Session IDs subject to packet corruption, and so on. The Cookie may also protect against some specific malicious packet insertion attacks, as described in Section 8.2. ๐ฅ
When the L2TP control connection is used for session establishment, random Cookie values are selected and exchanged as Assigned Cookie AVPs during session creation. ๐
4.1.1. L2TPv3 over IP ๐
L2TPv3 over IP (both versions) uses the IANA-assigned IP protocol ID 115.
4.1.1.1. L2TPv3 Session Header Over IP ๐
Unlike L2TP over UDP, the L2TPv3 session header over IP is free of any restrictions imposed by coexistence with L2TPv2 and L2F. Because of that, the header format has been designed to optimize packet processing. The following session header format is used when operating L2TPv3 over IP:
Figure 4.1.1.1: L2TPv3 Session Header Over IP
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Session ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cookie (optional, maximum 64 bits)...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Session ID and Cookie fields are as defined in Section 4.1. The Session ID of zero is reserved for L2TP control messages (see Section 4.1.1.2). ๐ง
4.1.1.2. L2TP Control and Data Traffic over IP ๐
Unlike L2TP over UDP, which uses the T bit to tell L2TP control and data packets apart, L2TP over IP uses the reserved Session ID of zero (0) when sending control messages. The idea is that checking for a zero Session ID is more efficient, both in header size for data packets and in processing speed for telling control and data messages apart, than checking a single bit. ๐ง
The entire control message header over IP, including the zero session ID, looks like this:
Figure 4.1.1.2: L2TPv3 Control Message Header Over IP
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (32 bits of zeros) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|L|x|x|S|x|x|x|x|x|x|x| Ver | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Control Connection ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Ns | Nr |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The named fields are as defined in Section 3.2.1. Note that the Length field is still calculated from the beginning of the control message header, starting with the T bit. It does NOT include the "(32 bits of zeros)" shown above. ๐
When operating directly over IP, L2TP packets lose the ability to use the UDP checksum as a simple packet integrity check, and that's a big deal for L2TP control messages ๐ญ Control Message Authentication (see Section 4.3), even with an empty password field, provides a sufficient packet integrity check and SHOULD always be enabled. ๐
4.1.2. L2TP over UDP ๐ท
L2TPv3 over UDP has to consider other L2 tunneling protocols that might be running in the same environment, including L2TPv2 [RFC2661] and L2F [RFC2341]. ๐
Running L2TP directly over IP has its efficiencies, but there can be side effects too. For instance, L2TP over IP is not as NAT-friendly as L2TP over UDP. ๐
4.1.2.1. L2TP Session Header Over UDP ๐
The following session header format is used when operating L2TPv3 over UDP:
Figure 4.1.2.1: L2TPv3 Session Header over UDP
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|T|x|x|x|x|x|x|x|x|x|x|x| Ver | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Session ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cookie (optional, maximum 64 bits)...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The T bit MUST be set to 0, which means this is a data message. ๐จ
The x bits and the Reserved field are reserved for future extensions. All reserved values MUST be set to 0 on outgoing messages and ignored on incoming messages. ๐งผ
The Ver field MUST be set to 3, which means it's an L2TPv3 message. โ
Heads up: the initial bits 1, 4, 6, and 7 mean something in L2TPv2 [RFC2661], and they're deprecated and marked as reserved in L2TPv3. So for UDP mode on a system that supports both versions of L2TP, it's important to inspect the Ver field first to figure out the version of the header before acting on any of these bits. ๐จ
The Session ID and Cookie fields are as defined in Section 4.1. ๐ซ
4.1.2.2. UDP Port Selection ๐
The method for UDP Port Selection defined in this section is identical to the one defined for L2TPv2 [RFC2661].
When negotiating a control connection over UDP, control messages MUST be sent as UDP datagrams using the registered UDP port 1701 [RFC1700]. The initiator of an L2TP control connection picks an available source UDP port (which may or may not be 1701) and sends to the desired destination address at port 1701. The recipient picks a free port on its own system (which may or may not be 1701) and sends its reply to the initiator's UDP port and address, setting its own source port to the free port it found. ๐ฏ
Any subsequent traffic tied to this control connection (either control traffic or data traffic from a session established through this control connection) must use these same UDP ports. ๐
It has been suggested that having the recipient choose an arbitrary source port (instead of using the destination port in the packet that started the control connection, i.e., 1701) may make it harder for L2TP to traverse some NAT devices. Implementations should think carefully about this before choosing an arbitrary source port. A NAT device that can pass TFTP traffic with variant UDP ports should be able to pass L2TP UDP traffic too, since both protocols use similar policies for UDP port selection. ๐ต๏ธโโ๏ธ
4.1.2.3. UDP Checksum ๐งฎ
The tunneled frames that L2TP carries often have their own checksums or integrity checks, which makes the UDP checksum redundant for much of the L2TP data message contents. So UDP checksums MAY be disabled to reduce the packet processing burden at the L2TP endpoints. ๐ซ
The L2TP header itself doesn't have its own checksum or integrity check. However, using the L2TP Session ID and Cookie pair guards against accepting an L2TP data message if the Session ID or its associated Cookie has been corrupted. When the L2-Specific Sublayer is present in the L2TP header, there's no built-in integrity check for the information in it unless UDP checksums or some other integrity check are used. IPsec (see Section 4.1.3) may be used for strong integrity protection of the entire contents of L2TP data messages. ๐ก๏ธ
UDP checksums MUST be enabled for L2TP control messages. ๐
4.1.3. L2TP and IPsec โจ
okay bestie, the L2TP data channel has zero cryptographic security built in ๐ so if it's running over a public or untrusted IP network where privacy matters, or you're expecting sophisticated attacks, IPsec [RFC2401] MUST be made available to lock the L2TP traffic down ๐
Either L2TP over UDP or L2TP over IP can be secured with IPsec. [RFC3193] is the recommended method for securing L2TPv2 ๐ L2TPv3 has identical characteristics to IPsec as L2TPv2 when it runs over UDP, so implementations MUST follow the same recommendation ๐
When it's running over IP directly, [RFC3193] still applies, though the bits about UDP source and destination ports (especially the ones in Section 4, "IPsec Filtering details when protecting L2TP") may be ignored ๐ Instead, the selectors used to spot L2TPv3 traffic are just the source and destination IP addresses of the tunnel endpoints, plus the L2TPv3 IP protocol type, 115 โจ
IPsec also has a tunnel mode for tunneling IP packets ๐ฆ The packet-level encryption and authentication from IPsec tunnel mode and the protection you get from L2TP secured with IPsec give you an equivalent level of security for these requirements. Literally the same vibe ๐
IPsec also defines access control features that a compliant IPsec implementation is required to have ๐ These let you filter packets based on network and transport layer stuff like IP address, ports, etc. In the L2TP tunneling model, similar filtering may be performed at the network layer above L2TP ๐ธ These network layer access control features may be handled at an LCCE through vendor-specific authorization features, or at the network layer itself by using IPsec transport mode end-to-end between the communicating hosts. The requirements for access control mechanisms are not a part of the L2TP specification, so they're outside the scope of this document ๐ง
Protecting the L2TP packet stream with IPsec also protects the data inside the tunneled session packets while it's transported from one LCCE to the other ๐ซถ But this protection must not be considered a substitution for end-to-end security between communicating hosts or applications. Don't let it trick you, bestie ๐ญ
4.1.4. IP Fragmentation Issues ๐งฉ
Fragmentation and reassembly in network equipment generally need way more resources than sending or receiving a packet as a single unit ๐ So fragmentation and reassembly should be avoided whenever possible. The ideal ways to dodge fragmentation include proper configuration and management of MTU sizes among the Remote System, the LCCE, and the IP network, plus adaptive measures that work with the originating host (e.g., [RFC1191], [RFC1981]) to shrink the packet sizes at the source ๐
An LCCE MAY fragment a packet before encapsulating it in L2TP ๐ For example, say an IPv4 packet shows up at an LCCE from a Remote System, and after it gets its framing, L2TP, and IP wrapped around it, it doesn't fit in the available path MTU toward its LCCE peer. The local LCCE may perform IPv4 fragmentation on the packet before tunnel encapsulation. This creates two (or more) L2TP packets, each carrying an IPv4 fragment with its associated framing. Basically the burden of fragmenting lands on the LCCE, while reassembly happens on the IPv4 destination host ๐
If an IPv6 packet arrives at an LCCE from a Remote System, and after its framing, L2TP, and IP are added it doesn't fit in the available path MTU toward its L2TP peer, the Generic Packet Tunneling specification [RFC2473], Section 7.1 SHOULD be followed. In that case, the LCCE should either send an ICMP Packet Too Big message to the data source, or fragment the resultant L2TP/IP packet (so the L2TP peer can reassemble it) ๐ฆ
If the amount of traffic needing fragmentation and reassembly is pretty light, or the tunnel endpoints have sufficiently optimized mechanisms, fragmenting the L2TP/IP packet may be sufficient for handling mismatched MTUs that can't be managed by more efficient means โจ This method basically fakes a larger MTU between the tunnel endpoints and should work for any type of L2-encapsulated packet. Note that IPv6 does not support "in-flight" fragmentation of data packets ๐ญ So, unlike IPv4, the MTU of the path toward an L2TP peer must be known in advance (or the last-resort IPv6 minimum MTU of 1280 bytes gets used) so that IPv6 fragmentation can happen at the LCCE. Bestie, plan ahead ๐๏ธ
In summary, there are a bunch of valid ways to handle MTU mismatches: trying to control the source MTU by talking to the originating host, forcing the path between LCCE peers to have an MTU big enough to tunnel a frame from any other interface without fragmentation, fragmenting IP packets before L2TP/IP encapsulation, or fragmenting the resultant L2TP/IP packet between the tunnel endpoints ๐
Some are clearly better than others depending on the deployment. For example, a passive monitoring application using L2TP would <rose>definitely not</rose> want ICMP messages sent to a traffic source ๐ And if the links connecting a set of LCCEs have a very large MTU (e.g., SDH/SONET), and it's known that every link being tunneled by L2TP has a smaller MTU (e.g., 1500 bytes), then any IP fragmentation and reassembly enabled on the participating LCCEs would never get used ๐ซ
An implementation MUST implement at least one of the methods described in this section for managing mismatched MTUs, based on careful consideration of how the final product will be deployed ๐ Like, pick your fighter, but pick it on purpose ๐
L2TP-specific fragmentation and reassembly methods may be defined as well, and they may or may not depend on the characteristics of the type of link being tunneled (e.g., judicious packing of ATM cells). But those methods are outside the scope of this document ๐ธ
4.2. Reliable Delivery of Control Messages ๐
okay so L2TP has its own lower-level reliable delivery service for ALL control messages ๐
The Nr and Ns fields in the control message header (check Section 3.2.1 ๐ง) belong to this delivery mechanism. The upper-level L2TP functions don't care about retransmission or ordering of control messages at all, it's giving "not my problem" ๐ This reliable control messaging thing is a sliding window mechanism that handles both retransmission AND congestion control. Each peer keeps its own separate sequence number state for each control connection โจ
The message sequence number, Ns, starts at 0 ๐ธ and every next message goes up by one. It's a free-running counter, represented modulo 65536, so it just wraps around, periodt. A received message's sequence number counts as "less than or equal to" the last one received if it lands in the range from the last received number and the 32767 values before it, inclusive. Example time: if the last received sequence number was 15, then messages numbered 0 through 15 AND 32784 through 65535 would all count as less than or equal ๐ญ Those are treated as duplicates of something already received, so they get ignored for processing. BUT here's the iconic part: receipt of duplicate messages MUST be acknowledged by the reliable delivery mechanism, so every message gets ACKed properly, especially if an ACK got lost along the way ๐ซถ That acknowledgment can either be piggybacked on a message already in the queue, or sent explicitly via an ACK message.
All control messages take up one slot in the control message sequence number space, except the ACK message. So Ns doesn't go up after an ACK is sent. Main character energy for the ACK, honestly ๐
The last received message number, Nr, is how an L2TP peer acknowledges messages it got. It holds the sequence number of the message the peer expects to receive next (so basically the last Ns of a non-ACK message received, plus 1, modulo 65536) ๐ฆ The Nr in a received ACK is used to flush messages out of the local retransmit queue (more on that below), but the Nr of the next message you send does NOT get updated by the Ns of that ACK. Also, Nr SHOULD be sanity-checked before you flush the retransmit queue. For instance, if the Nr in a control message is greater than the last Ns sent plus 1 modulo 65536, that control message is clearly invalid ๐ Not vibing with that one.
The reliable delivery mechanism at a receiving peer is responsible for making sure control messages reach the upper level in order and without duplication โจ Messages that show up out-of-order can be queued so they get delivered in order once the missing ones arrive. Or they can be discarded, which means the peer has to retransmit them. When dropping out-of-order control packets, Nr MAY be updated before the packet is discarded ๐ง
Each control connection keeps a queue of control messages to send to its peer ๐ The message at the front of the queue goes out with a given Ns value and gets held until a control message arrives from the peer whose Nr field shows that this message was received. After a period of time (a recommended default is 1 second but SHOULD be configurable) passes with no acknowledgment, the message gets retransmitted. The retransmitted message keeps the same Ns value, but its Nr value MUST be updated with the sequence number of the next expected message ๐ฅ
Every retransmission after that MUST use an exponential backoff interval, so it's like a little escalating countdown ๐ญ If the first retransmission happened after 1 second, the next one should occur after 2 seconds have elapsed, then 4 seconds, and so on. An implementation MAY put a cap on the maximum interval between retransmissions ๐ That cap SHOULD be no less than 8 seconds per retransmission. If there's still no response from the peer after several retransmissions (a recommended default is 10, but MUST be configurable), the control connection and ALL its associated sessions MUST be cleared ๐ The SCCRQ MAY use a different retransmission maximum than other control messages, since it's the first message used to set up a control connection, and that helps with failing over to alternate LCCEs in a timely way ๐
Now the shutdown part, which is SO important. When a control connection is being shut down for reasons OTHER than losing connectivity, the state and reliable delivery mechanisms MUST be maintained and operated for the full retransmission interval after the final StopCCN message has been sent (e.g., 1 + 2 + 4 + 8 + 8... seconds), or until the StopCCN message itself has been acknowledged ๐ซถ Don't just bounce early, bestie.
Here's the sliding window bit ๐ช Picture two peers, A and B. Say A specifies a Receive Window Size AVP with a value of N in the SCCRQ or SCCRP message. Then B is allowed to have a maximum of N outstanding (aka unacknowledged) control messages ๐ Once N messages have been sent, B must wait for an acknowledgment from A that advances the window before it sends any new control messages. An implementation may advertise a non-zero receive window as small or as large as it wants, depending on how well it can process incoming messages before sending an acknowledgement โจ Each peer MUST limit the number of unacknowledged messages it will send before receiving an acknowledgement to this Receive Window Size. The actual internal unacknowledged message send-queue depth might be limited even further by local resource allocation, or by dynamic slow-start and congestion-avoidance mechanisms ๐ธ
When retransmitting control messages, a slow start and congestion avoidance window adjustment procedure SHOULD be utilized ๐ง A recommended procedure is described in Appendix A. A peer MAY drop messages, but it MUST NOT actively delay acknowledgment of messages as a way to do flow control of control messages. No slow-walking your ACKs ๐ โโ๏ธ Appendix B has examples of control message transmission, acknowledgment, and retransmission, so go check those out ๐ฆ
4.3. Control Message Authentication ๐
L2TP has an optional authentication and integrity check for ALL control messages ๐ก๏ธ This mechanism is made of a computed one-way hash over the header and body of the L2TP control message, a pre-configured shared secret, and a local and remote nonce (random value) exchanged via the Control Message Authentication Nonce AVP. This per-message authentication and integrity check is designed to do a mutual authentication between L2TP nodes, check integrity of all control messages, and guard against control message spoofing and replay attacks that would otherwise be trivially easy to pull off ๐ค
At least one shared secret (password) MUST exist between communicating L2TP nodes to enable Control Message Authentication ๐ See Section 5.4.3 for details on how the Message Digest is calculated and how the Control Message Authentication Nonce and Message Digest AVPs are built.
L2TPv3 Control Message Authentication is similar to L2TPv2 [RFC2661] Tunnel Authentication in that it uses a shared secret and one-way hash calculation ๐ฏ The main difference is that instead of computing the hash over selected contents of a received control message (like the Challenge AVP and Message Type, as in L2TPv2), L2TPv3 hashes the ENTIRE message. Also, instead of only including the hash digest in the SCCRP and SCCCN messages, it's now included in ALL L2TP messages ๐
Control Message Authentication is optional, and it can be disabled if both peers agree ๐ For example, if IPsec is already doing security and integrity checking between the LCCEs, then the L2TP mechanism is redundant and may be disabled. Double-checking your homework is cute, but not when it's literally the same check twice ๐
The presence of the Control Message Authentication Nonce AVP in an SCCRQ or SCCRP message is how a peer knows Control Message Authentication is enabled ๐ฆ If an SCCRQ or SCCRP contains a Control Message Authentication Nonce AVP, the receiver of the message MUST respond with a Message Digest AVP in ALL subsequent messages it sends. Control Message Authentication is always bidirectional, so either both sides take part in authentication, or neither one does. No one-sided situationships here ๐
If Control Message Authentication is disabled, the Message Digest AVP still MAY be sent as an integrity check of the message ๐งฉ The integrity check is calculated as in Section 5.4.3, with an empty zero-length shared secret, local nonce, and remote nonce. If an invalid Message Digest is received, it should be assumed that the message got corrupted in transit, and the message gets dropped accordingly ๐๏ธ
Implementations MAY rate-limit control messages, especially SCCRQ messages, when they're received, either for performance reasons or to protect against denial of service attacks ๐ง Protect your peace, protect your server ๐ก๏ธ
4.4. Keepalive (Hello) ๐
L2TP uses a keepalive mechanism to detect loss of connectivity between a pair of LCCEs ๐ซ It works by injecting Hello control messages (see Section 6.5) once a period of time has passed since the last data message or control message was received on an L2TP session or control connection, respectively. Same as with any other control message, if the Hello message isn't reliably delivered, the sending LCCE declares that the control connection is down and resets its state for that control connection ๐ฌ This makes sure a connectivity failure between the LCCEs gets detected independently by each end of a control connection. Both sides are watching each other, no ghosting ๐
Since the control channel runs in-band with data traffic over the PSN, this single mechanism can be used to infer basic data connectivity between a pair of LCCEs for all sessions associated with the control connection โจ One check, many sessions covered, very efficient, very iconic ๐ง
Periodic keepalive for the control connection MUST be implemented by sending a Hello if a period of time (a recommended default is 60 seconds, but MUST be configurable) has passed without receiving any message (data or control) from the peer โฐ And an LCCE sending Hello messages across multiple control connections between the same LCCE endpoints MUST employ a jittered timer mechanism, so the Hello messages don't all get grouped together and clump up ๐ Spread the love, spread the timers ๐
4.5. Forwarding Session Data Frames ๐
Okay bestie, once session establishment is done, circuit frames show up at an LCCE ๐. They get wrapped up in L2TP (paying attention to framing, as described in the documents for the particular pseudowire type ๐ง) and sent out over the right session. For every outgoing data message, the sender drops the identifier from the Local Session ID AVP (the one it got from its peer during session establishment) into the Session ID field of the L2TP data header ๐. That's how session frames get multiplexed and demultiplexed between a given pair of LCCEs ๐ฆ. Multiple control connections can exist between the same pair of LCCEs, and multiple sessions can hang off one control connection, periodt ๐.
The peer LCCE that receives the L2TP data packet figures out which session it belongs to from the Session ID in the packet's header ๐. Then it checks the Cookie field against the value it got in the Assigned Cookie AVP during session establishment ๐. Important for implementers: the Cookie check happens after you look up the session context by Session ID, so it's literally just a value match between the Cookie field and whatever's stored in that retrieved context ๐ . You don't need to look up the Session ID and Cookie as one combined value ๐. Any received data packets with invalid Session IDs or associated Cookie values MUST be dropped ๐. Finally, the LCCE either forwards the network packet inside the tunneled frame (like an LNS does) or switches the frame onto a circuit (like a LAC does) ๐.
4.6. Default L2-Specific Sublayer ๐ธ
This document defines a Default L2-Specific Sublayer format (see Section 3.2.2) that a pseudowire can use for stuff like sequencing support, L2 interworking, OAM, or other per-data-packet operations ๐ง. The Default L2-Specific Sublayer SHOULD be used by a given PW type for these features if it's adequate and its presence was requested by a peer during session negotiation ๐. Alternative sublayers MAY be defined (for example, an encapsulation with a bigger Sequence Number field, or timing information) and identified for use via the L2-Specific Sublayer Type AVP โจ.
Figure 4.6: Default L2-Specific Sublayer Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|x|S|x|x|x|x|x|x| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The S (Sequence) bit is set to 1 when the Sequence Number contains a valid number for this sequenced frame ๐ฆ. If the S bit is set to zero, the Sequence Number contents are undefined and MUST be ignored by the receiver ๐.
The Sequence Number field is a free-running counter of 2^24 sequence numbers ๐ข. If the number in this field is valid, the S bit MUST be set to 1 ๐ . The Sequence Number begins at zero, which is a valid sequence number (so implementations inserting sequence numbers don't have to "skip" zero when they increment ๐ซถ). The sequence number in the header of a received message is considered less than or equal to the last received number if its value lies in the range of the last received number and the preceding (2^23-1) values, inclusive ๐ง .
4.6.1. Sequencing Data Packets ๐งฆ
The Sequence Number field can be used to detect lost, duplicate, or out-of-order packets within a given session ๐ต๏ธ.
When L2 frames are carried over an L2TP-over-IP or L2TP-over-UDP/IP data channel, that part of the link can reorder, duplicate, or silently drop packets ๐ญ. Reordering may break some non-IP protocols or L2 control traffic carried by the link. Silent dropping or duplication may break protocols that assume per-packet indications of error, like TCP header compression ๐. A common mechanism for packet sequence detection is provided, but the sequence dependency characteristics of individual protocols are outside the scope of this document ๐.
If any protocol carried over L2TP data channels can't tolerate misordered data packets, packet duplication, or silent packet loss, sequencing may be enabled on some or all packets by using the S bit and Sequence Number field defined in the Default L2-Specific Sublayer (see Section 4.6) ๐. For a given L2TP session, each LCCE is responsible for telling its peer the level of sequencing support it requires of the data packets it receives ๐ฌ. Mechanisms to advertise this during session negotiation are provided (see Data Sequencing AVP in Section 5.4.4) โจ.
When figuring out whether a packet is in or out of sequence, an implementation SHOULD use a method that's resilient to temporary dropouts in connectivity combined with high per-session packet rates ๐. The recommended method is outlined in Appendix C ๐.
4.7. L2TPv2/v3 Interoperability and Migration ๐ฆ
L2TPv2 and L2TPv3 environments should be able to coexist while a migration to L2TPv3 is made. Migration issues are discussed for each media type in this section. Most issues only apply to implementations that need both L2TPv2 and L2TPv3 operation ๐ซ .
However, even L2TPv3-only implementations must at least be mindful of these issues so they can interoperate with implementations that support both versions ๐ค.
4.7.1. L2TPv3 over IP ๐
L2TPv3 implementations running strictly over IP, with no desire to interoperate with L2TPv2 implementations, may safely disregard most migration issues from L2TPv2 โจ. All control messages and data messages are sent as described in this document, without normative reference to RFC 2661 ๐ .
If one wishes to tunnel PPP over L2TPv3, and fall back to L2TPv2 only if it's not available, then L2TPv3 over UDP with automatic fallback (see Section 4.7.3) MUST be used ๐จ. There is no deterministic method for automatic fallback from L2TPv3 over IP to either L2TPv2 or L2TPv3 over UDP ๐. One could infer whether L2TPv3 over IP is supported by sending an SCCRQ and waiting for a response, but that could be problematic during periods of packet loss between L2TP nodes ๐ฌ.
4.7.2. L2TPv3 over UDP ๐
The format of the L2TPv3 over UDP header is defined in Section 4.1.2.1 ๐งฉ.
When operating over UDP, L2TPv3 uses the same port (1701) as L2TPv2 and shares the first two octets of header format with L2TPv2 ๐ซ. The Ver field is used to tell L2TPv2 packets apart from L2TPv3 packets ๐. If an implementation can operate in L2TPv2 or L2TPv3 modes, it's possible to automatically detect whether a peer supports L2TPv2 or L2TPv3 and operate accordingly ๐ง . The details of this fallback capability are defined in the following section ๐.
4.7.3. Automatic L2TPv2 Fallback ๐
When running over UDP, an implementation may detect whether a peer is L2TPv3-capable by sending a special SCCRQ that's properly formatted for both L2TPv2 and L2TPv3 โจ. This is done by sending an SCCRQ with its Ver field set to 2 (for L2TPv2), making sure that any L2TPv3-specific AVPs (i.e., AVPs present within this document and not defined within RFC 2661) in the message are sent with each M bit set to 0, and that all L2TPv2 AVPs are present as they would be for L2TPv2 ๐. This way, L2TPv3 AVPs get ignored by an L2TPv2-only implementation ๐. Note that, in both L2TPv2 and L2TPv3, the value sitting in the space of the control message header that's used by the 32-bit Control Connection ID in L2TPv3, and by the 16-bit Tunnel ID and 16-bit Session ID in L2TPv2, is always 0 for an SCCRQ ๐ข. This effectively hides the fact that there are a pair of 16-bit fields in L2TPv2 and a single 32-bit field in L2TPv3 ๐ซฅ.
If the peer implementation is L2TPv3-capable, a control message with the Ver field set to 3 and an L2TPv3 header and message format will be sent in response to the SCCRQ ๐. Operation may then continue as L2TPv3 ๐ฆ. If a message is received with the Ver field set to 2, it must be assumed that the peer implementation is L2TPv2-only, so falling back to L2TPv2 mode can happen safely ๐.
Note Well ๐: The L2TPv2/v3 auto-detection mode requires that all L2TPv3 implementations over UDP be liberal in accepting an SCCRQ control message with the Ver field set to 2 or 3 and the presence of L2TPv2-specific AVPs. An L2TPv3-only implementation MUST ignore all L2TPv2 AVPs (e.g., those defined in RFC 2661 and not in this document) within an SCCRQ with the Ver field set to 2 (even if the M bit is set on the L2TPv2-specific AVPs).
5. Control Message Attribute Value Pairs ๐
To maximize extensibility while permitting interoperability, a uniform method for encoding message types is used throughout L2TP ๐ง. This encoding will be termed AVP (Attribute Value Pair) for the remainder of this document ๐.
5.1. AVP Format ๐
Okay bestie, every AVP gets encoded the same way, so let's stare at these boxes together ๐ฆ
Figure 5.1: AVP Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|M|H| rsvd | Length | Vendor ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Type | Attribute Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(until Length is reached) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The first six bits are a bit mask that describes the general attributes of the AVP. Two bits are defined in this document, and the rest are saved for future extensions ๐. Reserved bits MUST be set to 0 when sent and ignored upon receipt.
- Mandatory (M) bit: This one decides what a receiver has to do when it runs into an AVP it doesn't recognize ๐. The M bit of a given AVP MUST only be inspected and acted upon if the AVP is unrecognized (see Section 5.2).
- Hidden (H) bit: This marks whether the data in the Attribute Value field is hidden. It's giving privacy ๐, because it keeps sensitive stuff like user passwords from traveling as cleartext in an AVP. Section 5.3 describes the procedure for performing AVP hiding.
- Length: This is the number of octets in the AVP, counting the Overall Length and bit mask fields too. The Length may be calculated as 6 + the length of the Attribute Value field in octets.
The field itself is 10 bits, so one AVP can hold a maximum of 1023 octets of data ๐. The minimum Length of an AVP is 6. If the Length is 6, then the Attribute Value field is absent.
- Vendor ID: This is the IANA-assigned "SMI Network Management Private Enterprise Codes" [RFC1700] value. The value 0, corresponding to IETF-adopted attribute values, is used for all AVPs defined within this document. Any vendor who wants its own L2TP extensions can use its own Vendor ID along with private Attribute values, so they won't collide with any other vendor's extensions or future IETF extensions โจ. Note that there are 16 bits allocated for the Vendor ID, which limits this feature to the first 65,535 enterprises.
- Attribute Type: A 2-octet value with a unique interpretation across all AVPs defined under a given Vendor ID ๐ง.
- Attribute Value: This is the actual value, as indicated by the Vendor ID and Attribute Type. It comes right after the Attribute Type field and runs for the remaining octets indicated in the Length (that's Length minus 6 octets of header). This field is absent if the Length is 6.
In the event that the 16-bit Vendor ID space is exhausted, vendor-specific AVPs with a 32-bit Vendor ID MUST be encapsulated in the following manner:
Figure 5.2: Extended Vendor ID AVP Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|M|H| rsvd | Length | 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 58 | 32-bit Vendor ID ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Attribute Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
(until Length is reached) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This AVP is a little wrapper ๐ that encodes a vendor-specific AVP with a 32-bit Vendor ID space inside its Attribute Value field. Multiple AVPs of this type may exist in any message. The 16-bit Vendor ID MUST be 0, which tells you this is an IETF-defined AVP, and the Attribute Type MUST be 58, which tells you that what follows is a vendor-specific AVP with a 32-bit Vendor ID code. This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP MUST be set to 0. The Length of the AVP is 12 plus the length of the Attribute Value.
5.2. Mandatory AVPs and Setting the M Bit ๐
If the M bit is set on an AVP that is unrecognized by its recipient, the session or control connection associated with the control message containing the AVP MUST be shut down. If the control message containing the unrecognized AVP is associated with a session (e.g., an ICRQ, ICRP, ICCN, SLI, etc.), then the session MUST be issued a CDN with a Result Code of 2 and Error Code of 8 (as defined in Section 5.4.2) and shut down. If the control message containing the unrecognized AVP is associated with establishment or maintenance of a Control Connection (e.g., SCCRQ, SCCRP, SCCCN, Hello), then the associated Control Connection MUST be issued a StopCCN with Result Code of 2 and Error Code of 8 (as defined in Section 5.4.2) and shut down. If the M bit is not set on an unrecognized AVP, the AVP MUST be ignored when received, processing the control message as if the AVP were not present.
Receipt of an unrecognized AVP that has the M bit set is catastrophic to the session or control connection it's tied to ๐. So the M bit should only be set for AVPs that the sender deems crucial to proper operation of the session or control connection. What counts as crucial can vary by application and configured options. In no case shall a receiver "validate" whether the M bit is set on a recognized AVP. If the AVP is recognized (as all AVPs defined in this document MUST be for a compliant L2TPv3 specification), then by definition, the M bit is of no consequence.
The sender of an AVP is free to set its M bit to 1 or 0, depending on whether the configured application strictly requires the value in the AVP to be recognized or not. For example, "Automatic L2TPv2 Fallback" in Section 4.7.3 requires the M bit on all new L2TPv3 AVPs to be set to zero if fallback to L2TPv2 is supported and desired, and 1 if not ๐.
The M bit is useful as extra assurance for support of critical AVP extensions. However, more explicit methods may be available to determine support for a given feature, so the M bit isn't the only tool you've got ๐ง . For example, if a new AVP is defined in a message that always gets a reply (an ICRQ, ICRP, SCCRQ, or SCCRP message), then instead of just sending an AVP with the M bit set, you can check support by sending an AVP in the request and expecting a corresponding AVP in the reply. This more explicit method, when it's possible, is preferred ๐.
The M bit also plays a role in deciding whether a malformed or out-of-range value within an AVP should be ignored or should result in termination of a session or control connection (see Section 7.1 for more details) ๐ธ.
5.3. Hiding of AVP Attribute Values ๐
okay so the H bit in every AVP header is basically the "this is private, don't peek" flag ๐คซ it tells the receiving peer whether the AVP's contents are hidden or sitting there in cleartext. this is the thing you use for the spicy stuff like user passwords, IDs, or other vital info ๐
the H bit MUST only be set if (1) a shared secret exists between the LCCEs and (2) Control Message Authentication is enabled (see Section 4.3). if the H bit is set in any AVP(s) in a given control message, at least one Random Vector AVP must also be present in the message and MUST precede the first AVP having an H bit of 1. no cap, the order matters ๐ซถ
the shared secret between LCCEs gets turned into a unique shared key for all the hiding and unhiding math ๐ it's made with an HMAC-MD5 keyed hash [RFC2104], where the key is the shared secret and the data being hashed is one single octet with the value 1.
shared_key = HMAC_MD5 (shared_secret, 1)
okay now the hiding itself, which happens in a few steps ๐ง step one is grabbing the length and value fields of the original cleartext AVP and packing them into the Hidden AVP Subformat, which looks like this:
Figure 5.3: Hidden AVP Subformat
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length of Original Value | Original Attribute Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... | Padding ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
the fields inside are:
- Length of Original Attribute Value ๐: the length of the Original Attribute Value being obscured, in octets. this is needed so you can figure out the real length again after the extra Padding gets tacked on.
- Original Attribute Value ๐: the Attribute Value that's getting hidden.
- Padding ๐ธ: random extra octets that hide how long the hidden value really is.
to hide the size of the data, the resulting subformat MAY be padded like shown above. padding does NOT alter the value in the Length of Original Attribute Value field, but it DOES change the length of the AVP you end up creating ๐ for example, a hidden value that's 4 octets long means the unhidden AVP length would be 10 octets (6 + Attribute Value length). after hiding, the AVP length becomes 6 + Attribute Value length + size of the Length of Original Attribute Value field + Padding. so if Padding is 12 octets, the AVP length works out to 6 + 4 + 2 + 12 = 24 octets. the math is mathing โจ
step two: an MD5 [RFC1321] hash gets run (in network byte order) on the concatenation of:
- the 2-octet Attribute number of the AVP
- the shared key
- an arbitrary length random vector
the random vector used in that hash gets passed in the value field of a Random Vector AVP. this Random Vector AVP must be placed in the message by the sender before any hidden AVPs. the same random vector can be reused for more than one hidden AVP in the same message, BUT not for hiding two or more instances of an AVP with the same Attribute Type, unless the Attribute Values in those AVPs are also identical. when you switch to a different random vector for the next hidden AVPs, a new Random Vector AVP MUST be placed in the control message before the first AVP it applies to. keep track of your random vectors, bestie, it's giving organization ๐๏ธ
next, the MD5 hash value gets XORed with the first 16-octet (or less) segment of the Hidden AVP Subformat, and the result goes into the Attribute Value field of the Hidden AVP. if the Hidden AVP Subformat is less than 16 octets, it gets treated as if the Attribute Value field had been padded out to 16 octets before the XOR. only the octets that are actually present in the Subformat get modified, and the length of the AVP stays the same ๐ฆ
if the Subformat is longer than 16 octets, a second one-way MD5 hash is calculated over a stream of octets made of the shared key followed by the result of the first XOR. that hash gets XORed with the second 16-octet (or less) segment of the Subformat, and the output lands in the matching octets of the Value field of the Hidden AVP.
if it's still not done, you just repeat this, with the shared key plus each XOR result generating the next hash to XOR the next segment with ๐
the hiding method was adapted from [RFC2865], which was itself taken from the "Mixing in the Plaintext" section in the book "Network Security" by Kaufman, Perlman and Speciner [KPS]. here's the detailed version of how it works:
call the shared key S, the Random Vector RV, and the Attribute Type A. break the value field into 16-octet chunks p_1, p_2, etc., where the last one gets padded at the end with random data up to a 16-octet boundary. call the ciphertext blocks c_1, c_2, etc. we'll also define intermediate values b_1, b_2, etc.
b_1 = MD5 (A + S + RV) c_1 = p_1 xor b_1
b_2 = MD5 (S + c_1) c_2 = p_2 xor b_2
. .
. .
. .
b_i = MD5 (S + c_i-1) c_i = p_i xor b_i
the String will contain c_1 + c_2 +...+ c_i, where "+" means concatenation.
on receipt, the random vector comes from the last Random Vector AVP encountered in the message before the AVP that needs unhiding. then you just reverse the whole process and boom, the original value comes back out ๐
5.4. AVP Summary ๐
okay so this section is basically the cheat sheet ๐ it contains a list of all the L2TP AVPs defined in this document.
after each AVP's name, you get a list of the message types that use that AVP ๐จ then comes a short description of what the AVP is for, a detailed breakdown of the Attribute Value format (with a diagram), and any extra info you need to use the AVP properly. main character energy for the reference section ๐
5.4.1. General Control Message AVPs ๐
Okay bestie, this is the big one: the AVPs that show up in basically every control message. Let's go! ๐
Message Type (All Messages) ๐ง
The Message Type AVP, Attribute Type 0, tells you which control message you're looking at, and it sets the context for working out what the other AVPs mean. ๐
The Attribute Value field for this AVP has the following format:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Message Type is a 2-octet unsigned integer. ๐
The Message Type AVP MUST be the first AVP in a message, immediately following the control message header (defined in Section 3.2.1). See Section 3.1 for the list of defined control message types and their identifiers. ๐
The M bit in this AVP is lowkey unique. It doesn't mean "ignore this AVP if you don't recognize it." It means whether the whole control message should be ignored. If the M bit is set and the Message Type is unknown to the implementation, the control connection MUST be cleared. If the M bit is not set, the implementation may ignore an unknown message type. The M bit MUST be set to 1 for all message types defined in this document. This AVP MUST NOT be hidden (the H bit MUST be 0). The Length of this AVP is 8. ๐
A vendor-specific control message may be defined by setting the Vendor ID of the Message Type AVP to a value other than the IETF Vendor ID of 0 (see Section 5.1). The Message Type AVP MUST still be the first AVP in the control message. โจ
Message Digest (All Messages) ๐
The Message Digest AVP, Attribute Type 59, is used as an integrity and authentication check of the L2TP Control Message header and body. It's giving security guard energy. ๐
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Digest Type | Message Digest ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... (16 or 20 octets) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Digest Type is a one-octet integer that picks the digest calculation algorithm:
0 HMAC-MD5 [RFC2104]
1 HMAC-SHA-1 [RFC2104]
Digest Type 0 (HMAC-MD5) MUST be supported, while Digest Type 1 (HMAC-SHA-1) SHOULD be supported. ๐
The Message Digest is variable length and holds the result of the control message authentication and integrity calculation. For Digest Type 0 (HMAC-MD5), the length of the digest MUST be 16 bytes. For Digest Type 1 (HMAC-SHA-1), the length of the digest MUST be 20 bytes. ๐ฆ
If Control Message Authentication is enabled, at least one Message Digest AVP MUST be present in all messages, and it MUST be placed immediately after the Message Type AVP. This forces the Message Digest AVP to begin at a well-known and fixed offset. A second Message Digest AVP MAY be present in a message, and if it is, it MUST be placed directly after the first Message Digest AVP. ๐ซถ
The shared secret between LCCEs is used to derive a unique shared key for Control Message Authentication calculations. The derived shared key comes from an HMAC-MD5 keyed hash [RFC2104], where the key is the shared secret and the data being hashed is a single octet containing the value 2:
shared_key = HMAC_MD5 (shared_secret, 2)
Calculating the Message Digest works like this for all messages other than the SCCRQ (where "+" means concatenation):
Message Digest = HMAC_Hash (shared_key, local_nonce +
remote_nonce + control_message)
Here's what each piece means:
HMAC_Hash: the HMAC hashing algorithm identified by the Digest Type (MD5 or SHA1)local_nonce: a nonce chosen locally and advertised to the remote LCCEremote_nonce: a nonce received from the remote LCCEshared_key: the derived shared key for this control connectioncontrol_message: the entire contents of the L2TP control message, including the control message header and all AVPs. The control message header in this case begins after the all-zero Session ID when running over IP (see Section 4.1.1.2), and after the UDP header when running over UDP (see Section 4.1.2.1).
(The local_nonce and remote_nonce are advertised via the Control Message Authentication Nonce AVP, also defined in this section. ๐ฐ)
When calculating the Message Digest, the Message Digest AVP MUST be present within the control message with the Digest Type set to its proper value, but the Message Digest itself set to zeros. ๐
When receiving a control message, the contents of the Message Digest AVP MUST be compared against the expected digest value from a local calculation. You do this by running the same digest calculation as above, but with the local_nonce and remote_nonce reversed. This message authenticity and integrity checking MUST be performed before using any information contained within the control message. If the calculation fails, the message MUST be dropped. ๐ซ
The SCCRQ gets its own special treatment because it's the initial message that starts a new control connection. Because of that, only one nonce is available. Since the nonce is already in the message itself as part of the Control Message Authentication Nonce AVP, there's no need to use it in the calculation explicitly. The SCCRQ Message Digest is calculated like this:
Message Digest = HMAC_Hash (shared_key, control_message)
To allow for a graceful switchover to a new shared secret or hash algorithm, two Message Digest AVPs MAY be present in a control message, and two shared secrets MAY be configured for a given LCCE. If two Message Digest AVPs are received in a control message, the message MUST be accepted if either Message Digest is valid. If two shared secrets are configured, each one (separately) MUST be used for calculating a digest to compare against the Message Digest(s) received. When calculating a digest for a control message, the Value field for both of the Message Digest AVPs MUST be set to zero. ๐
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length is 23 for Digest Type 1 (HMAC-MD5), and 27 for Digest Type 2 (HMAC-SHA-1). ๐งฎ
Control Message Authentication Nonce (SCCRQ, SCCRP) ๐ฒ
The Control Message Authentication Nonce AVP, Attribute Type 73, MUST contain a cryptographically random value [RFC1750]. This value is used for Control Message Authentication. It's the randomness that keeps things fresh. ๐ธ
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Nonce ... (arbitrary number of octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Nonce can be any length, though at least 16 octets is recommended. The Nonce holds the random value used in the Control Message Authentication hash calculation (see the Message Digest AVP definition in this section). ๐ท
If Control Message Authentication is enabled, this AVP MUST be present in the SCCRQ and SCCRP messages. ๐ฅ
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length of this AVP is 6 plus the length of the Nonce. ๐
Random Vector (All Messages) ๐ฆ
The Random Vector AVP, Attribute Type 36, MUST contain a cryptographically random value [RFC1750]. This value is used for AVP Hiding. Hiding is only as good as the randomness behind it, so this one matters a lot. ๐
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Random Octet String ... (arbitrary number of octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Random Octet String can be any length, though at least 16 octets is recommended. The string holds the random vector used when computing the MD5 hash to retrieve or hide the Attribute Value of a hidden AVP (see Section 5.3). ๐ง
More than one Random Vector AVP may appear in a message. When that happens, a hidden AVP uses the Random Vector AVP that comes most closely before it. So at least one Random Vector AVP MUST precede the first AVP with the H bit set. ๐
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length of this AVP is 6 plus the length of the Random Octet String. โจ
5.4.2. Result and Error Codes โจ
Result Code (StopCCN, CDN) ๐
The Result Code AVP, Attribute Type 1, is the one that tells you why the control connection or session is getting terminated. Bestie, this is the reason it's over ๐
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Result Code | Error Code (optional) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Error Message ... (optional, arbitrary number of octets) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
So the Result Code is a 2-octet unsigned integer, and the optional Error Code is also a 2-octet unsigned integer ๐ An optional Error Message can come right after the Error Code. You can tell whether the Error Code and Message are there by looking at the AVP Length field ๐ง The Error Message is an arbitrary string with extra (human-readable) text about the situation. And ngl, it's giving very "be kind to the humans reading this": human-readable text in all error messages MUST be provided in the UTF-8 charset [RFC3629] using the Default Language [RFC2277]. No exceptions, periodt ๐
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length is 8 if there is no Error Code or Message, 10 if there is an Error Code and no Error Message, or 10 plus the length of the Error Message if there is an Error Code and Message ๐
Here are the defined Result Code values for the StopCCN message ๐
0- Reserved.1- General request to clear control connection.2- General error, Error Code indicates the problem.3- Control connection already exists.4- Requester is not authorized to establish a control connection.5- The protocol version of the requester is not supported, Error Code indicates highest version supported.6- Requester is being shut down.7- Finite state machine error or timeout
And here are the general Result Code values for the CDN message ๐
0- Reserved.1- Session disconnected due to loss of carrier or circuit disconnect.2- Session disconnected for the reason indicated in Error Code.3- Session disconnected for administrative reasons.4- Session establishment failed due to lack of appropriate facilities being available (temporary condition).5- Session establishment failed due to lack of appropriate facilities being available (permanent condition).13- Session not established due to losing tie breaker.14- Session not established due to unsupported PW type.15- Session not established, sequencing required without valid L2-Specific Sublayer.16- Finite state machine error or timeout.
Other service-specific Result Codes are defined outside this document, so keep an eye out for those too ๐
Now the Error Codes. These are for problems that aren't tied to any one particular L2TP request. They're about protocol or message format errors instead ๐ If an L2TP reply says in its Result Code that a General Error happened, you should look at the General Error value to figure out what went wrong. The General Error codes that are defined right now, and what they mean, are:
0- No General Error.1- No control connection exists yet for this pair of LCCEs.2- Length is wrong.3- One of the field values was out of range.4- Insufficient resources to handle this operation now.5- Invalid Session ID.6- A generic vendor-specific error occurred.7- Try another. If initiator is aware of other possible responder destinations, it should try one of them. This can be used to guide an LAC or LNS based on policy.8- The session or control connection was shut down due to receipt of an unknown AVP with the M bit set (see Section 5.2). The Error Message SHOULD contain the attribute of the offending AVP in (human-readable) text form.9- Try another directed. If an LAC or LNS is aware of other possible destinations, it should inform the initiator of the control connection or session. The Error Message MUST contain a comma-separated list of addresses from which the initiator may choose. If the L2TP data channel runs over IPv4, then this would be a comma-separated list of IP addresses in the canonical dotted-decimal format (e.g., "192.0.2.1, 192.0.2.2, 192.0.2.3") in the UTF-8 charset [RFC3629] using the Default Language [RFC2277]. If there are no servers for the LAC or LNS to suggest, then Error Code 7 should be used. For IPv4, the delimiter between addresses MUST be precisely a single comma and a single space. For IPv6, each literal address MUST be enclosed in "[" and "]" characters, following the encoding described in [RFC2732].
โ ๏ธ Heads up for Error Code 9: the delimiter between IPv4 addresses has to be precisely a single comma and a single space. For IPv6, every literal address MUST be wrapped in "[" and "]" characters. Don't freestyle this one, it's very specific ๐ญ
When a General Error Code of 6 is used, extra info about the error SHOULD go in the Error Message field ๐ซถ A vendor-specific AVP MAY be sent too, to explain a vendor-specific problem in more detail โจ
5.4.3. Control Connection Management AVPs ๐
Control Connection Tie Breaker (SCCRQ) ๐ฆ
The Control Connection Tie Breaker AVP, Attribute Type 5, says that the sender wants exactly one control connection to exist between a given pair of LCCEs. Main character energy, one connection only ๐
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Control Connection Tie Breaker Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... (64 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Control Connection Tie Breaker Value is an 8-octet random value. It's used to pick a single control connection when two LCCEs request one at the same time ๐ฒ The recipient of a SCCRQ has to check whether it has already sent a SCCRQ to that peer. If it has, a tie has been detected. In that case, the LCCE has to compare its Control Connection Tie Breaker value with the one it received in the SCCRQ. The lower value "wins", and the "loser" MUST discard its control connection. A StopCCN SHOULD be sent by the winner as an explicit rejection for the losing SCCRQ ๐ฅ If a tie breaker is on both sides and the values are equal, both sides MUST discard their control connections and restart control connection negotiation with a new, random tie breaker value. Two sides with the same number? Both start over, iykyk ๐
If a tie breaker is received and an outstanding SCCRQ has no tie breaker value, the initiator that included the Control Connection Tie Breaker AVP "wins". And if neither side sends a tie breaker, two separate control connections get opened ๐ธ
Applications that use a distinct, well-known initiator don't need tie breaking. They MAY leave this AVP out or turn off tie breaking functionality ๐ง Applications that do need tie breaking also need an LCCE to be uniquely identifiable when an SCCRQ arrives. For L2TP over IP, this MUST be done with the Router ID AVP.
Quick history note: in [RFC2661], this AVP is called the "Tie Breaker AVP" and only applies to a control connection. In L2TPv3, the AVP does the same tie breaking job, but now it also applies to a session. The Control Connection Tie Breaker AVP (only in Control Connection messages) and the Session Tie Breaker AVP (only in Session messages) are described separately in this document, but they share the same Attribute type of 5 ๐
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The length of this AVP is 14 ๐
Host Name (SCCRQ, SCCRP) ๐ท๏ธ
The Host Name AVP, Attribute Type 7, tells you the name of the issuing LAC or LNS, encoded in the US-ASCII charset ๐
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Host Name ... (arbitrary number of octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Host Name can be any length, but it MUST be at least 1 octet ๐ซง
The name should be as broadly unique as possible. For hosts that take part in DNS [RFC1034], a host name with a fully qualified domain would be a good fit. The Host Name AVP and/or Router ID AVP MUST be used to identify an LCCE as described in Section 3.3 ๐ชช
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length of this AVP is 6 plus the length of the Host Name โจ
Router ID (SCCRQ, SCCRP) ๐
The Router ID AVP, Attribute Type 60, is an identifier used to identify an LCCE for control connection setup, tie breaking, and/or tunnel authentication. It's giving ID card energy ๐ชช
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Router Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Router Identifier is a 4-octet unsigned integer. Its value is unique for a given LCCE, per Section 8.1 of [RFC2072]. The Host Name AVP and/or Router ID AVP MUST be used to identify an LCCE as described in Section 3.3.
๐ซ Implementations MUST NOT assume that the Router Identifier is a valid IP address. Bestie, don't do it. The Router Identifier for L2TP over IPv6 can be gotten from an IPv4 address (if one is available) or via unspecified implementation-specific means.
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length of this AVP is 10 ๐
Vendor Name (SCCRQ, SCCRP) ๐ญ
The Vendor Name AVP, Attribute Type 8, holds a vendor-specific (possibly human-readable) string that describes the type of LAC or LNS being used ๐ง
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Vendor Name ... (arbitrary number of octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Vendor Name is the indicated number of octets that represent the vendor string. Human-readable text for this AVP MUST be provided in the US-ASCII charset [RFC1958, RFC2277] ๐
Okay so the Vendor Name AVP is giving "optional but make it iconic" ๐ This one MAY be hidden ๐ (the H bit MAY be 0 or 1). The M bit SHOULD be set to 0, but it MAY vary, so check Section 5.2 for the deets ๐. The Length before hiding is 6 plus the length of the Vendor Name.
Assigned Control Connection ID (SCCRQ, SCCRP, StopCCN) โจ
The Assigned Control Connection ID AVP, Attribute Type 61, is literally the ID the sender is giving this control connection ๐ฆ
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Assigned Control Connection ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
It's a 4-octet non-zero unsigned integer ๐ข This AVP is the thing that lets two LCCEs sort out multiple control connections between each other ๐ Once an LCCE receives it, the Control Connection ID from the AVP MUST go in the Control Connection ID field of every control packet it sends to that peer for the whole lifetime of the control connection ๐ Before that AVP shows up, every control message to that peer MUST be sent with a Control Connection ID value of 0 in the header. Zero is basically the special "not yet" value, so it MUST NOT be sent as an Assigned Control Connection ID value ๐ โโ๏ธ
Now the plot twist ๐ญ Sometimes an LCCE has to send a StopCCN before it has heard back an Assigned Control Connection ID (so it sent an SCCRQ but no SCCRP has come back yet). In that case, the Assigned Control Connection ID it already put in the SCCRQ MUST be sent again as the Assigned Control Connection ID in the StopCCN. That way the peer can do a reverse lookup and find the right control connection ๐ง
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit SHOULD be set to 1, but MAY vary (see Section 5.2). The Length before hiding is 10 โจ
Receive Window Size (SCCRQ, SCCRP) ๐
The Receive Window Size AVP, Attribute Type 10, tells the remote peer how big a receive window we're offering ๐ธ
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Window Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Window Size is a 2-octet unsigned integer. If this AVP is absent, the peer must assume a Window Size of 4 for its transmit window ๐ The remote peer may send that many control messages before it has to wait for an acknowledgment. For more on reliable control message delivery, see Section 4.2 ๐ฆ
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit SHOULD be set to 1, but MAY vary (see Section 5.2). The Length of this AVP is 8.
Pseudowire Capabilities List (SCCRQ, SCCRP) ๐
The Pseudowire Capabilities List (PW Capabilities List) AVP, Attribute Type 62, shows which L2 payload types the sender can support ๐ง The specific payload type for a given session is identified by the Pseudowire Type AVP.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PW Type 0 | ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... | PW Type N |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The defined PW types that can show up in this list are managed by IANA, and they'll be in the pseudowire-specific documents for each PW type ๐ If a sender includes a PW type in this list, it takes full responsibility for supporting that payload. That includes any payload-specific AVPs, the L2-Specific Sublayer, or control messages defined in the companion document ๐ซถ
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit SHOULD be set to 1, but MAY vary (see Section 5.2). The Length before hiding is 8 octets with one PW type specified, plus 2 octets for each additional PW type ๐
Preferred Language (SCCRQ, SCCRP) ๐
The Preferred Language AVP, Attribute Type 72, lets an LCCE tell its peer which language the human-readable messages it sends SHOULD be composed in ๐ฃ๏ธ This AVP holds a single language tag or language range [RFC3066].
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Preferred Language... (arbitrary number of octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Preferred Language is the indicated number of octets representing the language tag or language range, encoded in the US-ASCII charset ๐ค
Sending this AVP is totally optional ๐ If (1) an LCCE doesn't signal a language preference by including this AVP in the SCCRQ or SCCRP, (2) the Preferred Language AVP isn't recognized, or (3) the requested language isn't supported by the peer LCCE, then the default language [RFC2277] MUST be used for all internationalized strings sent by the peer ๐ธ
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit SHOULD be set to 0, but MAY vary (see Section 5.2). The Length before hiding is 6 plus the length of the Preferred Language โจ
5.4.4. Session Management AVPs ๐ง
Local Session ID (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN, CDN, WEN, SLI) ๐ฆ
The Local Session ID AVP (basically the L2TPv2 Assigned Session ID's glow-up ๐), Attribute Type 63, holds the identifier the sender is assigning to this session.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Local Session ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Local Session ID is a 4-octet non-zero unsigned integer. This AVP sets up the two identifiers used to multiplex and demultiplex sessions between two LCCEs ๐ฏ Each LCCE picks any free value it wants and sends it to the remote LCCE using this AVP. The remote LCCE MUST then send all data packets for this session using this value. Also, for every session-oriented control message sent after this AVP is received (like ICRP, ICCN, CDN, SLI, etc.), the remote LCCE MUST echo this value in the Remote Session ID AVP ๐
Heads up: a Session ID is unidirectional ๐ Since each LCCE chooses its own Session ID independently of its peer, the value does NOT have to match in each direction for a given session. See Section 4.1 for more on the Session ID.
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit SHOULD be set to 1, but MAY vary (see Section 5.2). The Length before hiding is 10 ๐
Remote Session ID (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN, CDN, WEN, SLI) ๐
The Remote Session ID AVP, Attribute Type 64, holds the identifier that the peer assigned to this session ๐ซถ
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Remote Session ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Remote Session ID is a 4-octet non-zero unsigned integer. This AVP MUST be present in all session-level control messages ๐ฃ Its value echoes the session identifier the peer advertised through the Local Session ID AVP. It's the same value this side uses in all of its transmitted data messages for the session. Most of the time that identifier is enough for the peer to look up the session-level context for this control message ๐
If a session-level control message has to go to the peer before the Local Session ID AVP has been received, the Remote Session ID AVP MUST be set to zero ๐ญ On top of that, the Local Session ID AVP (sent in an earlier control message for this session) MUST be included in the control message. The peer must then use the Local Session ID AVP to do a reverse lookup and find its session context ๐งฉ The session-level control messages in this document that might get a reverse lookup from the receiving peer are the CDN, WEN, and SLI ๐
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit SHOULD be set to 1, but MAY vary (see Section 5.2). The Length before hiding is 10 โจ
Assigned Cookie (ICRQ, ICRP, OCRQ, OCRP) ๐ช
The Assigned Cookie AVP, Attribute Type 65, holds the Cookie value the sender is assigning to this session ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Assigned Cookie (32 or 64 bits) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Assigned Cookie is a 4-octet or 8-octet random value. This AVP holds the value used to check that a received data message really belongs to the session identified by the Session ID ๐ All data messages sent to a peer MUST use the Assigned Cookie that the peer sent in this AVP. The length of the value (0, 32, or 64 bits) comes from the length of the AVP ๐
If the Assigned Cookie AVP is missing, or the Assigned Cookie Value has zero length, then the Cookie field should not be present in any data packets sent to the LCCE that sent this AVP ๐ โโ๏ธ For more on the Assigned Cookie, see Section 4.1.
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit SHOULD be set to 1, but MAY vary (see Section 5.2). The Length before hiding may be 6, 10, or 14 octets ๐
Serial Number (ICRQ, OCRQ) ๐ข
Okay so the Serial Number AVP (Attribute Type 15) ๐ขโจ is basically a little ID tag that the LAC or LNS slaps on each session, so admins on both ends have something easy to point at when a session goes sideways ๐ญ. Think shared "this one, bestie" label.
The Attribute Value field looks like this ๐:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Serial Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Serial Number is a 32-bit value ๐ . It's meant to be super easy for admins on both sides of a control connection to reference when they're debugging session failures ๐. Serial Numbers should be set to progressively increasing values, which are likely to stay unique for a long time across all the interconnected LNSs and LACs. Very organized, very iconic. ๐ธ
Quick throwback ๐ฐ๏ธ: in RFC 2661, this was called the "Call Serial Number AVP." Same purpose, same attribute value, same composition, just a new name.
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP SHOULD be set to 0, but MAY vary (see Section 5.2). The Length (before hiding) of this AVP is 10.
Remote End ID (ICRQ, OCRQ)
The Remote End ID AVP (Attribute Type 66) ๐ฆ holds an identifier that binds L2TP sessions to a given circuit, interface, or bridging instance. It can also help detect session-level ties ๐.
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Remote End Identifier ... (arbitrary number of octets)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Remote End Identifier field is variable-length, and its value is unique for a given LCCE peer, as described in Section 3.3 ๐งฉ.
A session-level tie is detected if an LCCE receives an ICRQ or OCRQ whose End ID AVP matches the value it just sent in an outgoing ICRQ or OCRQ to the same peer. If the two values match, the LCCE knows a tie exists, meaning both LCCEs are trying to set up sessions for the same circuit ๐ญ. The tie gets broken by the Session Tie Breaker AVP.
By default, the LAC-LAC cross-connect application (see Section 2(b)) of L2TP over an IP network MUST use the Router ID AVP and Remote End ID AVP to associate a circuit with an L2TP session. Other AVPs MAY be used for LCCE or circuit identification as specified in companion documents. ๐
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length (before hiding) of this AVP is 6 plus the length of the Remote End Identifier value.
Session Tie Breaker (ICRQ, OCRQ)
The Session Tie Breaker AVP (Attribute Type 5) is the tiebreaker ๐ for when two peers try to establish a session for the same circuit at the same time.
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Session Tie Breaker Value ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... (64 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Session Tie Breaker Value is an 8-octet random value ๐ฒ used to choose a session when two LCCEs request one for the same circuit at once. A tie is detected by looking at the peer's identity (described in Section 3.3) plus the per-session shared value sent via the End ID AVP. When there's a tie, the recipient of an ICRQ or OCRQ MUST compare the tie breaker value it received with the one it sent earlier. The LCCE with the lower value "wins" and MUST send a CDN with result code set to 13 (as defined in Section 5.4.2) in response to the losing ICRQ or OCRQ. If a tie is detected, both sides send tie breakers, and the values are equal, both sides MUST discard their sessions and restart session negotiation with new random tie breaker values ๐.
If a tie is detected but only one side sends a Session Tie Breaker AVP, the session initiator that included the AVP "wins" ๐ฅ. If neither side issues a tie breaker, then both sides MUST tear down the session ๐.
This AVP MUST NOT be hidden (the H bit MUST be 0). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length of this AVP is 14.
Pseudowire Type (ICRQ, OCRQ)
The Pseudowire Type (PW Type) AVP (Attribute Type 68) tells you the L2 payload type of the packets that will be tunneled using this L2TP session ๐ง.
The Attribute Value field for this AVP has the following format:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PW Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
A peer MUST NOT request an incoming or outgoing call with a PW Type AVP specifying a value that wasn't advertised in the PW Capabilities List AVP it received during control connection establishment ๐ซ. Attempts to do so MUST result in the call being rejected via a CDN with the Result Code set to 14 (see Section 5.4.2).
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length (before hiding) of this AVP is 8.
L2-Specific Sublayer (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN)
The L2-Specific Sublayer AVP (Attribute Type 69) says whether the sender needs an L2-Specific Sublayer on all incoming data packets for this L2TP session, and what format it should be ๐งฑ.
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| L2-Specific Sublayer Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The L2-Specific Sublayer Type is a 2-octet unsigned integer, and this document defines these values:
0- There is no L2-Specific Sublayer present.1- The Default L2-Specific Sublayer (defined in Section 4.6) is used.
If this AVP is received with a value other than zero, the receiving LCCE MUST include the identified L2-Specific Sublayer in its outgoing data messages. If the AVP isn't received at all, it's assumed there's no sublayer present ๐คทโโ๏ธ.
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length (before hiding) of this AVP is 8.
Data Sequencing (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN)
The Data Sequencing AVP (Attribute Type 70) says the sender wants some or all of the data packets it receives to be sequenced ๐ข.
The Attribute Value field for this AVP has the following format:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data Sequencing Level |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Data Sequencing Level is a 2-octet unsigned integer showing how much of the incoming data traffic the sender of this AVP wants marked with sequence numbers. The defined levels are:
0- No incoming data packets require sequencing.1- Only non-IP data packets require sequencing.2- All incoming data packets require sequencing.
If a Data Sequencing Level of 0 is specified, there's no need to send packets with sequence numbers. If sequence numbers do get sent, they'll be ignored on receipt. If no Data Sequencing AVP is received, a Data Sequencing Level of 0 is assumed ๐.
If a Data Sequencing Level of 1 is specified, only non-IP traffic carried inside the tunneled L2 frame should get sequence numbers. Non-IP traffic here means any packets that can't be classified as IP within their own L2 framing (for example, a PPP control packet or NETBIOS frame encapsulated by Frame Relay before being tunneled). All traffic that can be classified as IP MUST be sent with no sequencing (i.e., the S bit in the L2-Specific Sublayer is set to zero). If a packet can't be classified at all (for example, because it was compressed or encrypted at layer 2), or if an implementation can't do that classification within L2 frames, all packets MUST be given sequence numbers (essentially falling back to a Data Sequencing Level of 2) ๐ง .
If a Data Sequencing Level of 2 is specified, all traffic MUST be sequenced ๐ถ.
Data sequencing may only be requested when there's an L2-Specific Sublayer present that can provide sequence numbers. If sequencing is requested without requesting an L2-Specific Sublayer AVP, the session MUST be disconnected with a Result Code of 15 (see Section 5.4.2) ๐ช.
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP SHOULD be set to 1, but MAY vary (see Section 5.2). The Length (before hiding) of this AVP is 8.
Tx Connect Speed (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN)
The Tx Connect Speed BPS AVP (Attribute Type 74) contains the speed of the facility picked for the connection attempt ๐๏ธ.
The Attribute Value field for this AVP has the following format:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Connect Speed in bps...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...Connect Speed in bps (64 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The Tx Connect Speed BPS is an 8-octet value giving the speed in bits per second. A value of zero means the speed can't be determined, or there's no physical point-to-point link ๐ซฅ.
When the optional Rx Connect Speed AVP is present, the value in this AVP is the transmit connect speed from the LAC's point of view (i.e., data flowing from the LAC to the remote system). When the optional Rx Connect Speed AVP is NOT present, the connection speed between the remote system and the LAC is assumed to be symmetric and is represented by the single value in this AVP โ๏ธ.
This AVP MAY be hidden (the H bit MAY be 0 or 1). The M bit for this AVP SHOULD be set to 0, but MAY vary (see Section 5.2). The Length (before hiding) of this AVP is 14.
Rx Connect Speed (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN)
The Rx Connect Speed AVP (Attribute Type 75) shows the speed of the connection from the LAC's point of view (i.e., data flowing from the remote system to the LAC) ๐ฅ.
The Attribute Value field for this AVP has the following format:
Okay bestie, the Connect Speed BPS AVP is the tail end of that diagram ๐. It's an 8-octet value that tells you the speed in bits per second. A value of zero is the special vibe: it means the speed is indeterminable or there's no physical point-to-point link ๐ซ .
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Connect Speed in bps...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...Connect Speed in bps (64 bits) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Seeing this AVP means the connection speed might be asymmetric compared to the transmit connect speed in the Tx Connect Speed AVP ๐ฆ. This one MAY be hidden (the H bit MAY be 0 or 1) ๐. The M bit SHOULD be 0, but it MAY vary (peek at Section 5.2 for the deets ๐ ). The Length before hiding is 14 ๐.
Physical Channel ID (ICRQ, ICRP, OCRP) ๐ธ
The Physical Channel ID AVP, Attribute Type 25, holds the vendor-specific physical channel number used for a call โจ.
The Attribute Value field for this AVP looks like this:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Physical Channel ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Physical Channel ID is a 4-octet value meant for logging purposes only ๐. This AVP MAY be hidden (the H bit MAY be 0 or 1) ๐. The M bit SHOULD be 0, but it MAY vary (see Section 5.2). The Length before hiding is 10 ๐.
5.4.5. Circuit Status AVPs ๐ฆ
Circuit Status (ICRQ, ICRP, ICCN, OCRQ, OCRP, OCCN, SLI) ๐
The Circuit Status AVP, Attribute Type 71, shows the initial status of a circuit (or a change in status) for the circuit the session is bound to ๐.
The Attribute Value field for this AVP looks like this:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |N|A|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
The A (Active) bit tells you if the circuit is up, active, or ready (1), or down, inactive, or not-ready (0) ๐ข๐ด.
The N (New) bit tells you if the circuit status is for a brand-new circuit (1) or an existing one (0) ๐. Links with a similar mechanism (like Frame Relay) MUST map this bit to their associated signaling ๐. Otherwise, the New bit SHOULD still be set the first time the L2TP session is established after provisioning ๐.
The remaining bits are reserved for future use. Reserved bits MUST be set to 0 when sending and ignored upon receipt ๐งน.
This AVP is how you advertise whether a circuit or interface bound to an L2TP session is up and ready to send and/or receive traffic ๐ฆ. Different circuit types have different names for their statuses ๐. For example, HDLC primary and secondary stations call a circuit "Receive Ready" or "Receive Not Ready", while Frame Relay calls it "Active" or "Inactive". This AVP goes with the latter terminology, though the concept stays the same no matter the PW type for the L2TP session โจ.
In the simplest case, the circuit is a single physical interface, port, or circuit, depending on the application and session setup ๐. The status here can then give you simple ILMI interworking for a variety of circuit types ๐งฉ. For virtual or multipoint interfaces, the Circuit Status AVP still gets used, but now it refers to the state of an internal structure or a logical set of circuits ๐. Each PW-specific companion document MUST specify precisely how this AVP is translated for each circuit type ๐.
If this AVP arrives with a Not Active notification for a given L2TP session, all data traffic for that session MUST cease (or not begin) in the direction of the sender of the Circuit Status AVP until the circuit is advertised as Active ๐.
The Circuit Status MUST be advertised by this AVP in ICRQ, ICRP, OCRQ, and OCRP messages ๐ฃ. Often the circuit type is marked Active when initiated, but it MAY later be advertised as Inactive ๐ฌ. That means an L2TP session is getting created, but the interface or circuit still isn't ready to pass traffic. The ICCN, OCCN, and SLI control messages all MAY contain this AVP to update the circuit status after the L2TP session establishment is requested ๐.
If a given PW type needs extra circuit status info, any new PW-specific AVPs MUST be defined in a separate document ๐. This AVP is only for general circuit status info that applies to all circuit and interface types ๐.
This AVP MAY be hidden (the H bit MAY be 0 or 1) ๐. The M bit SHOULD be set to 1, but it MAY vary (see Section 5.2). The Length before hiding is 8 โจ.
Circuit Errors (WEN) ๐จ
The Circuit Errors AVP, Attribute Type 34, passes circuit error info along to the peer ๐ฌ.
The Attribute Value field for this AVP looks like this:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Hardware Overruns |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Buffer Overruns |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timeout Errors |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Alignment Errors |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Here are the fields you get ๐ง:
- Reserved: 2 octets of Reserved data are there to give longword alignment within the AVP for the values that follow. Reserved data MUST be zero on sending and ignored upon receipt ๐งน.
- Hardware Overruns: the number of receive buffer overruns since the call was established ๐.
- Buffer Overruns: the number of buffer overruns detected since the call was established ๐.
- Timeout Errors: the number of timeouts since the call was established โฐ.
- Alignment Errors: the number of alignment errors since the call was established ๐.
This AVP MAY be hidden (the H bit MAY be 0 or 1) ๐. The M bit SHOULD be set to 0, but it MAY vary (see Section 5.2). The Length before hiding is 32 ๐.
6. Control Connection Protocol Specification ๐
The following control messages are used to establish, maintain, and tear down L2TP control connections ๐. All data packets are sent in network order (high-order octets first) ๐ข. Any "reserved" or "empty" fields MUST be sent as 0 values so the protocol can be extended later ๐งฉ.
The exchanges these messages are involved in are outlined in Section 3.3 ๐.
6.1. Start-Control-Connection-Request (SCCRQ) ๐
Start-Control-Connection-Request (SCCRQ) is a control message used to start a control connection between two LCCEs. Either the LAC or the LNS can send it to kick off the control connection establishment process ๐ค.
The following AVPs MUST be present in the SCCRQ:
- Message Type
- Host Name
- Router ID
- Assigned Control Connection ID
- Pseudowire Capabilities List
The following AVPs MAY be present in the SCCRQ:
- Random Vector
- Control Message Authentication Nonce
- Message Digest
- Control Connection Tie Breaker
- Vendor Name
- Receive Window Size
- Preferred Language
6.2. Start-Control-Connection-Reply (SCCRP) ๐
Start-Control-Connection-Reply (SCCRP) is the control message sent in reply to a received SCCRQ. The SCCRP says the SCCRQ was accepted and that establishing the control connection should keep going ๐ฅฐ.
The following AVPs MUST be present in the SCCRP:
- Message Type
- Host Name
- Router ID
- Assigned Control Connection ID
- Pseudowire Capabilities List
The following AVPs MAY be present in the SCCRP:
- Random Vector
- Control Message Authentication Nonce
- Message Digest
- Vendor Name
- Receive Window Size
- Preferred Language
6.3. Start-Control-Connection-Connected (SCCCN) โ
Start-Control-Connection-Connected (SCCCN) is the control message sent in reply to an SCCRP. The SCCCN wraps up the control connection establishment process ๐.
The following AVP MUST be present in the SCCCN:
- Message Type
The following AVPs MAY be present in the SCCCN:
- Random Vector
- Message Digest
6.4. Stop-Control-Connection-Notification (StopCCN) ๐
Stop-Control-Connection-Notification (StopCCN) is the control message either LCCE sends to tell its peer that the control connection is shutting down and should be closed ๐ค. On top of that, all active sessions are implicitly cleared, with no explicit session control messages sent ๐งน. The reason for the request is in the Result Code AVP ๐. There's no explicit reply to this message, just the implicit ACK from the reliable control message delivery layer ๐คซ.
The following AVPs MUST be present in the StopCCN:
- Message Type
- Result Code
The following AVPs MAY be present in the StopCCN:
- Random Vector
- Message Digest
- Assigned Control Connection ID
Note that the Assigned Control Connection ID MUST be present if the StopCCN is sent after an SCCRQ or SCCRP message has been sent ๐.
6.5. Hello (HELLO) ๐
The Hello (HELLO) message is an L2TP control message either peer of a control connection can send ๐ฌ. It works as a "keepalive" for the control connection, so you know your bestie is still there ๐ซถ. See Section 4.2 for how the keepalive mechanism works ๐.
HELLO messages are global to the control connection. The Session ID in a HELLO message MUST be 0 ๐ธ.
The following AVP MUST be present in the HELLO:
- Message Type
The following AVPs MAY be present in the HELLO:
- Random Vector
- Message Digest
6.6. Incoming-Call-Request (ICRQ) ๐โจ
Okay so the Incoming-Call-Request (ICRQ) is the message an LCCE sends to a peer when it spots an incoming call ๐ (though an ICRQ can also go out because of a local event, so it's not only for calls). It's the first of a three-message exchange for setting up a session over an L2TP control connection ๐ฆ
The ICRQ says "hey, we need a session between this LCCE and that peer" ๐ The sender hands over the session's parameter info, but it doesn't get bossy about how the peer ends the session. Whether the L2 traffic gets processed locally, forwarded, or something else is totally up to the peer ๐
These AVPs MUST be in the ICRQ:
- Message Type
- Local Session ID
- Remote Session ID
- Serial Number
- Pseudowire Type
- Remote End ID
- Circuit Status
These AVPs MAY be in the ICRQ:
- Random Vector
- Message Digest
- Assigned Cookie
- Session Tie Breaker
- L2-Specific Sublayer
- Data Sequencing
- Tx Connect Speed
- Rx Connect Speed
- Physical Channel ID
6.7. Incoming-Call-Reply (ICRP) ๐
The Incoming-Call-Reply (ICRP) is the LCCE's response to a received ICRQ ๐ It's the middle message in that three-message exchange for setting up sessions inside an L2TP control connection ๐ธ
The ICRP basically says "your ICRQ worked!" โจ It tells the peer it should go ahead and answer the incoming call if it hasn't already ๐ฒ The sender can also share specific parameters about the L2TP session here too ๐
These AVPs MUST be in the ICRP:
- Message Type
- Local Session ID
- Remote Session ID
- Circuit Status
These AVPs MAY be in the ICRP:
- Random Vector
- Message Digest
- Assigned Cookie
- L2-Specific Sublayer
- Data Sequencing
- Tx Connect Speed
- Rx Connect Speed
- Physical Channel ID
6.8. Incoming-Call-Connected (ICCN) ๐ฅณ
The Incoming-Call-Connected (ICCN) is sent by the same LCCE that originally sent the ICRQ, once it gets an ICRP back from its peer ๐ It's the last message in the three-message exchange for setting up L2TP sessions, so this is the big finish ๐
The ICCN is how the sender says "the ICRP was accepted, the call is connected, and the L2TP session should move to the established state" ๐ It can also share specific parameters about the established call, including ones that might not have been known when the ICRQ went out ๐ฅ
These AVPs MUST be in the ICCN:
- Message Type
- Local Session ID
- Remote Session ID
These AVPs MAY be in the ICCN:
- Random Vector
- Message Digest
- L2-Specific Sublayer
- Data Sequencing
- Tx Connect Speed
- Rx Connect Speed
- Circuit Status
6.9. Outgoing-Call-Request (OCRQ) ๐ค
The Outgoing-Call-Request (OCRQ) is sent by an LCCE to a LAC to say "please set up an outbound call" ๐ง It carries the specific destination info for that call, and it's the first of a three-message exchange for setting up a session and placing a call on behalf of the LCCE that started it ๐
Here's the tea: a call can be any L2 connection that needs well-known destination info sent from an LCCE to a LAC ๐ซถ That could be a dialup connection to the PSTN, an SVC connection, the IP address of another LCCE, or any other destination the sender decides on ๐
These AVPs MUST be in the OCRQ:
- Message Type
- Local Session ID
- Remote Session ID
- Serial Number
- Pseudowire Type
- Remote End ID
- Circuit Status
These AVPs MAY be in the OCRQ:
- Random Vector
- Message Digest
- Assigned Cookie
- Tx Connect Speed
- Rx Connect Speed
- Session Tie Breaker
- L2-Specific Sublayer
- Data Sequencing
6.10. Outgoing-Call-Reply (OCRP) ๐ท
The Outgoing-Call-Reply (OCRP) is the LAC's reply to a received OCRQ, sent back to the LCCE ๐จ It's the second message in a three-message exchange for setting up a session inside an L2TP control connection โจ
The OCRP says the LAC was able to try the outbound call ๐ It sends back any relevant parameters about that call attempt ๐ฆ Important bit, bestie: data MUST NOT be forwarded until the OCCN arrives, since that's what confirms the call has actually been placed ๐
These AVPs MUST be in the OCRP:
- Message Type
- Local Session ID
- Remote Session ID
- Circuit Status
These AVPs MAY be in the OCRP:
- Random Vector
- Message Digest
- Assigned Cookie
- L2-Specific Sublayer
- Tx Connect Speed
- Rx Connect Speed
- Data Sequencing
- Physical Channel ID
6.11. Outgoing-Call-Connected (OCCN) ๐ฅ
The Outgoing-Call-Connected (OCCN) is sent by a LAC to another LCCE after the OCRP goes out and the outgoing call is finished ๐ It's the final message in the three-message exchange for setting up a session ๐
The OCCN tells the LCCE that asked for the call that it worked ๐ It also shares info about the specific parameters the LAC got once the call was up ๐
These AVPs MUST be in the OCCN:
- Message Type
- Local Session ID
- Remote Session ID
These AVPs MAY be in the OCCN:
- Random Vector
- Message Digest
- L2-Specific Sublayer
- Tx Connect Speed
- Rx Connect Speed
- Data Sequencing
- Circuit Status
6.12. Call-Disconnect-Notify (CDN) ๐
The Call-Disconnect-Notify (CDN) is sent by an LCCE to ask for a specific session to be disconnected ๐ช Its whole job is to tell the peer that the session is ending and why ๐ The peer MUST clean up any resources, but it doesn't send back any success or failure indication for that cleanup ๐งน
These AVPs MUST be in the CDN:
- Message Type
- Result Code
- Local Session ID
- Remote Session ID
This AVP MAY be in the CDN:
- Random Vector
- Message Digest
6.13. WAN-Error-Notify (WEN) โ ๏ธ
The WAN-Error-Notify (WEN) is sent from a LAC to an LNS to report WAN error conditions ๐ฉ๏ธ The counters in this message are cumulative ๐ It should only be sent when an error actually happens, and not more than once every 60 seconds โฐ The counters get reset when a new call is established ๐
These AVPs MUST be in the WEN:
- Message Type
- Local Session ID
- Remote Session ID
- Circuit Errors
This AVP MAY be in the WEN:
- Random Vector
- Message Digest
6.14. Set-Link-Info (SLI) ๐
The Set-Link-Info control message is sent by an LCCE to share link or circuit status change info about the circuit tied to this L2TP session ๐ซ For example, if PPP renegotiates LCP at an LNS or between a LAC and a Remote System, or if a forwarded Frame Relay VC switches to Active or Inactive at a LAC, an SLI SHOULD be sent to flag that event ๐ฉ The precise details of when the SLI gets sent, which PW type-specific AVPs have to be there, and how the receiving peer should read those AVPs are outside the scope of this document ๐ โโ๏ธ Those details belong in the pseudowire-specific documents that need this message ๐
These AVPs MUST be in the SLI:
- Message Type
- Local Session ID
- Remote Session ID
These AVPs MAY be in the SLI:
- Random Vector
- Message Digest
- Circuit Status
6.15. Explicit-Acknowledgement (ACK) ๐ซก
The Explicit Acknowledgement (ACK) message is only used to acknowledge receipt of a message or messages on the control connection ๐ (for example, to update Ns and Nr values ๐ข) Getting one of these doesn't trigger an event for the L2TP protocol state machine ๐
A message with no AVPs at all (including no Message Type AVP) is called a Zero Length Body (ZLB) message ๐ซง It does the same job as the Explicit Acknowledgement โจ ZLB messages are only permitted when Control Message Authentication defined in Section 4.3 is not enabled ๐
These AVPs MAY be in the ACK message:
- Message Type
- Message Digest
7. Control Connection State Machines ๐ง
The state tables in this section control how control messages from Section 6 get exchanged ๐๏ธ There are tables for incoming call placement, outgoing call placement, and starting the control connection itself ๐ The state tables don't cover timeout and retransmission behavior, because that's handled by the underlying reliable control message delivery mechanism (see Section 4.2) ๐
7.1. Malformed AVPs and Control Messages ๐
Okay so if you get a control message that's invalid or too broken to fix (unrecoverable), you SHOULD log it properly ๐ and then clear the control connection so everyone's back on known, safe ground โจ. After that, the initiator may restart the control connection ๐.
An invalid control message is one that (1) has a Message Type marked as mandatory (see Section 5.4.1) but the implementation doesn't recognize it, or (2) shows up in the wrong state ๐.
Malformed control messages can look like (1) a message with an invalid value in its header, (2) a message with an AVP that's formatted wrong or has an out-of-range value, or (3) a message that's missing a required AVP ๐. A control message with a malformed header MUST be discarded ๐๏ธ.
When it's possible, a malformed AVP should be treated as an unrecognized AVP (see Section 5.2) ๐งฉ. So you SHOULD try to peek at the M bit to figure out how important the AVP is, and how bad the malformation is for the whole control message ๐. If you can reasonably read the M bit inside the malformed AVP and it's set, then just like with an unrecognized AVP, the session or control connection MUST be shut down ๐. If you read the M bit and it's 0, the AVP MUST be ignored (as long as recovering from the malformation is actually possible) ๐ซถ.
This policy must not be considered a license to send malformed AVPs ๐ซ. It's more of a guide for how to handle a badly formatted message if one shows up in your inbox ๐ฌ. Listing every possible malformation of a given message isn't possible, so no way are we giving advice for each one ๐ญ.
One malformed AVP situation that should be recoverable: the Rx Connect Speed AVP arrives with a length of 10 instead of 14, which means the connect speed bits-per-second is being formatted in 4 octets instead of 8 ๐ค. If the AVP doesn't have its M bit set (which is usually the case), it's not considered catastrophic ๐ธ. So the control message should be accepted as though the AVP weren't there (though a local error message may be logged) โจ.
In a bunch of the tables coming up, a protocol message gets sent and then a "clean up" happens ๐งน. Heads up: no matter who started destroying the control connection, the reliable delivery mechanism must be allowed to run (see Section 4.2) before the control connection gets destroyed ๐ซถ. That's how the control connection management messages actually make it to the peer ๐.
Appendix B.1 has an example of lock-step control connection establishment ๐ฆ.
7.2. Control Connection States ๐
Okay, so the L2TP control connection protocol can't tell the two LCCEs apart ๐, but it can tell the originator and the receiver apart ๐โโ๏ธ. The originating peer is the one that starts setting up the control connection first (and in a tie breaker situation, the one who wins the tie ๐). Since either the LAC or the LNS can be the originator, a collision can totally happen ๐ฅ. Check out the Control Connection Tie Breaker AVP in Section 5.4.3 for how that works and how it gets resolved ๐.
State Event Action New State
----- ----- ------ ---------
idle Local open Send SCCRQ wait-ctl-reply
request
idle Receive SCCRQ, Send SCCRP wait-ctl-conn
acceptable
idle Receive SCCRQ, Send StopCCN, idle
not acceptable clean up
idle Receive SCCRP Send StopCCN, idle
clean up
idle Receive SCCCN Send StopCCN, idle
clean up
wait-ctl-reply Receive SCCRP, Send SCCCN, established
acceptable send control-conn
open event to
waiting sessions
wait-ctl-reply Receive SCCRP, Send StopCCN, idle
not acceptable clean up
wait-ctl-reply Receive SCCRQ, Send SCCRP, wait-ctl-conn
lose tie breaker, Clean up losing
SCCRQ acceptable connection
wait-ctl-reply Receive SCCRQ, Send StopCCN, idle
lose tie breaker, Clean up losing
SCCRQ unacceptable connection
wait-ctl-reply Receive SCCRQ, Send StopCCN for wait-ctl-reply
win tie breaker losing connection
wait-ctl-reply Receive SCCCN Send StopCCN, idle
clean up
wait-ctl-conn Receive SCCCN, Send control-conn established
acceptable open event to
waiting sessions
wait-ctl-conn Receive SCCCN, Send StopCCN, idle
not acceptable clean up
wait-ctl-conn Receive SCCRQ, Send StopCCN, idle
SCCRP clean up
established Local open Send control-conn established
request open event to
(new call) waiting sessions
established Administrative Send StopCCN, idle
control-conn clean up
close event
established Receive SCCRQ, Send StopCCN, idle
SCCRP, SCCCN clean up
idle, Receive StopCCN Clean up idle
wait-ctl-reply,
wait-ctl-conn,
established
Here's what each state means for an LCCE during control connection establishment ๐ง:
idle: Both the initiator and the recipient start here ๐ฑ. The initiator sends an SCCRQ, while a recipient just chills in the idle state until it gets an SCCRQ ๐ค.wait-ctl-reply: The originator checks whether another connection has already been requested from the same peer. If it has, it handles the collision as described in Section 5.4.3 โ๏ธ.wait-ctl-conn: Waiting around for an SCCCN โณ. If the SCCCN is valid, the control connection is established ๐. If not, it gets torn down (sending a StopCCN with the proper result and/or error code) ๐ค.established: The connection can be terminated by a local condition or by receiving a StopCCN ๐. If it's a local termination, the originator MUST send a StopCCN and clean up the control connection ๐งน. If the originator gets a StopCCN, it MUST also clean up the control connection ๐ .
7.3. Incoming Calls ๐
An ICRQ is generated by an LCCE, usually because of an incoming call or a local event ๐ฒ. Once the LCCE sends the ICRQ, it waits for the peer to respond ๐. But it can choose to hold off on setting up the call (like answering it or bringing up the circuit) until the peer says with an ICRP that it'll accept the call ๐ซถ. The peer might decide not to accept the call if, for example, it doesn't have enough resources for one more session ๐ฌ.
If the peer does accept, it responds with an ICRP โ . When the local LCCE gets that ICRP, it tries to set up the call ๐ ๏ธ. Then a final call connected message, the ICCN, goes from the local LCCE to the peer, saying both LCCEs' call states should now be established ๐ฅณ. If the call gets terminated before the peer can accept it, the local LCCE sends a CDN to say so ๐ด.
When a call moves to a "disconnected" or "down" state, it gets cleared normally, and the local LCCE sends a CDN ๐งผ. Same deal if the peer wants to clear a call: it sends a CDN and cleans up its session ๐.
7.3.1. ICRQ Sender States ๐ฆ
State Event Action New State
----- ----- ------ ---------
idle Call signal or Initiate local wait-control-conn
ready to receive control-conn
incoming conn open
idle Receive ICCN, Clean up idle
ICRP, CDN
wait-control- Bearer line drop Clean up idle
conn or local close
request
wait-control- control-conn-open Send ICRQ wait-reply
conn
wait-reply Receive ICRP, Send ICCN established
acceptable
wait-reply Receive ICRP, Send CDN, idle
Not acceptable clean up
wait-reply Receive ICRQ, Process as idle
lose tie breaker ICRQ Recipient
(Section 7.3.2)
wait-reply Receive ICRQ, Send CDN wait-reply
win tie breaker for losing
session
wait-reply Receive CDN, Clean up idle
ICCN
wait-reply Local close Send CDN, idle
request clean up
established Receive CDN Clean up idle
established Receive ICRQ, Send CDN, idle
ICRP, ICCN clean up
established Local close Send CDN, idle
request clean up
Here's what the ICRQ sender's states mean ๐:
idle: The LCCE spots an incoming call on one of its interfaces (like an analog PSTN line ringing, or an ATM PVC getting provisioned), or some other local event happens ๐. The LCCE kicks off its control connection establishment state machine and moves to a state where it's waiting to confirm that a control connection exists ๐.wait-control-conn: The session is waiting for either the control connection to open or for a check that it's already open ๐. Once it hears the control connection has opened, session control messages can get exchanged ๐ฌ. The first one of those is the ICRQ ๐.wait-reply: The ICRQ sender gets either (1) a CDN saying the peer won't accept the call (general error or do not accept), so it goes back to idle ๐ โโ๏ธ, or (2) an ICRP saying the call is accepted ๐. In the second case, the LCCE sends an ICCN and enters the established state โจ.established: Data is flowing over the session ๐. The call can be cleared by any of these:- An event on the connected interface: the LCCE sends a CDN ๐ด.
- Receiving a CDN: the LCCE cleans up and disconnects the call ๐งน.
- A local reason: the LCCE sends a CDN ๐ .
7.3.2. ICRQ Recipient States โจ
okay bestie, this is the recipient side of an ICRQ, aka the receiving LCCE's little state diagram ๐ฆ here's the whole table:
State Event Action New State
----- ----- ------ ---------
idle Receive ICRQ, Send ICRP wait-connect
acceptable
idle Receive ICRQ, Send CDN, idle
not acceptable clean up
idle Receive ICRP Send CDN idle
clean up
idle Receive ICCN Clean up idle
wait-connect Receive ICCN, Prepare for established
acceptable data
wait-connect Receive ICCN, Send CDN, idle
not acceptable clean up
wait-connect Receive ICRQ, Send CDN, idle
ICRP clean up
idle, Receive CDN Clean up idle
wait-connect,
established
wait-connect Local close Send CDN, idle
request clean up
established Receive ICRQ, Send CDN, idle
ICRP, ICCN clean up
The states for the ICRQ recipient go like this ๐
idle An ICRQ comes in. If it's not acceptable, the local LCCE sends a CDN back to the peer LCCE and just chills in idle ๐ If the ICRQ is acceptable, it sends an ICRP and the session moves to wait-connect. ๐
wait-connect The local LCCE is waiting on an ICCN from the peer. Once that ICCN lands, it moves to established. ๐ธ
established The session gets terminated either by sending a CDN or by receiving one from the peer. Cleanup happens on both sides no matter who started it. the vibes are very "we're all in this together" ๐ซถ
7.4. Outgoing Calls ๐
okay so outgoing calls are how an LCCE tells an LAC to go place a call ๐ there are three messages for this: OCRQ, OCRP, and OCCN. the LCCE starts by sending an OCRQ to the LAC asking for an outgoing call. the LAC MUST respond to that OCRQ with an OCRP once it has figured out that the right facilities exist to place the call and the call is administratively authorized. ๐ then, once the outbound call is connected, the LAC sends an OCCN to the peer to tell it the final result of the call attempt. the whole thing is giving "send, confirm, announce the result" ๐ฅ
7.4.1. OCRQ Sender States โจ
State Event Action New State
----- ----- ------ ---------
idle Local open Initiate local wait-control-conn
request control-conn-open
idle Receive OCCN, Clean up idle
OCRP
wait-control- control-conn-open Send OCRQ wait-reply
conn
wait-reply Receive OCRP, none wait-connect
acceptable
wait-reply Receive OCRP, Send CDN, idle
not acceptable clean up
wait-reply Receive OCCN Send CDN, idle
clean up
wait-reply Receive OCRQ, Process as idle
lose tie breaker OCRQ Recipient
(Section 7.4.2)
wait-reply Receive OCRQ, Send CDN wait-reply
win tie breaker for losing
session
wait-connect Receive OCCN none established
wait-connect Receive OCRQ, Send CDN, idle
OCRP clean up
idle, Receive CDN Clean up idle
wait-reply,
wait-connect,
established
established Receive OCRQ, Send CDN, idle
OCRP, OCCN clean up
wait-reply, Local close Send CDN, idle
wait-connect, request clean up
established
wait-control- Local close Clean up idle
conn request
The states for the OCRQ sender are like a little journey ๐ง
idle, wait-control-conn When an outgoing call request kicks off, a control connection gets created (as described above) if there isn't one already. Once that control connection is up, an OCRQ goes out to the LAC and the session moves into wait-reply. ๐ฆ
wait-reply If a CDN shows up, the session gets cleaned up and goes back to idle. ๐ If an OCRP shows up instead, the call is in progress and the session moves to wait-connect. โจ
wait-connect If a CDN shows up, the session gets cleaned up and goes back to idle. If an OCCN shows up, the call succeeded and the session can now exchange data. ๐
established If a CDN shows up, the session gets cleaned up and goes back to idle. Or, if the LCCE decides it wants to end the session, it sends a CDN to the LAC, cleans up, and moves to idle. ๐
7.4.2. OCRQ Recipient (LAC) States ๐
State Event Action New State
----- ----- ------ ---------
idle Receive OCRQ, Send OCRP, wait-cs-answer
acceptable Place call
idle Receive OCRQ, Send CDN, idle
not acceptable clean up
idle Receive OCRP Send CDN, idle
clean up
idle Receive OCCN, Clean up idle
CDN
wait-cs-answer Call placement Send OCCN established
successful
wait-cs-answer Call placement Send CDN, idle
failed clean up
wait-cs-answer Receive OCRQ, Send CDN, idle
OCRP, OCCN clean up
established Receive OCRQ, Send CDN, idle
OCRP, OCCN clean up
wait-cs-answer, Receive CDN Clean up idle
established
wait-cs-answer, Local close Send CDN, idle
established request clean up
The states for the LAC on outgoing calls are these ๐
idle If the OCRQ was received in error, respond with a CDN. Otherwise, place the call, send an OCRP, and move to wait-cs-answer. ๐ฒ
wait-cs-answer If the call doesn't get completed, or a timer runs out while waiting for it to complete, send a CDN with the right error condition set and go back to idle. ๐ญ If a circuit-switched connection gets established, send an OCCN saying success and go to established. ๐
established If the LAC gets a CDN from the peer, the call MUST be released through the appropriate mechanisms and the session gets cleaned up. Also, if the call gets disconnected because the circuit transitions to a "disconnected" or "down" state, the LAC MUST send a CDN to the peer and return to idle. no cap, both of those are musts ๐ฅ
7.5. Termination of a Control Connection ๐
a control connection gets terminated when either peer issues a StopCCN ๐ the sender of that message SHOULD wait a full control message retransmission cycle (for example, 1 + 2 + 4 + 8 ... seconds) for the acknowledgment before releasing the control information tied to the control connection. the recipient of the StopCCN should send an acknowledgment back to the peer and then release the associated control information. โจ
when to release a control connection is an implementation issue and this document doesn't specify it ๐ each implementation can use whatever policy makes sense for deciding. some might keep a control connection open for a while, or even indefinitely, after the last session on it is cleared. others might disconnect right after the last call on the control connection goes down. it's giving "your call, bestie" ๐ฆ
8. Security Considerations ๐
this section covers some of the security issues L2TP runs into when it's operating ๐
8.1. Control Connection Endpoint and Message Security ๐ก๏ธ
if a shared secret (password) exists between two LCCEs, it may be used to do a mutual authentication between them, and to build an authentication and integrity check for arriving L2TP control messages. the mechanism provided by L2TPv3 is described in Section 4.3 and in the definitions of the Message Digest and Control Message Authentication Nonce AVPs in Section 5.4.1. ๐
this control message security mechanism gives you two things: (1) mutual endpoint authentication, and (2) individual control message integrity and authenticity checking. mutual endpoint authentication makes sure an L2TPv3 control connection only gets established between two endpoints that are configured with the proper password ๐ the individual control message and integrity check guards against accidental or intentional packet corruption (meaning corruption caused by a control message spoofing or man-in-the-middle attack). this is the serious part, bestie, so pay attention ๐
the shared secret used for all control connection, control message, and AVP security features in this document never needs to be sent in the clear between L2TP tunnel endpoints. โจ๐ซถ
8.2. Data Packet Spoofing ๐ต๏ธโโ๏ธ
Okay so packet spoofing for any VPN protocol is a HUGE deal, bestie ๐ญ. If someone sneaks carefully made rogue packets into the VPN transit network, it could break VPN traffic separation and leak data into a customer VPN ๐. The scary part is that the VPN operator might not even realize their network has become a transit point into or between customer VPNs ๐.
L2TPv3 keeps its VPNs separated with a 32-bit Session ID in the L2TPv3 data header ๐. When it's present, the L2TPv3 Cookie (described in Section 4.1) adds an extra check that an arriving packet is meant for the identified session โจ. So using a Cookie alongside the Session ID gives you an extra guarantee that the Session ID lookup was done properly and that the Session ID didn't get corrupted in transit ๐ซถ.
In the case of a blind packet spoofing attack, the Cookie can also protect against frames accidentally leaking into a customer VPN ๐ฆ. Think of it like this: checking a 64-bit Cookie is kind of like checking whether a packet matches a given source and destination IP address pair ๐. Both are quick checks on cleartext header info for every arriving packet. BUT since L2TPv3 uses its own value, you don't have to keep a list of (possibly several) allowed or denied IP addresses, and you don't have to hide that list from hackers who might get it and spoof those addresses ๐ โโ๏ธ. Also, it's way easier to change a compromised L2TPv3 Cookie than a compromised IP address, and a cryptographically random [RFC1750] value is much less likely to get brute-forced than an IP address ๐ฅ.
For protection against brute-force, blind, insertion attacks, a 64-bit Cookie MUST be used with all sessions. ๐จ A 32-bit Cookie can be brute-force guessed at high packet rates, so it should not be considered an effective barrier to blind insertion attacks ๐. It's still useful as an extra check that a Session ID lookup worked, though ๐ง. The Cookie gives zero protection against a sophisticated man-in-the-middle attacker who can sniff and correlate captured data between nodes for a coordinated attack ๐ค.
The Assigned Cookie AVP is how the Cookie's value and size get signaled for a given session, and that Cookie has to show up in every data packet for that session ๐ฆ. Each Assigned Cookie MUST be selected in a cryptographically random manner [RFC1750] so that a series of Assigned Cookies doesn't give away what a future Cookie will be ๐ฎ.
โ ๏ธ The L2TPv3 Cookie must not be regarded as a substitute for security such as IPsec when you're operating over an open or untrusted network, where packets can be sniffed, decoded, and correlated for a coordinated attack. It is NOT a replacement for real security, bestie. See Section 4.1.3 for more on running L2TP over IPsec ๐.
9. Internationalization Considerations ๐
The Host Name and Vendor Name AVPs aren't internationalized ๐. The Vendor Name AVP is meant to be human-readable, but it kinda fits the category of "globally visible names" [RFC2277], so it's represented in US-ASCII ๐ค.
If (1) an LCCE doesn't signify a language preference by including a Preferred Language AVP (see Section 5.4.3) in the SCCRQ or SCCRP, (2) the Preferred Language AVP isn't recognized, or (3) the requested language isn't supported by the peer LCCE, the default language [RFC2277] MUST be used for all internationalized strings sent by the peer. ๐ซถ
10. IANA Considerations ๐
This document defines a bunch of "magic" numbers that IANA has to maintain ๐ช. This section explains how IANA assigns extra numbers in each of these lists ๐ . The subsections below describe the assignment policy for the namespaces defined elsewhere in this document โจ.
Sections 10.1 through 10.3 are requests for new values that IANA already manages under [RFC3438] ๐. The rest are for brand new registries that get added to the existing L2TP registry and are maintained by IANA too ๐ธ.
10.1. Control Message Attribute Value Pairs (AVPs) ๐
This number space is managed by IANA as per [RFC3438] ๐.
Here's a summary of the new AVPs:
Control Message Attribute Value Pairs
Attribute
Type Description
--------- ------------------
58 Extended Vendor ID AVP
59 Message Digest
60 Router ID
61 Assigned Control Connection ID
62 Pseudowire Capabilities List
63 Local Session ID
64 Remote Session ID
65 Assigned Cookie
66 Remote End ID
68 Pseudowire Type
69 L2-Specific Sublayer
70 Data Sequencing
71 Circuit Status
72 Preferred Language
73 Control Message Authentication Nonce
74 Tx Connect Speed
75 Rx Connect Speed
10.2. Message Type AVP Values ๐
This number space is also managed by IANA as per [RFC3438] ๐. There's one new message type, defined in Section 3.1, that was allocated for this spec:
Message Type AVP (Attribute Type 0) Values
------------------------------------------
Control Connection Management
20 (ACK) Explicit Acknowledgement
10.3. Result Code AVP Values ๐ท๏ธ
This number space is managed by IANA as per [RFC3438] ๐ .
New Result Code values for the CDN message are defined in Section 5.4. Here's the summary:
Result Code AVP (Attribute Type 1) Values
-----------------------------------------
General Error Codes
13 - Session not established due to losing
tie breaker (L2TPv3).
14 - Session not established due to unsupported
PW type (L2TPv3).
15 - Session not established, sequencing required
without valid L2-Specific Sublayer (L2TPv3).
16 - Finite state machine error or timeout.
10.4. AVP Header Bits ๐งฉ
This is a new registry for IANA to maintain ๐.
There are six bits at the very start of the L2TP AVP header โจ. New bits get assigned via Standards Action [RFC2434].
Leading Bits of the L2TP AVP Header
-----------------------------------
Bit 0 - Mandatory (M bit)
Bit 1 - Hidden (H bit)
Bit 2 - Reserved
Bit 3 - Reserved
Bit 4 - Reserved
Bit 5 - Reserved
10.5. L2TP Control Message Header Bits ๐ฆ
This is a new registry for IANA to maintain ๐.
There are 12 bits at the beginning of the L2TP Control Message Header ๐ท. Reserved bits should only be defined by Standard Action [RFC2434].
Leading Bits of the L2TP Control Message Header
-----------------------------------------------
Bit 0 - Message Type (T bit)
Bit 1 - Length Field is Present (L bit)
Bit 2 - Reserved
Bit 3 - Reserved
Bit 4 - Sequence Numbers Present (S bit)
Bit 5 - Reserved
Bit 6 - Offset Field is Present [RFC2661]
Bit 7 - Priority Bit (P bit) [RFC2661]
Bit 8 - Reserved
Bit 9 - Reserved
Bit 10 - Reserved
Bit 11 - Reserved
10.6. Pseudowire Types ๐ง
This is a new registry for IANA to maintain, and there are no values assigned within this document to maintain ๐ซง.
The Pseudowire Type (PW Type, see Section 5.4) is a 2-octet value used in the Pseudowire Type AVP and Pseudowire Capabilities List AVP defined in Section 5.4.3 ๐. Values 0 to 32767 are assignable by Expert Review [RFC2434], while 32768 to 65535 are assigned on a First Come First Served policy [RFC2434] ๐โโ๏ธ. No specific pseudowire types are assigned within this document. Each pseudowire-specific document must allocate its own PW types from IANA as necessary ๐.
L2TPv3 Pseudowire Types
-----------------------
10.7. Circuit Status Bits ๐
This is a new registry for IANA to maintain ๐.
The Circuit Status field is a 16-bit mask, and the two low-order bits are assigned โจ. Additional bits may be assigned by IETF Consensus [RFC2434].
Circuit Status Bits
-------------------
Bit 14 - New (N bit)
Bit 15 - Active (A bit)
10.8. Default L2-Specific Sublayer Bits ๐
This is a new registry for IANA to maintain ๐.
The Default L2-Specific Sublayer has 8 bits in the low-order portion of the header ๐ธ. Reserved bits may be assigned by IETF Consensus [RFC2434].
Default L2-Specific Sublayer Bits
---------------------------------
Bit 0 - Reserved
Bit 1 - Sequence (S bit)
Bit 2 - Reserved
Bit 3 - Reserved
Bit 4 - Reserved
Bit 5 - Reserved
Bit 6 - Reserved
Bit 7 - Reserved
10.9. L2-Specific Sublayer Type ๐ง
This is a new registry for IANA to maintain ๐.
The L2-Specific Sublayer Type is a 2-octet unsigned integer ๐ข. Additional values may be assigned by Expert Review [RFC2434].
L2-Specific Sublayer Type
-------------------------
0 - No L2-Specific Sublayer
1 - Default L2-Specific Sublayer present
10.10. Data Sequencing Level ๐
This is a new registry for IANA to maintain ๐.
The Data Sequencing Level is a 2-octet unsigned integer. Additional values may be assigned by Expert Review [RFC2434] ๐ซ.
Data Sequencing Level
---------------------
0 - No incoming data packets require sequencing.
1 - Only non-IP data packets require sequencing.
2 - All incoming data packets require sequencing.
11. References ๐
11.1. Normative References ๐
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2277] Alvestrand, H., "IETF Policy on Character Sets and
Languages", BCP 18, RFC 2277, January 1998.
[RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
IANA Considerations section in RFCs", BCP 26, RFC 2434,
October 1998.
[RFC2473] Conta, A. and S. Deering, "Generic Packet Tunneling in IPv6
Specification", RFC 2473, December 1998.
[RFC2661] Townsley, W., Valencia, A., Rubens, A., Pall, G., Zorn, G.,
and Palter, B., "Layer Two Tunneling Layer Two Tunneling
Protocol (L2TP)", RFC 2661, August 1999.
[RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson,
"Remote Authentication Dial In User Service (RADIUS)", RFC
2865, June 2000.
[RFC3066] Alvestrand, H., "Tags for the Identification of Languages",
BCP 47, RFC 3066, January 2001.
[RFC3193] Patel, B., Aboba, B., Dixon, W., Zorn, G., and Booth, S.,
"Securing L2TP using IPsec", RFC 3193, November 2001.
[RFC3438] Townsley, W., "Layer Two Tunneling Protocol (L2TP) Internet
Assigned Numbers Authority (IANA) Considerations Update",
BCP 68, RFC 3438, December 2002.
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646",
STD 63, RFC 3629, November 2003.
11.2. Informative References ๐
okay bestie, these are the reading-list ones ๐ Not required to build the thing, but they're the background drama that explains where the ideas came from. Here's the full list:
- [RFC1034] Mockapetris, P., "Domain Names - Concepts and Facilities", STD 13, RFC 1034, November 1987.
- [RFC1191] Mogul, J. and S. Deering, "Path MTU Discovery", RFC 1191, November 1990.
- [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.
- [RFC1661] Simpson, W., Ed., "The Point-to-Point Protocol (PPP)", STD 51, RFC 1661, July 1994.
- [RFC1700] Reynolds, J. and Postel, J., "Assigned Numbers", STD 2, RFC 1700, October 1994.
- [RFC1750] Eastlake, D., Crocker, S., and Schiller, J., "Randomness Recommendations for Security", RFC 1750, December 1994.
- [RFC1958] Carpenter, B., Ed., "Architectural Principles of the Internet", RFC 1958, June 1996.
- [RFC1981] McCann, J., Deering, S., and Mogul, J., "Path MTU Discovery for IP version 6", RFC 1981, August 1996.
- [RFC2072] Berkowitz, H., "Router Renumbering Guide", RFC 2072, January 1997.
- [RFC2104] Krawczyk, H., Bellare, M., and Canetti, R., "HMAC: Keyed-Hashing for Message Authentication", RFC 2104, February 1997.
- [RFC2341] Valencia, A., Littlewood, M., and Kolar, T., "Cisco Layer Two Forwarding (Protocol) L2F", RFC 2341, May 1998.
- [RFC2401] Kent, S. and Atkinson, R., "Security Architecture for the Internet Protocol", RFC 2401, November 1998.
- [RFC2581] Allman, M., Paxson, V., and Stevens, W., "TCP Congestion Control", RFC 2581, April 1999.
- [RFC2637] Hamzeh, K., Pall, G., Verthein, W., Taarud, J., Little, W., and Zorn, G., "Point-to-Point Tunneling Protocol (PPTP)", RFC 2637, July 1999.
- [RFC2732] Hinden, R., Carpenter, B., and Masinter, L., "Format for Literal IPv6 Addresses in URL's", RFC 2732, December 1999.
- [RFC2809] Aboba, B. and Zorn, G., "Implementation of L2TP Compulsory Tunneling via RADIUS", RFC 2809, April 2000.
- [RFC3070] Rawat, V., Tio, R., Nanji, S., and Verma, R., "Layer Two Tunneling Protocol (L2TP) over Frame Relay", RFC 3070, February 2001.
- [RFC3355] Singh, A., Turner, R., Tio, R., and Nanji, S., "Layer Two Tunnelling Protocol (L2TP) Over ATM Adaptation Layer 5 (AAL5)", RFC 3355, August 2002.
- [KPS] Kaufman, C., Perlman, R., and Speciner, M., "Network Security: Private Communications in a Public World", Prentice Hall, March 1995, ISBN 0-13-061466-1.
- [STEVENS] Stevens, W. Richard, "TCP/IP Illustrated, Volume I: The Protocols", Addison-Wesley Publishing Company, Inc., March 1996, ISBN 0-201-63346-9.
12. Acknowledgments โจ
okay the shoutouts ๐ซถ So a lot of the core L2TP constructs were originally in RFC 2661, "L2TPv2" ๐ That's where this doc's text started out. The RFC 2661 authors are W. Townsley, A. Valencia, A. Rubens, G. Pall, G. Zorn and B. Palter.
The basic concept for L2TP, plus lots of its protocol constructs, came from L2F [RFC2341] and PPTP [RFC2637]. The authors of those versions are A. Valencia, M. Littlewood, T. Kolar, K. Hamzeh, G. Pall, W. Verthein, J. Taarud, W. Little, and G. Zorn. Iconic lineup ๐
Danny Mcpherson and Suhail Nanji published the first "L2TP Service Type" version ๐, which defined using L2TP to tunnel different L2 payload types (initially, Ethernet and Frame Relay).
The team that split RFC 2661 into this base document and the companion PPP document was Ignacio Goyret, Jed Lau, Bill Palter, Mark Townsley, and Madhvi Verma. Skip Booth also gave super helpful review and comments ๐ธ
Some L2TPv3 constructs were partly based on UTI (Universal Transport Interface), which was originally conceived by Peter Lothberg and Tony Bates ๐ง
Stewart Bryant and Simon Barber gave valuable input for the L2TPv3 over IP header ๐ฆ
Juha Heinanen gave helpful review in the early stages of this effort ๐
Jan Vilhuber, Scott Fluhrer, David McGrew, Scott Wainner, Skip Booth and Maria Dos Santos contributed to the Control Message Authentication Mechanism, plus general security discussions ๐ฅ
James Carlson, Thomas Narten, Maria Dos Santos, Steven Bellovin, Ted Hardie, and Pekka Savola gave very helpful review of the final versions of the text ๐
Russ Housley gave valuable review and comments on security, especially for the Control Message Authentication mechanism ๐ซถ
Pekka Savola helped with proper alignment with IPv6 and inspired much of Section 4.1.4 on fragmentation ๐
Aside from his original influence and co-authorship of RFC 2661, Glen Zorn helped get all of the language and character references straight in this document ๐
A bunch of people gave valuable input and effort for RFC 2661, which this document was based on:
John Bray, Greg Burns, Rich Garrett, Don Grosser, Matt Holdrege, Terry Johnson, Dory Leifer, and Rich Shea gave valuable input and review at the 43rd IETF in Orlando, FL, which led to better readability and clarity of RFC 2661 โญ
Thomas Narten did a ton of critical review and formatting. He also wrote the first version of the IANA Considerations section ๐
Dory Leifer made valuable refinements to the protocol definition of L2TP and helped edit early versions leading to RFC 2661 ๐
Steve Cobb and Evan Caves redesigned the state machine tables. Barney Wolff gave a ton of design input on the original endpoint authentication mechanism ๐ง
Appendix A: Control Slow Start and Congestion Avoidance
okay so this appendix is the vibe check for control packets ๐ Even though each side has said how big its receive window is, it's RECOMMENDED-adjacent behaviour (it's "recommended", lowercase, no cap ๐) to use a slow start and congestion avoidance method when sending control packets. These methods are based on the TCP congestion avoidance algorithm from Section 21.6 of TCP/IP Illustrated, Volume I, by W. Richard Stevens [STEVENS] (this algorithm is also described in [RFC2581]).
Slow start and congestion avoidance use a few variables. The congestion window (CWND) is how many packets a sender can send before waiting for an acknowledgment ๐ฆ CWND grows and shrinks as described below. Important detail: CWND is never allowed to go past the advertised window from the Receive Window AVP โจ (in the text below, any increase is assumed to be limited by the Receive Window Size). The variable SSTHRESH decides when the sender switches from slow start to congestion avoidance. Slow start runs while CWND is less than SSHTRESH ๐
A sender starts in the slow start phase ๐ CWND gets set to one packet, and SSHTRESH is set to the advertised window (taken from the Receive Window AVP). The sender sends one packet and waits for its acknowledgment (either explicit or piggybacked). Once the ack comes back, the congestion window goes from one to two. During slow start, CWND goes up by one packet every time an ACK (explicit ACK message or piggybacked) arrives. Adding one per ACK basically doubles CWND every round trip, which is an exponential increase ๐ When CWND hits SSHTRESH, slow start ends and congestion avoidance begins.
During congestion avoidance, CWND grows way more slowly ๐ข Specifically, it goes up by 1/CWND for every new ACK received. So CWND goes up by one packet after CWND new ACKs have come in. Window expansion in this phase is effectively linear, with CWND going up by one packet each round trip.
When congestion happens (signalled by a retransmission being triggered) ๐ญ half of CWND gets saved in SSTHRESH, CWND is set to one, and the sender goes back into the slow start phase.
Appendix B: Control Message Examples
okay the examples are my favourite part, the diagrams are literally so clean ๐ง These show what the messages look like on the wire.
B.1: Lock-Step Control Connection Establishment
In this example, an LCCE sets up a control connection, and each side takes turns sending messages ๐ The final acknowledgment is sent explicitly inside an ACK message here. The alternative is to piggyback that acknowledgment onto a message sent back in reply to the ICRQ or OCRQ that will probably follow from the side that started the control connection ๐
LCCE A LCCE B
------ ------
SCCRQ ->
Nr: 0, Ns: 0
<- SCCRP
Nr: 1, Ns: 0
SCCCN ->
Nr: 1, Ns: 1
<- ACK
Nr: 2, Ns: 1
B.2: Lost Packet with Retransmission
Plot twist time ๐ฑ An existing control connection gets a new session requested by LCCE A. The ICRP gets lost, so LCCE B has to retransmit it. Note that losing the ICRP has two effects: it stops the upper-level state machine from moving forward, and it also keeps LCCE A from seeing a timely lower-level acknowledgment of its ICRQ ๐
LCCE A LCCE B
------ ------
ICRQ ->
Nr: 1, Ns: 2
(packet lost) <- ICRP
Nr: 3, Ns: 1
(pause; LCCE A's timer started first, so fires first)
ICRQ ->
Nr: 1, Ns: 2
(Realizing that it has already seen this packet,
LCCE B discards the packet and sends an ACK message)
<- ACK
Nr: 3, Ns: 2
(LCCE B's retransmit timer fires)
<- ICRP
Nr: 3, Ns: 1
ICCN ->
Nr: 2, Ns: 3
<- ACK
Nr: 4, Ns: 2
Appendix C: Processing Sequence Numbers โจ
okay bestie, the Default L2-Specific Sublayer from Section 4.6 gives you a 24-bit field to number the data packets in an L2TP session ๐ข๐. L2TP data packets are never retransmitted, so the sequence number is only there to help you spot packets that arrive out of order, duplicates, and lost packets. It's giving detective energy ๐ต๏ธโโ๏ธ
The 24-bit Sequence Number field holds the packet sequence number for the session ๐ฆ. Every sequenced data packet you send has to carry the number of the previous sequenced packet on that session, plus one. When a packet comes in, anything with a sequence number equal to or greater than the one you're expecting (the last in-order packet you got, plus one) should be considered "new" and accepted โ . Everything else is "old" or "duplicate" and gets tossed ๐๏ธ. Zero counts as a valid sequence number in the 24-bit space too, so you can use a masked 32-bit counter if that's your vibe ๐. Also, all new sessions MUST start sending sequence numbers at zero ๐ธ
Bigger or smaller sequence number fields are possible in L2TP if you use a different format from the Default L2-Specific Sublayer in this document ๐. 24 bits might be enough in plenty of situations, but a bigger space is way less likely to hit wrapping problems when you've got really high session data rates and long dropout periods ๐ . The sequence number recommendations below should hold for any field size, no cap ๐ซถ
Now, wrapping. When you're checking whether a sequence number is "greater" or "less" than another one, you MUST think about wrapping ๐ The usual move is to keep a window of sequence numbers past the current expected one, and use that to decide if a packet is "new" or not ๐ช. The window can be sized based on link speed and the sequence number space, and it SHOULD be configurable. The default is one half of the available number space, which is 2^(n-1), where n is the number of bits in the sequence number ๐งฎ (main character math, honestly ๐)
When a packet's number exactly matches the expected one, it gets processed right away and the next expected number goes up by one ๐ซ. Packets that land inside the new-packet window have two options. You can process them immediately and update the next expected number to one plus whatever number the new packet had. Or you can hold them for a very short time, hoping the missing packet(s) show up ๐ค. That "very short period" should be configurable, with a default that's at least an order of magnitude less than the retransmission timeout periods of higher layer protocols like TCP โฑ๏ธ (okay that's a lot of zeros, but the point is it has to be way shorter than TCP's patience ๐ญ)
For normal, transient out-of-order packets, just dropping them is usually enough, and it takes way fewer resources than actively reordering packets inside L2TP ๐ง The exception is when a pair of packet fragments keeps getting retransmitted and sent out of order ๐ For example, say an IP packet got fragmented into a very small packet followed by a very large packet before L2TP tunneled it. It's possible (though admittedly wrong) that those two L2TP packets keep getting mis-ordered by the PSN in transit between L2TP nodes ๐ If sequence numbers get enforced at the receiving node with no buffering of out-of-order packets, the fragmented IP packet might never reach its destination ๐ Worth noting that this is true for any IP tunneling mechanism that checks sequence numbers on receipt, like GRE [RFC2890] ๐ซ
Heads up: this is one of those "it works until it doesn't" situations, so be careful with sequence number enforcement on fragments ๐
Using a Data Sequencing Level of 1 (where only non-IP data packets require sequencing; see Section 5.4.3) lets IP data packets tunneled by L2TP skip sequence numbers ๐ฏ Meanwhile, the remaining non-IP data packets still get sequence numbers and enforced packet order. Depending on what the tunneled link layer needs and what network data is moving across it, this is enough in many cases to enforce order on the frames that need it (like end-to-end data link control messages), without doing it to IP packets that are known to be resilient to reordering ๐
Last but not least, the big outage situation ๐ฑ. If a large number of packets (more than one new packet window's worth) get dropped due to an extended outage or loss of sequence number state on one side of the connection (maybe during a forwarding plane reset or a failover to a standby node), then a bunch of packets might be sent in order but get wrongly flagged by the peer as out of order ๐ This can be generally characterized for a window size w, sequence number space s, and number of packets lost in transit between L2TP endpoints p, like this:
If s > p > w, then an additional (s - p) packets that were otherwise received in order will be incorrectly classified as out of order and dropped ๐
So for a sequence number space s = 128, window size w = 64, and number of lost packets p = 70, that's 128 - 70 = 58 additional packets dropped after the outage, until the sequence number wrapped back around to the current expected next sequence number ๐ฉ
To fix this extra packet loss, one MUST inspect the sequence numbers of packets dropped for being classified as "old" and reset the expected sequence number accordingly ๐ง You can do this by counting the "old" packets that were in sequence among themselves and, once you hit a threshold, resetting the next expected sequence number to the one seen in the arriving data packets ๐ฏ Packet timestamps can also be used as a signal to reset the expected sequence number, by detecting a period of time over which "old" packets have been received in sequence โฐ The ideal thresholds depend on link speed, sequence number space, and how much the link can tolerate out-of-order packets, and they MUST be configurable โจ
Editors' Addresses ๐
Jed Lau
cisco Systems
170 W. Tasman Drive
San Jose, CA 95134
EMail: jedlau@cisco.com
W. Mark Townsley
cisco Systems
EMail: mark@townsley.net
Ignacio Goyret
Lucent Technologies
EMail: igoyret@lucent.com
Full Copyright Statement ๐
Copyright (C) The Internet Society (2005) ๐ธ
This document is subject to the rights, licenses, and restrictions in BCP 78. Except as set out there, the authors keep all their rights ๐ฆ
This document and the info in it are provided on an "AS IS" basis, and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ๐
Intellectual Property ๐งพ
The IETF takes no position on whether any Intellectual Property Rights or other rights that someone might claim over the technology in this document are valid or in scope, or on whether licenses under those rights might be available ๐คทโโ๏ธ It also doesn't claim to have made any independent effort to find such rights. Info on how rights work for RFC documents is in BCP 78 and BCP 79 ๐
Copies of IPR disclosures made to the IETF Secretariat, any assurances of licenses that will be made available, and the results of any attempt to get a general license or permission for implementers or users of this specification can be found in the IETF online IPR repository at http://www.ietf.org/ipr ๐
The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology needed to implement this standard. Send that info to the IETF at ietf-ipr@ietf.org ๐
Acknowledgement ๐ซถ
Funding for the RFC Editor function is currently provided by the Internet Society ๐โจ
๐ฆ where this page comes from
- ietf: rfc3931 2005-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms