Skip to content

Conversation

@c8ef
Copy link
Contributor

@c8ef c8ef commented Nov 15, 2025

This patch introduces two macros in netinet/in.h. The redundant tests for macro values in the testcases have been removed.

@llvmbot llvmbot added the libc label Nov 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 15, 2025

@llvm/pr-subscribers-libc

Author: Connector Switch (c8ef)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/168207.diff

2 Files Affected:

  • (modified) libc/include/llvm-libc-macros/netinet-in-macros.h (+8)
  • (modified) libc/test/include/netinet_in_test.cpp (+15-16)
diff --git a/libc/include/llvm-libc-macros/netinet-in-macros.h b/libc/include/llvm-libc-macros/netinet-in-macros.h
index 2011c34e288cd..c0d8c19045154 100644
--- a/libc/include/llvm-libc-macros/netinet-in-macros.h
+++ b/libc/include/llvm-libc-macros/netinet-in-macros.h
@@ -33,4 +33,12 @@
 #define INET_ADDRSTRLEN 16
 #define INET6_ADDRSTRLEN 46
 
+#define IN6_IS_ADDR_LINKLOCAL(a)                                               \
+  ((__LLVM_LIBC_CAST(reinterpret_cast, uint8_t *, a)[0]) == 0xfe &&            \
+   (__LLVM_LIBC_CAST(reinterpret_cast, uint8_t *, a)[1] & 0xc0) == 0x80)
+
+#define IN6_IS_ADDR_SITELOCAL(a)                                               \
+  ((__LLVM_LIBC_CAST(reinterpret_cast, uint8_t *, a)[0]) == 0xfe &&            \
+   (__LLVM_LIBC_CAST(reinterpret_cast, uint8_t *, a)[1] & 0xc0) == 0xc0)
+
 #endif // LLVM_LIBC_MACROS_NETINET_IN_MACROS_H
diff --git a/libc/test/include/netinet_in_test.cpp b/libc/test/include/netinet_in_test.cpp
index 714892f511b1c..6937262f92e90 100644
--- a/libc/test/include/netinet_in_test.cpp
+++ b/libc/test/include/netinet_in_test.cpp
@@ -9,21 +9,20 @@
 #include "include/llvm-libc-macros/netinet-in-macros.h"
 #include "test/UnitTest/Test.h"
 
-TEST(LlvmLibcNetinetInTest, IPPROTOMacro) {
-  EXPECT_EQ(IPPROTO_IP, 0);
-  EXPECT_EQ(IPPROTO_ICMP, 1);
-  EXPECT_EQ(IPPROTO_TCP, 6);
-  EXPECT_EQ(IPPROTO_UDP, 17);
-  EXPECT_EQ(IPPROTO_IPV6, 41);
-  EXPECT_EQ(IPPROTO_RAW, 255);
-}
+TEST(LlvmLibcNetinetInTest, IN6Macro) {
+  char buff[16] = {};
+
+  buff[0] = 0xfe;
+  buff[1] = 0x80;
+  EXPECT_TRUE(IN6_IS_ADDR_LINKLOCAL(buff));
+  buff[0] = 0xff;
+  buff[1] = 0x80;
+  EXPECT_FALSE(IN6_IS_ADDR_LINKLOCAL(buff));
 
-TEST(LlvmLibcNetinetInTest, IPV6Macro) {
-  EXPECT_EQ(IPV6_UNICAST_HOPS, 16);
-  EXPECT_EQ(IPV6_MULTICAST_IF, 17);
-  EXPECT_EQ(IPV6_MULTICAST_HOPS, 18);
-  EXPECT_EQ(IPV6_MULTICAST_LOOP, 19);
-  EXPECT_EQ(IPV6_JOIN_GROUP, 20);
-  EXPECT_EQ(IPV6_LEAVE_GROUP, 21);
-  EXPECT_EQ(IPV6_V6ONLY, 26);
+  buff[0] = 0xfe;
+  buff[1] = 0xc0;
+  EXPECT_TRUE(IN6_IS_ADDR_SITELOCAL(buff));
+  buff[0] = 0xff;
+  buff[1] = 0x80;
+  EXPECT_FALSE(IN6_IS_ADDR_SITELOCAL(buff));
 }

Comment on lines +37 to +38
((__LLVM_LIBC_CAST(reinterpret_cast, uint8_t *, a)[0]) == 0xfe && \
(__LLVM_LIBC_CAST(reinterpret_cast, uint8_t *, a)[1] & 0xc0) == 0x80)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we are not worrying about endianness for now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow here. Does this mean we can assume all our supported host platforms are little-endian now? I think the current implementation can support both endianness.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing byte 0 == 0xfe and byte 1 & mask == 80, so assuming the high parts of 32-bit address a are at byte 0 and 1, that's big endian. Are we assuming a will be big endian, or does it depend on the host?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we assuming a will be big endian

Yes.

Quote from manpages: Each macro is of type int and takes a single argument of type const struct in6_addr *

struct in6_addr is required by the standard to store the address in Network Byte Order (Big Endian). This means the most significant byte is always at memory offset 0, regardless of the host architecture.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind adding the explanation + reference to a comment here, so that this question won't come up in the future? Thanks,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor

@michaelrj-google michaelrj-google left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good to me, please edit the PR description so it doesn't @ me before merging. If merged as-is it will ping me every time someone pushes a copy of this commit to github which is a little annoying.

@c8ef
Copy link
Contributor Author

c8ef commented Dec 9, 2025

Overall looks good to me, please edit the PR description so it doesn't @ me before merging. If merged as-is it will ping me every time someone pushes a copy of this commit to github which is a little annoying.

Done.

@c8ef c8ef requested a review from lntue December 9, 2025 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants