[libc-commits] [libc] e1f9a86 - [libc] Add the sockaddr_in6 type and IN6ADDR_*_INIT macros (#201357)
via libc-commits
libc-commits at lists.llvm.org
Thu Jun 11 06:27:48 PDT 2026
Author: Pavel Labath
Date: 2026-06-11T13:27:43Z
New Revision: e1f9a860f628a649cf5c7d1386f3649c400e5c9d
URL: https://github.com/llvm/llvm-project/commit/e1f9a860f628a649cf5c7d1386f3649c400e5c9d
DIFF: https://github.com/llvm/llvm-project/commit/e1f9a860f628a649cf5c7d1386f3649c400e5c9d.diff
LOG: [libc] Add the sockaddr_in6 type and IN6ADDR_*_INIT macros (#201357)
This patch adds struct sockaddr_in6 and the
IN6ADDR_ANY_INIT/IN6ADDR_LOOPBACK_INIT initializer macros. These are
configured to be exported via <netinet/in.h>.
I also added tests for these new features:
- layout and initialization check in test/src/netinet/in_test.cpp
verifying sockaddr_in6 size/member alignment and the in6_addr
initializer macros.
- a smoke test in test/src/sys/socket/linux/bind_test.cpp to verify
binding AF_INET6 to a localhost address. This requires a configured ipv6
stack, and may need tweaking/skipping if our build infrastructure does
not support it.
Assisted by Gemini.
Added:
libc/hdr/types/struct_sockaddr_in6.h
libc/include/llvm-libc-types/struct_sockaddr_in6.h
Modified:
libc/hdr/types/CMakeLists.txt
libc/include/CMakeLists.txt
libc/include/llvm-libc-macros/netinet-in-macros.h
libc/include/llvm-libc-types/CMakeLists.txt
libc/include/netinet/in.yaml
libc/test/src/netinet/CMakeLists.txt
libc/test/src/netinet/in_test.cpp
libc/test/src/sys/socket/linux/CMakeLists.txt
libc/test/src/sys/socket/linux/bind_test.cpp
libc/utils/docgen/netinet/in.yaml
Removed:
################################################################################
diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt
index 47d47cc884e1b..4ca50242131d8 100644
--- a/libc/hdr/types/CMakeLists.txt
+++ b/libc/hdr/types/CMakeLists.txt
@@ -492,6 +492,15 @@ add_proxy_header_library(
libc.include.netinet_in
)
+add_proxy_header_library(
+ struct_sockaddr_in6
+ HDRS
+ struct_sockaddr_in6.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_sockaddr_in6
+ libc.include.netinet_in
+)
+
add_proxy_header_library(
struct_udphdr
HDRS
diff --git a/libc/hdr/types/struct_sockaddr_in6.h b/libc/hdr/types/struct_sockaddr_in6.h
new file mode 100644
index 0000000000000..0a3a0acb82ea3
--- /dev/null
+++ b/libc/hdr/types/struct_sockaddr_in6.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 for struct sockaddr_in6.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_SOCKADDR_IN6_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_SOCKADDR_IN6_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_sockaddr_in6.h"
+
+#else
+
+#include <netinet/in.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_SOCKADDR_IN6_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index fcb3cbaa3f01b..86565408fcf13 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -224,6 +224,7 @@ add_header_macro(
.llvm-libc-types.in_port_t
.llvm-libc-types.sa_family_t
.llvm-libc-types.struct_sockaddr_in
+ .llvm-libc-types.struct_sockaddr_in6
.llvm-libc-types.struct_in_addr
.llvm-libc-types.struct_in6_addr
.llvm_libc_common_h
diff --git a/libc/include/llvm-libc-macros/netinet-in-macros.h b/libc/include/llvm-libc-macros/netinet-in-macros.h
index f85f6f5403635..6109140fb0ac5 100644
--- a/libc/include/llvm-libc-macros/netinet-in-macros.h
+++ b/libc/include/llvm-libc-macros/netinet-in-macros.h
@@ -33,6 +33,19 @@
// Not specified by POSIX, added in SVR4
#define INADDR_LOOPBACK __LLVM_LIBC_CAST(static_cast, in_addr_t, 0x7f000001)
+#define IN6ADDR_ANY_INIT \
+ { \
+ { \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } \
+ } \
+ }
+#define IN6ADDR_LOOPBACK_INIT \
+ { \
+ { \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 } \
+ } \
+ }
+
// The following macros test for special IPv6 addresses. Each macro is of type
// int and takes a single argument of type const struct in6_addr *:
// https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/netinet_in.h.html
diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt
index 238ba20dc96b8..73a3219ce1a02 100644
--- a/libc/include/llvm-libc-types/CMakeLists.txt
+++ b/libc/include/llvm-libc-types/CMakeLists.txt
@@ -198,6 +198,16 @@ add_header(sa_family_t HDR sa_family_t.h)
add_header(socklen_t HDR socklen_t.h)
add_header(struct_sockaddr HDR struct_sockaddr.h DEPENDS .sa_family_t)
add_header(struct_sockaddr_in HDR struct_sockaddr_in.h DEPENDS .in_port_t .sa_family_t .struct_in_addr)
+add_header(
+ struct_sockaddr_in6
+ HDR
+ struct_sockaddr_in6.h
+ DEPENDS
+ .in_port_t
+ .sa_family_t
+ .struct_in6_addr
+ libc.include.llvm-libc-macros.stdint_macros
+)
add_header(struct_sockaddr_storage HDR struct_sockaddr_storage.h DEPENDS .sa_family_t)
add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t)
add_header(struct_iovec HDR struct_iovec.h DEPENDS .size_t)
diff --git a/libc/include/llvm-libc-types/struct_sockaddr_in6.h b/libc/include/llvm-libc-types/struct_sockaddr_in6.h
new file mode 100644
index 0000000000000..fc4d4823836fa
--- /dev/null
+++ b/libc/include/llvm-libc-types/struct_sockaddr_in6.h
@@ -0,0 +1,31 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Definition of struct sockaddr_in6. This is the sockaddr specialization for
+/// AF_INET6 sockets, as defined by posix.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_SOCKADDR_IN6_H
+#define LLVM_LIBC_TYPES_STRUCT_SOCKADDR_IN6_H
+
+#include "in_port_t.h"
+#include "llvm-libc-macros/stdint-macros.h"
+#include "sa_family_t.h"
+#include "struct_in6_addr.h"
+
+struct __attribute__((may_alias)) sockaddr_in6 {
+ sa_family_t sin6_family;
+ in_port_t sin6_port;
+ uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ uint32_t sin6_scope_id;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_SOCKADDR_IN6_H
diff --git a/libc/include/netinet/in.yaml b/libc/include/netinet/in.yaml
index c5f24200b72ac..ad62e0955e9e6 100644
--- a/libc/include/netinet/in.yaml
+++ b/libc/include/netinet/in.yaml
@@ -16,6 +16,10 @@ macros:
macro_header: netinet-in-macros.h
- macro_name: IPPROTO_RAW
macro_header: netinet-in-macros.h
+ - macro_name: IN6ADDR_ANY_INIT
+ macro_header: netinet-in-macros.h
+ - macro_name: IN6ADDR_LOOPBACK_INIT
+ macro_header: netinet-in-macros.h
- macro_name: INET_ADDRSTRLEN
macro_header: inet-address-macros.h
- macro_name: INET6_ADDRSTRLEN
@@ -25,6 +29,7 @@ types:
- type_name: in_addr_t
- type_name: sa_family_t
- type_name: struct_sockaddr_in
+ - type_name: struct_sockaddr_in6
- type_name: struct_in_addr
- type_name: struct_in6_addr
enums: []
diff --git a/libc/test/src/netinet/CMakeLists.txt b/libc/test/src/netinet/CMakeLists.txt
index 36d37f2dbdf72..c168186b60eeb 100644
--- a/libc/test/src/netinet/CMakeLists.txt
+++ b/libc/test/src/netinet/CMakeLists.txt
@@ -7,7 +7,9 @@ add_libc_unittest(
SRCS
in_test.cpp
DEPENDS
+ libc.hdr.netinet_in_macros
libc.hdr.types.struct_in6_addr
+ libc.hdr.types.struct_sockaddr_in6
libc.src.arpa.inet.htons
libc.src.arpa.inet.htonl
libc.src.string.memcmp
diff --git a/libc/test/src/netinet/in_test.cpp b/libc/test/src/netinet/in_test.cpp
index ee3a4af0fa53f..7ca408ac21ead 100644
--- a/libc/test/src/netinet/in_test.cpp
+++ b/libc/test/src/netinet/in_test.cpp
@@ -16,10 +16,12 @@
#include "src/string/memcmp.h"
#include "test/UnitTest/Test.h"
+#include "hdr/netinet_in_macros.h"
#include "hdr/types/struct_in6_addr.h"
+#include "hdr/types/struct_sockaddr_in6.h"
TEST(LlvmLibcNetinetInTest, In6AddrLayout) {
- EXPECT_EQ(sizeof(struct in6_addr), size_t(16));
+ EXPECT_EQ(sizeof(struct in6_addr), static_cast<size_t>(16));
struct in6_addr addr = {};
@@ -52,3 +54,27 @@ TEST(LlvmLibcNetinetInTest, In6AddrLayout) {
16),
0);
}
+
+TEST(LlvmLibcNetinetInTest, IN6AddrInitMacros) {
+ struct in6_addr any = IN6ADDR_ANY_INIT;
+ const uint8_t ANY_CONTENT[16] = {0};
+ EXPECT_EQ(LIBC_NAMESPACE::memcmp(&any, ANY_CONTENT, 16), 0);
+ EXPECT_TRUE(IN6_IS_ADDR_UNSPECIFIED(&any));
+
+ struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
+ const uint8_t LOOPBACK_CONTENT[16] = {0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1};
+ EXPECT_EQ(LIBC_NAMESPACE::memcmp(&loopback, LOOPBACK_CONTENT, 16), 0);
+ EXPECT_TRUE(IN6_IS_ADDR_LOOPBACK(&loopback));
+}
+
+TEST(LlvmLibcNetinetInTest, SockaddrIn6Layout) {
+ EXPECT_EQ(offsetof(struct sockaddr_in6, sin6_family), static_cast<size_t>(0));
+ EXPECT_EQ(offsetof(struct sockaddr_in6, sin6_port), static_cast<size_t>(2));
+ EXPECT_EQ(offsetof(struct sockaddr_in6, sin6_flowinfo),
+ static_cast<size_t>(4));
+ EXPECT_EQ(offsetof(struct sockaddr_in6, sin6_addr), static_cast<size_t>(8));
+ EXPECT_EQ(offsetof(struct sockaddr_in6, sin6_scope_id),
+ static_cast<size_t>(24));
+ EXPECT_EQ(sizeof(struct sockaddr_in6), static_cast<size_t>(28));
+}
diff --git a/libc/test/src/sys/socket/linux/CMakeLists.txt b/libc/test/src/sys/socket/linux/CMakeLists.txt
index b3ac8c1fbdd40..fc02db4aec7a0 100644
--- a/libc/test/src/sys/socket/linux/CMakeLists.txt
+++ b/libc/test/src/sys/socket/linux/CMakeLists.txt
@@ -42,6 +42,7 @@ add_libc_unittest(
libc.hdr.netinet_in_macros
libc.hdr.sys_socket_macros
libc.hdr.types.struct_sockaddr_in
+ libc.hdr.types.struct_sockaddr_in6
libc.hdr.types.struct_sockaddr_un
libc.src.arpa.inet.htonl
libc.src.errno.errno
diff --git a/libc/test/src/sys/socket/linux/bind_test.cpp b/libc/test/src/sys/socket/linux/bind_test.cpp
index 9a459a54ae7ee..af2b855c7e6c1 100644
--- a/libc/test/src/sys/socket/linux/bind_test.cpp
+++ b/libc/test/src/sys/socket/linux/bind_test.cpp
@@ -21,6 +21,7 @@
#include "hdr/netinet_in_macros.h"
#include "hdr/sys_socket_macros.h"
#include "hdr/types/struct_sockaddr_in.h"
+#include "hdr/types/struct_sockaddr_in6.h"
#include "hdr/types/struct_sockaddr_un.h"
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
@@ -75,3 +76,32 @@ TEST_F(LlvmLibcBindTest, BindInetSocket) {
EXPECT_NE(my_addr.sin_port, static_cast<in_port_t>(0));
EXPECT_EQ(my_addr.sin_addr.s_addr, (LIBC_NAMESPACE::htonl)(INADDR_LOOPBACK));
}
+
+TEST_F(LlvmLibcBindTest, BindInet6Socket) {
+ int sock = LIBC_NAMESPACE::socket(AF_INET6, SOCK_DGRAM, 0);
+ ASSERT_GE(sock, 0);
+ ASSERT_ERRNO_SUCCESS();
+ LIBC_NAMESPACE::cpp::scope_exit close_sock(
+ [&] { ASSERT_THAT(LIBC_NAMESPACE::close(sock), Succeeds(0)); });
+
+ struct sockaddr_in6 my_addr = {};
+ my_addr.sin6_family = AF_INET6;
+ my_addr.sin6_addr = IN6ADDR_LOOPBACK_INIT;
+
+ int result =
+ LIBC_NAMESPACE::bind(sock, reinterpret_cast<struct sockaddr *>(&my_addr),
+ sizeof(struct sockaddr_in6));
+ if (result == -1) {
+ ASSERT_ERRNO_EQ(EADDRNOTAVAIL); // Ipv6 not available on this host.
+ return;
+ }
+
+ my_addr = {};
+ socklen_t len = sizeof(my_addr);
+ ASSERT_THAT(LIBC_NAMESPACE::getsockname(
+ sock, reinterpret_cast<struct sockaddr *>(&my_addr), &len),
+ Succeeds(0));
+ ASSERT_EQ(len, static_cast<socklen_t>(sizeof(struct sockaddr_in6)));
+ EXPECT_EQ(my_addr.sin6_family, static_cast<sa_family_t>(AF_INET6));
+ EXPECT_NE(my_addr.sin6_port, static_cast<in_port_t>(0));
+}
diff --git a/libc/utils/docgen/netinet/in.yaml b/libc/utils/docgen/netinet/in.yaml
index dd575dcb0f181..eb4e913669c5f 100644
--- a/libc/utils/docgen/netinet/in.yaml
+++ b/libc/utils/docgen/netinet/in.yaml
@@ -17,6 +17,10 @@ macros:
in-latest-posix: ''
INADDR_LOOPBACK:
c-definition: ''
+ IN6ADDR_ANY_INIT:
+ in-latest-posix: ''
+ IN6ADDR_LOOPBACK_INIT:
+ in-latest-posix: ''
INET6_ADDRSTRLEN:
in-latest-posix: ''
INET_ADDRSTRLEN:
More information about the libc-commits
mailing list