[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