Skip to content

Commit 87fdaa6

Browse files
authored
[simulation] add IPv6 loopback address support (openthread#12828)
This commit adds support for IPv6 loopback address (::1) in the simulation platform. When the local interface is set to the IPv6 loopback address, it uses the interface-local multicast group (ff01::116) instead of the link-local group (ff02::116) for node-to-node communication. It also ensures that the `sin6_scope_id` is correctly set for the loopback address in the transmission socket.
1 parent 3d731aa commit 87fdaa6

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

examples/platforms/simulation/simul_utils.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#define UTILS_SOCKET_LOCAL_HOST_ADDR "127.0.0.1"
5151
#define UTILS_SOCKET_GROUP_ADDR "224.0.0.116"
5252
#define UTILS_SOCKET_GROUP_ADDR6 "ff02::116"
53+
#define UTILS_SOCKET_GROUP_ADDR6_LO "ff01::116"
5354

5455
const char *gLocalInterface = UTILS_SOCKET_LOCAL_HOST_ADDR;
5556

@@ -76,7 +77,16 @@ static bool IsAddressLinkLocal(const struct in6_addr *aAddress)
7677
return ((aAddress->s6_addr[0] & 0xff) == 0xfe) && ((aAddress->s6_addr[1] & 0xc0) == 0x80);
7778
}
7879

79-
static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address, unsigned int aIfIndex)
80+
static bool IsAddressLoopback(const struct in6_addr *aAddress)
81+
{
82+
static const uint8_t sLoopbackAddr[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
83+
return memcmp(aAddress->s6_addr, sLoopbackAddr, sizeof(aAddress->s6_addr)) == 0;
84+
}
85+
86+
static void InitRxSocket(utilsSocket *aSocket,
87+
const struct in_addr *aIp4Address,
88+
const struct in6_addr *aIp6Address,
89+
unsigned int aIfIndex)
8090
{
8191
int fd;
8292
int one = 1;
@@ -118,7 +128,13 @@ static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address
118128
else
119129
{
120130
struct ipv6_mreq mreq;
121-
struct sockaddr_in6 *sockaddr = &aSocket->mGroupAddr.mSockAddr6;
131+
struct sockaddr_in6 *sockaddr = &aSocket->mGroupAddr.mSockAddr6;
132+
const char *groupAddr = UTILS_SOCKET_GROUP_ADDR6;
133+
134+
if (aIp6Address != NULL && IsAddressLoopback(aIp6Address))
135+
{
136+
groupAddr = UTILS_SOCKET_GROUP_ADDR6_LO;
137+
}
122138

123139
rval = setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &aIfIndex, sizeof(aIfIndex));
124140
ExpectOrExitWithErrorMsg(rval != -1, "setsockopt(RxFd, IPV6_MULTICAST_IF)");
@@ -127,8 +143,7 @@ static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address
127143
sockaddr->sin6_family = AF_INET6;
128144
sockaddr->sin6_port = htons(aSocket->mPortBase);
129145
sockaddr->sin6_scope_id = aIfIndex; // This specifies network interface for link local scope
130-
ExpectOrExitWithErrorMsg(inet_pton(AF_INET6, UTILS_SOCKET_GROUP_ADDR6, &sockaddr->sin6_addr),
131-
"inet_pton(AF_INET6)");
146+
ExpectOrExitWithErrorMsg(inet_pton(AF_INET6, groupAddr, &sockaddr->sin6_addr), "inet_pton(AF_INET6)");
132147

133148
memset(&mreq, 0, sizeof(mreq));
134149
mreq.ipv6mr_multiaddr = sockaddr->sin6_addr;
@@ -150,7 +165,7 @@ static void InitRxSocket(utilsSocket *aSocket, const struct in_addr *aIp4Address
150165
}
151166
}
152167

153-
void InitTxSocketIp6(utilsSocket *aSocket, const struct in6_addr *aAddress, unsigned int aIfIndex)
168+
static void InitTxSocketIp6(utilsSocket *aSocket, const struct in6_addr *aAddress, unsigned int aIfIndex)
154169
{
155170
int fd;
156171
int one = 1;
@@ -164,7 +179,7 @@ void InitTxSocketIp6(utilsSocket *aSocket, const struct in6_addr *aAddress, unsi
164179
sockaddr.sin6_family = AF_INET6;
165180
sockaddr.sin6_addr = *aAddress;
166181
sockaddr.sin6_port = htons(aSocket->mPort);
167-
if (IsAddressLinkLocal(aAddress))
182+
if (IsAddressLinkLocal(aAddress) || IsAddressLoopback(aAddress))
168183
{
169184
sockaddr.sin6_scope_id = aIfIndex;
170185
}
@@ -283,7 +298,7 @@ static bool TryInitSocketIfname(utilsSocket *aSocket, const char *aLocalInterfac
283298
DieNow(OT_EXIT_FAILURE);
284299
}
285300

286-
InitRxSocket(aSocket, (addr6 ? NULL : addr4), ifIndex);
301+
InitRxSocket(aSocket, (addr6 ? NULL : addr4), addr6, ifIndex);
287302
aSocket->mInitialized = true;
288303
aSocket->mUseIp6 = (addr6 != NULL);
289304

@@ -299,7 +314,7 @@ static bool TryInitSocketIp4(utilsSocket *aSocket, const char *aLocalInterface)
299314
ExpectOrExitWithErrorMsg(inet_pton(AF_INET, aLocalInterface, &addr4), "inet_pton(AF_INET)");
300315

301316
InitTxSocketIp4(aSocket, &addr4);
302-
InitRxSocket(aSocket, &addr4, 0);
317+
InitRxSocket(aSocket, &addr4, NULL, 0);
303318
aSocket->mInitialized = true;
304319
aSocket->mUseIp6 = false;
305320

@@ -344,7 +359,7 @@ static bool TryInitSocketIp6(utilsSocket *aSocket, const char *aLocalInterface)
344359
}
345360

346361
InitTxSocketIp6(aSocket, &addr6, ifIndex);
347-
InitRxSocket(aSocket, NULL, ifIndex);
362+
InitRxSocket(aSocket, NULL, &addr6, ifIndex);
348363
aSocket->mInitialized = true;
349364
aSocket->mUseIp6 = true;
350365
break;

script/check-simulation-local-host

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ test_ipv6()
6464

6565
OT_NODE_TYPE=rcp OT_SIMULATION_LOCAL_HOST=$IFACE_NAME $EXPECT_TEST
6666
OT_NODE_TYPE=rcp OT_SIMULATION_LOCAL_HOST=$IP6ADDR $EXPECT_TEST
67+
OT_NODE_TYPE=rcp OT_SIMULATION_LOCAL_HOST=::1 $EXPECT_TEST
6768
}
6869

6970
test_ipv4()

0 commit comments

Comments
 (0)