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.