Re: [PATCH net-next v12 00/15] net: introduce QUIC infrastructure and core subcomponents

Xin Long <[email protected]> Tue, 2 Jun 2026 09:12:30 -0400
Newsgroups dev.linux.lists.kernel-tls-handshake,dev.linux.lists.quic,org.kernel.vger.linux-cifs,org.kernel.vger.netdev
Message-ID <CADvbK_fBbLCwY61HXsNeGCA8MhiBKcbvE0BvSZppohJgtXO+2g@mail.gmail.com>
On Sun, May 31, 2026 at 9:11 AM Xin Long <[email protected]> wrote:
>
> Introduction
> ============
>
> The QUIC protocol, defined in RFC 9000, is a secure, multiplexed transport
> built on top of UDP. It enables low-latency connection establishment,
> stream-based communication with flow control, and supports connection
> migration across network paths, while ensuring confidentiality, integrity,
> and availability.
>
> This implementation introduces QUIC support in Linux Kernel, offering
> several key advantages:
>
> - In-Kernel QUIC Support for Subsystems: Enables kernel subsystems
>   such as SMB and NFS to operate over QUIC with minimal changes. Once the
>   handshake is complete via the net/handshake APIs, data exchange proceeds
>   over standard in-kernel transport interfaces.
>
> - Standard Socket API Semantics: Implements core socket operations
>   (listen(), accept(), connect(), sendmsg(), recvmsg(), close(),
>   getsockopt(), setsockopt(), getsockname(), and getpeername()),
>   allowing user space to interact with QUIC sockets in a familiar,
>   POSIX-compliant way.
>
> - ALPN-Based Connection Dispatching: Supports in-kernel ALPN
>   (Application-Layer Protocol Negotiation) routing, allowing demultiplexing
>   of QUIC connections across different user-space processes based
>   on the ALPN identifiers.
>
> - Performance Enhancements: Handles all control messages in-kernel
>   to reduce syscall overhead, incorporates zero-copy mechanisms such as
>   sendfile() to minimize data movement, and is also structured to support
>   future crypto hardware offloads.
>
> This implementation offers fundamental support for the following RFCs:
>
> - RFC9000 - QUIC: A UDP-Based Multiplexed and Secure Transport
> - RFC9001 - Using TLS to Secure QUIC
> - RFC9002 - QUIC Loss Detection and Congestion Control
> - RFC9221 - An Unreliable Datagram Extension to QUIC
> - RFC9287 - Greasing the QUIC Bit
> - RFC9368 - Compatible Version Negotiation for QUIC
> - RFC9369 - QUIC Version 2
>
> The socket APIs for QUIC follow the RFC draft [1]:
>
> - The Sockets API Extensions for In-kernel QUIC Implementations
>
> Implementation
> ==============
>
> The central design is to implement QUIC within the kernel while delegating
> the handshake to userspace.
>
> Only the processing and creation of raw TLS Handshake Messages are handled
> in userspace, facilitated by a TLS library like GnuTLS. These messages are
> exchanged between kernel and userspace via sendmsg() and recvmsg(), with
> cryptographic details conveyed through control messages (cmsg).
>
> The entire QUIC protocol, aside from the TLS Handshake Messages processing
> and creation, is managed in the kernel. Rather than using an Upper Layer
> Protocol (ULP) layer, this implementation establishes a socket of type
> IPPROTO_QUIC (similar to IPPROTO_MPTCP), operating over UDP tunnels.
>
> For kernel consumers, they can initiate a handshake request from the kernel
> to userspace using the existing net/handshake netlink. The userspace
> component, such as tlshd service [2], then manages the processing
> of the QUIC handshake request.
>
> - Handshake Architecture:
>
>   ┌──────┐  ┌──────┐
>   │ APP1 │  │ APP2 │ ...
>   └──────┘  └──────┘
>   ┌──────────────────────────────────────────┐
>   │     {quic_client/server_handshake()}     │<─────────────┐
>   └──────────────────────────────────────────┘       ┌─────────────┐
>    {send/recvmsg()}      {set/getsockopt()}          │    tlshd    │
>    [CMSG handshake_info] [SOCKOPT_CRYPTO_SECRET]     └─────────────┘
>                          [SOCKOPT_TRANSPORT_PARAM_EXT]    │   ^
>                 │ ^                  │ ^                  │   │
>   Userspace     │ │                  │ │                  │   │
>   ──────────────│─│──────────────────│─│──────────────────│───│───────
>   Kernel        │ │                  │ │                  │   │
>                 v │                  v │                  v   │
>   ┌──────────────────┬───────────────────────┐       ┌─────────────┐
>   │ protocol, timer, │ socket (IPPROTO_QUIC) │<──┐   │ handshake   │
>   │                  ├───────────────────────┤   │   │netlink APIs │
>   │ common, family,  │ outqueue  |  inqueue  │   │   └─────────────┘
>   │                  ├───────────────────────┤   │      │       │
>   │ stream, connid,  │         frame         │   │   ┌─────┐ ┌─────┐
>   │                  ├───────────────────────┤   │   │     │ │     │
>   │ path, pnspace,   │         packet        │   │───│ SMB │ │ NFS │...
>   │                  ├───────────────────────┤   │   │     │ │     │
>   │ cong, crypto     │       UDP tunnels     │   │   └─────┘ └─────┘
>   └──────────────────┴───────────────────────┘   └──────┴───────┘
>
> - User Data Architecture:
>
>   ┌──────┐  ┌──────┐
>   │ APP1 │  │ APP2 │ ...
>   └──────┘  └──────┘
>    {send/recvmsg()}   {set/getsockopt()}              {recvmsg()}
>    [CMSG stream_info] [SOCKOPT_KEY_UPDATE]            [EVENT conn update]
>                       [SOCKOPT_CONNECTION_MIGRATION]  [EVENT stream update]
>                       [SOCKOPT_STREAM_OPEN/RESET/STOP]
>                 │ ^               │ ^                     ^
>   Userspace     │ │               │ │                     │
>   ──────────────│─│───────────────│─│─────────────────────│───────────
>   Kernel        │ │               │ │                     │
>                 v │               v │  ┌──────────────────┘
>   ┌──────────────────┬───────────────────────┐
>   │ protocol, timer, │ socket (IPPROTO_QUIC) │<──┐{kernel_send/recvmsg()}
>   │                  ├───────────────────────┤   │{kernel_set/getsockopt()}
>   │ common, family,  │ outqueue  |  inqueue  │   │{kernel_recvmsg()}
>   │                  ├───────────────────────┤   │
>   │ stream, connid,  │         frame         │   │   ┌─────┐ ┌─────┐
>   │                  ├───────────────────────┤   │   │     │ │     │
>   │ path, pnspace,   │         packet        │   │───│ SMB │ │ NFS │...
>   │                  ├───────────────────────┤   │   │     │ │     │
>   │ cong, crypto     │       UDP tunnels     │   │   └─────┘ └─────┘
>   └──────────────────┴───────────────────────┘   └──────┴───────┘
>
> Interface
> =========
>
> This implementation supports a mapping of QUIC into sockets APIs. Similar
> to TCP and SCTP, a typical Server and Client use the following system call
> sequence to communicate:
>
>     Client                             Server
>   ──────────────────────────────────────────────────────────────────────
>   sockfd = socket(IPPROTO_QUIC)      listenfd = socket(IPPROTO_QUIC)
>   bind(sockfd)                       bind(listenfd)
>                                      listen(listenfd)
>   connect(sockfd)
>   quic_client_handshake(sockfd)
>                                      sockfd = accept(listenfd)
>                                      quic_server_handshake(sockfd, cert)
>
>   sendmsg(sockfd)                    recvmsg(sockfd)
>   close(sockfd)                      close(sockfd)
>                                      close(listenfd)
>
> Please note that quic_client_handshake() and quic_server_handshake()
> functions are currently sourced from libquic [3]. These functions are
> responsible for receiving and processing the raw TLS handshake messages
> until the completion of the handshake process.
>
> For utilization by kernel consumers, it is essential to have tlshd
> service [2] installed and running in userspace. This service receives
> and manages kernel handshake requests for kernel sockets. In the kernel,
> the APIs closely resemble those used in userspace:
>
>     Client                             Server
>   ────────────────────────────────────────────────────────────────────────
>   __sock_create(IPPROTO_QUIC, &sock)  __sock_create(IPPROTO_QUIC, &sock)
>   kernel_bind(sock)                   kernel_bind(sock)
>                                       kernel_listen(sock)
>   kernel_connect(sock)
>   tls_client_hello_x509(args:{sock})
>                                       kernel_accept(sock, &newsock)
>                                       tls_server_hello_x509(args:{newsock})
>
>   kernel_sendmsg(sock)                kernel_recvmsg(newsock)
>   sock_release(sock)                  sock_release(newsock)
>                                       sock_release(sock)
>
> Please be aware that tls_client_hello_x509() and tls_server_hello_x509()
> are APIs from net/handshake/. They are used to dispatch the handshake
> request to the userspace tlshd service and subsequently block until the
> handshake process is completed.
>
> Use Cases
> =========
>
> - Samba
>
>   Stefan Metzmacher has integrated Linux QUIC into Samba for both client
>   and server roles [4].
>
> - tlshd
>
>   The tlshd daemon [2] facilitates Linux QUIC handshake requests from
>   kernel sockets. This is essential for enabling protocols like SMB
>   and NFS over QUIC.
>
> - curl
>
>   Linux QUIC is being integrated into curl [5] for HTTP/3. Example usage:
>
>   # curl --http3-only https://nghttp2.org:4433/
>   # curl --http3-only https://www.google.com/
>   # curl --http3-only https://facebook.com/
>   # curl --http3-only https://outlook.office.com/
>   # curl --http3-only https://cloudflare-quic.com/
>
> - httpd-portable
>
>   Moritz Buhl has deployed an HTTP/3 server over Linux QUIC [6] that is
>   accessible via Firefox and curl:
>
>   https://d.moritzbuhl.de/pub
>
> - NetPerfMeter
>
>   The latest NetPerfMeter release supports Linux QUIC and can be used to
>   run performance evaluations [10].
>
> Test Coverage
> =============
>
> The Coverage (gcov) of Functional and Interop Tests:
>
> https://d.moritzbuhl.de/lcov
>
> - Functional Tests
>
>   The libquic self-tests (make check) pass on all major architectures:
>   x86_64, i386, s390x, aarch64, ppc64le.
>
> - Interop tests
>
>   Interoperability was validated using the QUIC Interop Runner [7] against
>   all major userland QUIC stacks. Results are available at:
>
>   https://d.moritzbuhl.de/
>
> - Fuzzing via Syzkaller
>
>   Syzkaller has been running kernel fuzzing with QUIC for weeks using
>   tests/syzkaller/ in libquic [3].
>
> - Performance Testing
>
>   Performance was benchmarked using iperf [8] over a 100G NIC using
>   various MTUs and packet sizes:
>
>   - QUIC vs. kTLS:
>
>     UNIT        size:1024      size:4096      size:16384     size:65536
>     Gbits/sec   QUIC | kTLS    QUIC | kTLS    QUIC | kTLS    QUIC | kTLS
>     ────────────────────────────────────────────────────────────────────
>     mtu:1500    2.27 | 3.26    3.02 | 6.97    3.36 | 9.74    3.48 | 10.8
>     ────────────────────────────────────────────────────────────────────
>     mtu:9000    3.66 | 3.72    5.87 | 8.92    7.03 | 11.2    8.04 | 11.4
>
>   - QUIC(disable_1rtt_encryption) vs. TCP:
>
>     UNIT        size:1024      size:4096      size:16384     size:65536
>     Gbits/sec   QUIC | TCP     QUIC | TCP     QUIC | TCP     QUIC | TCP
>     ────────────────────────────────────────────────────────────────────
>     mtu:1500    3.09 | 4.59    4.46 | 14.2    5.07 | 21.3    5.18 | 23.9
>     ────────────────────────────────────────────────────────────────────
>     mtu:9000    4.60 | 4.65    8.41 | 14.0    11.3 | 28.9    13.5 | 39.2
>
>
>   The performance gap between QUIC and kTLS may be attributed to:
>
>   - The absence of Generic Segmentation Offload (GSO) for QUIC.
>   - An additional data copy on the transmission (TX) path.
>   - Extra encryption required for header protection in QUIC.
>   - A longer header length for the stream data in QUIC.
>
> Patches
> =======
>
> Note: This implementation is organized into five parts and submitted across
> two patchsets for review. This patchset includes Parts 1–2, while Parts 3–5
> will be submitted in a subsequent patchset. For complete series, see [9].
>
> 1. Infrastructure (2):
>
>   net: define IPPROTO_QUIC and SOL_QUIC constants
>   net: build socket infrastructure for QUIC protocol
>
> 2. Subcomponents (13):
>
>   quic: provide common utilities and data structures
>   quic: provide family ops for address and protocol
>   quic: provide quic.h header files for kernel and userspace
>   quic: add stream management
>   quic: add connection id management
>   quic: add path management
>   quic: add congestion control
>   quic: add packet number space
>   quic: add crypto key derivation and installation
>   quic: add crypto packet encryption and decryption
>   quic: add timer management
>   quic: add packet builder base
>   quic: add packet parser base
>
> 3. Data Processing (8):
>
>   quic: add frame encoder and decoder base
>   quic: implement outqueue transmission and flow control
>   quic: implement outqueue sack and retransmission
>   quic: implement inqueue receiving and flow control
>   quic: implement frame creation functions
>   quic: implement frame processing functions
>   quic: implement packet creation functions
>   quic: implement packet processing functions
>
> 4. Socket APIs (6):
>
>   quic: support bind/listen/connect/accept/close()
>   quic: support sendmsg() and recvmsg()
>   quic: support socket options related to interaction after handshake
>   quic: support socket options related to settings prior to handshake
>   quic: support socket options related to setup during handshake
>   quic: support socket ioctls and socket dump via procfs
>
> 5. Documentation and Selftests (3):
>
>   Documentation: describe QUIC protocol interface in quic.rst
>   quic: create sample test using handshake APIs for kernel consumers
>   selftests: net: add tests for QUIC protocol
>
> Notice: The QUIC module is currently labeled as "EXPERIMENTAL".
>
> All contributors are recognized in the respective patches with the tag of
> 'Signed-off-by:'. Special thanks to Moritz Buhl and Stefan Metzmacher whose
> practical use cases and insightful feedback have been instrumental in
> shaping the design and advancing the development.
>
> References
> ==========
>
> [1]  https://datatracker.ietf.org/doc/html/draft-lxin-quic-socket-apis
> [2]  https://github.com/oracle/ktls-utils
> [3]  https://github.com/lxin/quic
> [4]  https://gitlab.com/samba-team/samba/-/merge_requests/4019
> [5]  https://github.com/moritzbuhl/curl/tree/linux_curl
> [6]  https://github.com/moritzbuhl/httpd-portable
> [7]  https://github.com/quic-interop/quic-interop-runner
> [8]  https://github.com/lxin/iperf
> [9]  https://github.com/lxin/net-next/commits/quic/
> [10] https://www.nntb.no/~dreibh/netperfmeter/
>
> Changes in v2-v12: See individual patch changelogs for details.
>
> Xin Long (15):
>   net: define IPPROTO_QUIC and SOL_QUIC constants
>   net: build socket infrastructure for QUIC protocol
>   quic: provide common utilities and data structures
>   quic: provide family ops for address and protocol
>   quic: provide quic.h header files for kernel and userspace
>   quic: add stream management
>   quic: add connection id management
>   quic: add path management
>   quic: add congestion control
>   quic: add packet number space
>   quic: add crypto key derivation and installation
>   quic: add crypto packet encryption and decryption
>   quic: add timer management
>   quic: add packet builder base
>   quic: add packet parser base
>
>  Documentation/networking/ip-sysctl.rst |   39 +
>  MAINTAINERS                            |    9 +
>  include/linux/quic.h                   |   24 +
>  include/linux/socket.h                 |    1 +
>  include/uapi/linux/in.h                |    2 +
>  include/uapi/linux/quic.h              |  241 +++++
>  net/Kconfig                            |    1 +
>  net/Makefile                           |    1 +
>  net/quic/Kconfig                       |   35 +
>  net/quic/Makefile                      |    9 +
>  net/quic/common.c                      |  559 +++++++++++
>  net/quic/common.h                      |  220 +++++
>  net/quic/cong.c                        |  333 +++++++
>  net/quic/cong.h                        |  130 +++
>  net/quic/connid.c                      |  256 +++++
>  net/quic/connid.h                      |  182 ++++
>  net/quic/crypto.c                      | 1248 ++++++++++++++++++++++++
>  net/quic/crypto.h                      |   89 ++
>  net/quic/family.c                      |  452 +++++++++
>  net/quic/family.h                      |   44 +
>  net/quic/packet.c                      |  887 +++++++++++++++++
>  net/quic/packet.h                      |  120 +++
>  net/quic/path.c                        |  568 +++++++++++
>  net/quic/path.h                        |  190 ++++
>  net/quic/pnspace.c                     |  253 +++++
>  net/quic/pnspace.h                     |  201 ++++
>  net/quic/protocol.c                    |  418 ++++++++
>  net/quic/protocol.h                    |   63 ++
>  net/quic/socket.c                      |  475 +++++++++
>  net/quic/socket.h                      |  209 ++++
>  net/quic/stream.c                      |  416 ++++++++
>  net/quic/stream.h                      |  131 +++
>  net/quic/timer.c                       |  154 +++
>  net/quic/timer.h                       |   45 +
>  usr/include/Makefile                   |    1 +
>  35 files changed, 8006 insertions(+)
>  create mode 100644 include/linux/quic.h
>  create mode 100644 include/uapi/linux/quic.h
>  create mode 100644 net/quic/Kconfig
>  create mode 100644 net/quic/Makefile
>  create mode 100644 net/quic/common.c
>  create mode 100644 net/quic/common.h
>  create mode 100644 net/quic/cong.c
>  create mode 100644 net/quic/cong.h
>  create mode 100644 net/quic/connid.c
>  create mode 100644 net/quic/connid.h
>  create mode 100644 net/quic/crypto.c
>  create mode 100644 net/quic/crypto.h
>  create mode 100644 net/quic/family.c
>  create mode 100644 net/quic/family.h
>  create mode 100644 net/quic/packet.c
>  create mode 100644 net/quic/packet.h
>  create mode 100644 net/quic/path.c
>  create mode 100644 net/quic/path.h
>  create mode 100644 net/quic/pnspace.c
>  create mode 100644 net/quic/pnspace.h
>  create mode 100644 net/quic/protocol.c
>  create mode 100644 net/quic/protocol.h
>  create mode 100644 net/quic/socket.c
>  create mode 100644 net/quic/socket.h
>  create mode 100644 net/quic/stream.c
>  create mode 100644 net/quic/stream.h
>  create mode 100644 net/quic/timer.c
>  create mode 100644 net/quic/timer.h
>
> --
> 2.47.1
>

Note: I've run Sashiko on this patchset many times locally over the past
month and addressed all the real issues it found. I don't see any new real
issues being reported on:

https://sashiko.dev/#/patchset/cover.1780232930.git.lucien.xin%40gmail.com

Thanks.