[libc-commits] [libc] [llvm] [libc] Add TCP socket options to <netinet/tcp.h> (PR #236121)
Pavel Labath via libc-commits
libc-commits at lists.llvm.org
Tue Oct 27 06:56:43 PDT 2026
https://github.com/labath created https://github.com/llvm/llvm-project/pull/236121
This patch adds SOL_TCP and the TCP level socket option macros (TCP_MAXSEG, TCP_CORK, TCP_KEEPIDLE, etc.), as well as the constants used as values for TCP_REPAIR and TCP_REPAIR_QUEUE.
The values are Linux-specific, so I've moved them (along with the existing TCP_NODELAY definition) out of the yaml file into a new llvm-libc-macros header with an OS-specific subheader.
I've left out the options which need a struct to be useful (TCP_INFO, TCP_MD5SIG, TCP_REPAIR_WINDOW, TCP_ZEROCOPY_RECEIVE, TCP_AO_*, etc.). I'm leaving those for separate patch(es).
glibc and linux define the TCP_*_QUEUE constants as an enum. I've made them macros instead, since they live in a macro header. This means our header will not play nicely with <linux/tcp.h>, but that's true of glibc's header as well.
I've also added a test which sets a couple of options on a TCP socket.
Assisted-by: Gemini
>From 6ebce249776e8c6556a7b6e39138510e713cf1c7 Mon Sep 17 00:00:00 2001
From: Pavel Labath <pavel at labath.sk>
Date: Tue, 27 Oct 2026 13:14:37 +0000
Subject: [PATCH] [libc] Add TCP socket options to <netinet/tcp.h>
This patch adds SOL_TCP and the TCP level socket option macros
(TCP_MAXSEG, TCP_CORK, TCP_KEEPIDLE, etc.), as well as the constants
used as values for TCP_REPAIR and TCP_REPAIR_QUEUE.
The values are Linux-specific, so I've moved them (along with the
existing TCP_NODELAY definition) out of the yaml file into a new
llvm-libc-macros header with an OS-specific subheader.
I've left out the options which need a struct to be useful (TCP_INFO,
TCP_MD5SIG, TCP_REPAIR_WINDOW, TCP_ZEROCOPY_RECEIVE, TCP_AO_*, etc.).
I'm leaving those for separate patch(es).
glibc and linux define the TCP_*_QUEUE constants as an enum. I've made
them macros instead, since they live in a macro header. This means our
header will not play nicely with <linux/tcp.h>, but that's true of
glibc's header as well.
I've also added a test which sets a couple of options on a TCP socket.
Assisted-by: Gemini
---
libc/hdr/CMakeLists.txt | 8 +++
libc/hdr/netinet_tcp_macros.h | 27 ++++++++
libc/include/CMakeLists.txt | 1 +
libc/include/llvm-libc-macros/CMakeLists.txt | 6 ++
.../llvm-libc-macros/linux/CMakeLists.txt | 6 ++
.../linux/netinet-tcp-macros.h | 66 +++++++++++++++++++
.../llvm-libc-macros/netinet-tcp-macros.h | 21 ++++++
libc/include/netinet/tcp.yaml | 2 +-
libc/test/src/sys/socket/linux/CMakeLists.txt | 2 +
.../src/sys/socket/linux/socketopt_test.cpp | 36 ++++++++++
.../llvm-project-overlay/libc/BUILD.bazel | 19 ++++++
.../libc/test/src/sys/socket/BUILD.bazel | 2 +
12 files changed, 195 insertions(+), 1 deletion(-)
create mode 100644 libc/hdr/netinet_tcp_macros.h
create mode 100644 libc/include/llvm-libc-macros/linux/netinet-tcp-macros.h
create mode 100644 libc/include/llvm-libc-macros/netinet-tcp-macros.h
diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index fbf2cc81b160f4..1f5bdcf3610976 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -120,6 +120,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.netinet_in_macros
)
+add_proxy_header_library(
+ netinet_tcp_macros
+ HDRS
+ netinet_tcp_macros.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-macros.netinet_tcp_macros
+)
+
add_header_library(poll_overlay HDRS poll_overlay.h)
add_proxy_header_library(
poll_macros
diff --git a/libc/hdr/netinet_tcp_macros.h b/libc/hdr/netinet_tcp_macros.h
new file mode 100644
index 00000000000000..9fc03f5f6b944c
--- /dev/null
+++ b/libc/hdr/netinet_tcp_macros.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy header for macros from netinet/tcp.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_NETINET_TCP_MACROS_H
+#define LLVM_LIBC_HDR_NETINET_TCP_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/netinet-tcp-macros.h"
+
+#else // Overlay mode
+
+#include <netinet/tcp.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_NETINET_TCP_MACROS_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 0130ba1d72e0e1..8559d02b2cea60 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -1207,6 +1207,7 @@ add_header_macro(
../libc/include/netinet/tcp.yaml
netinet/tcp.h
DEPENDS
+ .llvm-libc-macros.netinet_tcp_macros
.llvm_libc_common_h
)
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index ed934df81886fe..43d2dfb277e05c 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -210,6 +210,12 @@ add_macro_header(
netinet-in-macros.h
)
+add_macro_header(
+ netinet_tcp_macros
+ HDR
+ netinet-tcp-macros.h
+)
+
add_macro_header(
offsetof_macro
HDR
diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 7d92c1389d064e..f09743d9ab12ca 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -112,6 +112,12 @@ add_header(
net-if-macros.h
)
+add_header(
+ netinet_tcp_macros
+ HDR
+ netinet-tcp-macros.h
+)
+
add_header(
netdb_macros
HDR
diff --git a/libc/include/llvm-libc-macros/linux/netinet-tcp-macros.h b/libc/include/llvm-libc-macros/linux/netinet-tcp-macros.h
new file mode 100644
index 00000000000000..0dffe507dc9fc1
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/netinet-tcp-macros.h
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Macros defined in netinet/tcp.h header file. Values come from the Linux
+/// syscall interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_NETINET_TCP_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_NETINET_TCP_MACROS_H
+
+#define SOL_TCP 6
+
+// TCP level socket options. The option type is int unless noted otherwise.
+#define TCP_NODELAY 1
+#define TCP_MAXSEG 2
+#define TCP_CORK 3
+#define TCP_KEEPIDLE 4
+#define TCP_KEEPINTVL 5
+#define TCP_KEEPCNT 6
+#define TCP_SYNCNT 7
+#define TCP_LINGER2 8
+#define TCP_DEFER_ACCEPT 9
+#define TCP_WINDOW_CLAMP 10
+#define TCP_QUICKACK 12
+#define TCP_CONGESTION 13 // char[]
+#define TCP_THIN_LINEAR_TIMEOUTS 16
+#define TCP_THIN_DUPACK 17
+#define TCP_USER_TIMEOUT 18
+#define TCP_REPAIR 19
+#define TCP_REPAIR_QUEUE 20
+#define TCP_QUEUE_SEQ 21
+#define TCP_FASTOPEN 23
+#define TCP_TIMESTAMP 24
+#define TCP_NOTSENT_LOWAT 25
+#define TCP_SAVE_SYN 27
+#define TCP_SAVED_SYN 28 // unsigned char[]
+#define TCP_FASTOPEN_CONNECT 30
+#define TCP_ULP 31 // char[]
+#define TCP_FASTOPEN_KEY 33 // unsigned char[]
+#define TCP_FASTOPEN_NO_COOKIE 34
+#define TCP_INQ 36
+#define TCP_TX_DELAY 37
+#define TCP_IS_MPTCP 43
+#define TCP_RTO_MAX_MS 44
+#define TCP_RTO_MIN_US 45
+#define TCP_DELACK_MAX_US 46
+
+// Values for TCP_REPAIR.
+#define TCP_REPAIR_ON 1
+#define TCP_REPAIR_OFF 0
+#define TCP_REPAIR_OFF_NO_WP -1
+
+// Values for TCP_REPAIR_QUEUE.
+#define TCP_NO_QUEUE 0
+#define TCP_RECV_QUEUE 1
+#define TCP_SEND_QUEUE 2
+#define TCP_QUEUES_NR 3 // Number of queues, not a valid value.
+
+#endif // LLVM_LIBC_MACROS_LINUX_NETINET_TCP_MACROS_H
diff --git a/libc/include/llvm-libc-macros/netinet-tcp-macros.h b/libc/include/llvm-libc-macros/netinet-tcp-macros.h
new file mode 100644
index 00000000000000..146b928f17d5a0
--- /dev/null
+++ b/libc/include/llvm-libc-macros/netinet-tcp-macros.h
@@ -0,0 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Macros defined in netinet/tcp.h header file.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_NETINET_TCP_MACROS_H
+#define LLVM_LIBC_MACROS_NETINET_TCP_MACROS_H
+
+#ifdef __linux__
+#include "linux/netinet-tcp-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_NETINET_TCP_MACROS_H
diff --git a/libc/include/netinet/tcp.yaml b/libc/include/netinet/tcp.yaml
index 9f0e29639ecd43..8b31fd48a3b675 100644
--- a/libc/include/netinet/tcp.yaml
+++ b/libc/include/netinet/tcp.yaml
@@ -3,7 +3,7 @@ standards:
- posix
macros:
- macro_name: TCP_NODELAY
- macro_value: 1
+ macro_header: netinet-tcp-macros.h
types: []
enums: []
objects: []
diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index 005e5191848434..67e26e3166d0b0 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -122,6 +122,8 @@ add_libc_test(
socketopt_test.cpp
DEPENDS
libc.include.sys_socket
+ libc.hdr.netinet_in_macros
+ libc.hdr.netinet_tcp_macros
libc.hdr.sys_socket_macros
libc.hdr.types.socklen_t
libc.hdr.types.struct_linger
diff --git a/libc/test/src/sys/socket/linux/socketopt_test.cpp b/libc/test/src/sys/socket/linux/socketopt_test.cpp
index 43071121e052ce..c0f803e9e9f5c8 100644
--- a/libc/test/src/sys/socket/linux/socketopt_test.cpp
+++ b/libc/test/src/sys/socket/linux/socketopt_test.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include "hdr/netinet_in_macros.h"
+#include "hdr/netinet_tcp_macros.h"
#include "hdr/sys_socket_macros.h"
#include "hdr/time_macros.h"
#include "hdr/types/struct_linger.h"
@@ -83,6 +85,40 @@ TEST_F(LlvmLibcSocketOptTest, BasicSocketOpt) {
ASSERT_EQ(optlen, static_cast<socklen_t>(sizeof(lin)));
}
+TEST_F(LlvmLibcSocketOptTest, TcpSocketOpt) {
+ static_assert(SOL_TCP == IPPROTO_TCP);
+
+ int sock = LIBC_NAMESPACE::socket(AF_INET, SOCK_STREAM, 0);
+ ASSERT_GE(sock, 0);
+ scope_exit close_sock(
+ [&] { ASSERT_THAT(LIBC_NAMESPACE::close(sock), Succeeds(0)); });
+
+ int optval = 1;
+ socklen_t optlen = sizeof(optval);
+ ASSERT_THAT(
+ LIBC_NAMESPACE::setsockopt(sock, SOL_TCP, TCP_NODELAY, &optval, optlen),
+ Succeeds(0));
+
+ optval = 0;
+ ASSERT_THAT(
+ LIBC_NAMESPACE::getsockopt(sock, SOL_TCP, TCP_NODELAY, &optval, &optlen),
+ Succeeds(0));
+ ASSERT_EQ(optval, 1);
+ ASSERT_EQ(optlen, static_cast<socklen_t>(sizeof(optval)));
+
+ optval = 47;
+ ASSERT_THAT(
+ LIBC_NAMESPACE::setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &optval, optlen),
+ Succeeds(0));
+
+ optval = 0;
+ ASSERT_THAT(
+ LIBC_NAMESPACE::getsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &optval, &optlen),
+ Succeeds(0));
+ ASSERT_EQ(optval, 47);
+ ASSERT_EQ(optlen, static_cast<socklen_t>(sizeof(optval)));
+}
+
TEST_F(LlvmLibcSocketOptTest, NotASocket) {
int fds[2];
ASSERT_THAT(LIBC_NAMESPACE::pipe(fds), Succeeds(0));
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index 751e08c7323cfb..c89128899e8021 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -631,6 +631,14 @@ libc_support_library(
],
)
+libc_support_library(
+ name = "llvm_libc_macros_netinet_tcp_macros",
+ hdrs = [
+ "include/llvm-libc-macros/linux/netinet-tcp-macros.h",
+ "include/llvm-libc-macros/netinet-tcp-macros.h",
+ ],
+)
+
libc_support_library(
name = "llvm_libc_macros_sys_wait_macros",
hdrs = [
@@ -818,6 +826,17 @@ libc_support_library(
hdrs = ["hdr/netinet_in_macros.h"],
)
+libc_support_library(
+ name = "hdr_netinet_tcp_macros",
+ hdrs = ["hdr/netinet_tcp_macros.h"],
+ deps = select({
+ ":full_build": [
+ ":llvm_libc_macros_netinet_tcp_macros",
+ ],
+ "//conditions:default": [],
+ }),
+)
+
libc_support_library(
name = "hdr_offsetof_macros",
hdrs = ["hdr/offsetof_macros.h"],
diff --git a/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel
index f3a5f645e69a35..15858b3f84e307 100644
--- a/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/test/src/sys/socket/BUILD.bazel
@@ -202,6 +202,8 @@ libc_test(
"//libc:__support_time_clock_gettime",
"//libc:close",
"//libc:getsockopt",
+ "//libc:hdr_netinet_in_macros",
+ "//libc:hdr_netinet_tcp_macros",
"//libc:hdr_sys_socket_macros",
"//libc:hdr_time_macros",
"//libc:pipe",
More information about the libc-commits
mailing list