Thread (35 messages) 35 messages, 5 authors, 2020-02-03

Re: [PATCH net] l2tp: Allow duplicate session creation with UDP

From: Guillaume Nault <hidden>
Date: 2020-01-17 13:43:36

On Thu, Jan 16, 2020 at 09:05:01PM +0000, Tom Parkin wrote:
On  Thu, Jan 16, 2020 at 20:28:27 +0100, Guillaume Nault wrote:
quoted
On Thu, Jan 16, 2020 at 12:31:43PM +0000, Tom Parkin wrote:
quoted
However, there's nothing to prevent user space from using the same UDP
port for multiple tunnels, at which point this relaxation of the RFC
rules would break down again.
Multiplexing L2TP tunnels on top of non-connected UDP sockets might be
a nice optimisation for someone using many tunnels (like hundred of
thouthands), but I'm afraid the rest of the L2TP code is not ready to
handle such load anyway. And the current implementation only allows
one tunnel for each UDP socket anyway.
TBH I was thinking more of the case where multiple sockets are bound and
connected to the same address/port (SO_REUSEADDR).  There's still a
1:1 mapping of tunnel:socket, but it's possible to have packets for tunnel
A arrive on tunnel B's socket and vice versa.

It's a bit of a corner case, I grant you.
Creating several sockets to handle the same tunnel (as identified by
its 5-tuple) may be doable with SO_REUSEPORT, with an ebpf program to
direct the packet to the right socket depending on the session ID. The
session ID would be local to the so_reuseport group. So I guess that
even this kind of setup can be achieved with non-global session IDs (I
haven't tried though, so I might have missed something).
quoted
quoted
Since UDP-encap can also be broken in the face of duplicated L2TPv3
session IDs, I think its better that the kernel continue to enforce
the RFC.
How is UDP-encap broken with duplicate session IDs (as long as a UDP
socket can only one have one tunnel associated with it and that no
duplicate session IDs are allowed inside the same tunnel)?

It all boils down to what's the scope of a session ID. For me it has
always been the parent tunnel. But if that's in contradiction with
RFC 3931, I'd be happy to know.
For RFC 2661 the session ID is scoped to the tunnel.  Section 3.1
says:

  "Session ID indicates the identifier for a session within a tunnel."

Control and data packets share the same header which includes both the
tunnel and session ID with 16 bits allocated to each.  So it's always
possible to tell from the data packet header which tunnel the session is
associated with.

RFC 3931 changed the scheme.  Control packets now include a 32-bit
"Control Connection ID" (analogous to the Tunnel ID).  Data packets
have a session header specific to the packet-switching network in use:
the RFC describes schemes for both IP and UDP, both of which employ a
32-bit session ID.  Section 4.1 says:

  "The Session ID alone provides the necessary context for all further
  packet processing"

Since neither UDP nor IP encapsulated data packets include the control
connection ID, the session ID must be unique to the LCCE to allow
identification of the session.
Well my understanding was that the tunnel was implicitely given by the
UDP and IP headers. I don't think that multiplexing tunnels over the
same UDP connection made any sense with L2TPv2, and the kernel never
supported it natively (it might be possible with SO_REUSEPORT). Given
that the tunnel ID field was redundant with the lower headers, it made
sense to me that L2TPv3 dropped it (note that the kernel ignores the
L2TPv2 tunnel ID field on Rx). At least that was my understanding.

But as your quote says, the session ID _alone_ should provide all the
L2TP context. So I guess the spirit of the RFC is that there's a single
global namespace for session IDs. Now, practically speaking, I don't
see how scoped session IDs makes us incompatible, unless we consider
that a given session can be shared between several remote hosts (the
cross-talk case in my other email). Also, sharing a session over
several hosts would mean that L2TPv3 sessions aren't point-to-point,
which the control plane doesn't seem to take into account.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help