Skip to content

Commit d68e986

Browse files
committed
Support IPv6 Unique Local Addresses
This change correctly identifies ULAs with the fc00::/7 prefix, so that they can be assigned to endpoints and correctly matched to received packets.
1 parent a4b6330 commit d68e986

File tree

6 files changed

+79
-13
lines changed

6 files changed

+79
-13
lines changed

source/FreeRTOS_IPv6_Utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ void vManageSolicitedNodeAddress( const struct xNetworkEndPoint * pxEndPoint,
317317
/* Solicited-node multicast addresses only apply to normal unicast non-loopback addresses. */
318318
xAddressType = xIPv6_GetIPType( &( pxEndPoint->ipv6_settings.xIPAddress ) );
319319

320-
if( ( xAddressType != eIPv6_LinkLocal ) && ( xAddressType != eIPv6_SiteLocal ) && ( xAddressType != eIPv6_Global ) )
320+
if( ( xAddressType != eIPv6_LinkLocal ) && ( xAddressType != eIPv6_SiteLocal ) && ( xAddressType != eIPv6_UniqueLocal ) && ( xAddressType != eIPv6_Global ) )
321321
{
322322
/* The address of this end-point is something other than a normal unicast address... Maybe it's the
323323
* loopback address or maybe this is an error scenario. In any case, there is no corresponding

source/FreeRTOS_Routing.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1411,12 +1411,13 @@ struct xIPv6_Couple
14111411
BaseType_t xIndex;
14121412
static const struct xIPv6_Couple xIPCouples[] =
14131413
{
1414-
/* IP-type Mask Value */
1415-
{ eIPv6_Global, 0xE000U, 0x2000U }, /* 001 */
1416-
{ eIPv6_LinkLocal, 0xFFC0U, 0xFE80U }, /* 1111 1110 10 */
1417-
{ eIPv6_SiteLocal, 0xFFC0U, 0xFEC0U }, /* 1111 1110 11 */
1418-
{ eIPv6_Multicast, 0xFF00U, 0xFF00U }, /* 1111 1111 */
1419-
{ eIPv6_Loopback, 0xFFFFU, 0x0000U }, /* 0000 0000 ::1 */
1414+
/* IP-type Mask Value */
1415+
{ eIPv6_Global, 0xE000U, 0x2000U }, /* 001 */
1416+
{ eIPv6_LinkLocal, 0xFFC0U, 0xFE80U }, /* 1111 1110 10 */
1417+
{ eIPv6_SiteLocal, 0xFFC0U, 0xFEC0U }, /* 1111 1110 11 */
1418+
{ eIPv6_UniqueLocal, 0xFE00U, 0xFC00U }, /* 1111 110 */
1419+
{ eIPv6_Multicast, 0xFF00U, 0xFF00U }, /* 1111 1111 */
1420+
{ eIPv6_Loopback, 0xFFFFU, 0x0000U }, /* 0000 0000 ::1 */
14201421
};
14211422

14221423
if( pxAddress != NULL )

source/include/FreeRTOS_Routing.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -352,12 +352,13 @@
352352

353353
typedef enum
354354
{
355-
eIPv6_Global, /* 001 */
356-
eIPv6_LinkLocal, /* 1111 1110 10 */
357-
eIPv6_SiteLocal, /* 1111 1110 11 */
358-
eIPv6_Multicast, /* 1111 1111 */
359-
eIPv6_Loopback, /* 1111 (::1) */
360-
eIPv6_Unknown /* Not implemented. */
355+
eIPv6_Global, /* 001 */
356+
eIPv6_LinkLocal, /* 1111 1110 10 */
357+
eIPv6_SiteLocal, /* 1111 1110 11 */
358+
eIPv6_UniqueLocal, /* 1111 110 */
359+
eIPv6_Multicast, /* 1111 1111 */
360+
eIPv6_Loopback, /* 1111 (::1) */
361+
eIPv6_Unknown /* Not implemented. */
361362
}
362363
IPv6_Type_t;
363364

test/unit-test/FreeRTOS_IP/FreeRTOS_IP_utest.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4419,6 +4419,26 @@ void test_prvIPNetworkUpCalls_SiteLocal()
44194419
prvIPNetworkUpCalls_Generic( ucAddress, eIPv6_SiteLocal, ipHAS_IPV6 | ipHAS_METHOD );
44204420
}
44214421

4422+
void test_prvIPNetworkUpCalls_UniqueLocal()
4423+
{
4424+
/* Use the unique local address fd12:3456:789a:1::1 */
4425+
static const uint8_t ucAddress[ 16 ] =
4426+
{
4427+
0xFDU, 0x12U,
4428+
0x34U, 0x56U,
4429+
0x78U, 0x9AU,
4430+
0x00U, 0x01U,
4431+
0x00U, 0x00U,
4432+
0x00U, 0x00U,
4433+
0x00U, 0x00U,
4434+
0x00U, 0x01U
4435+
};
4436+
4437+
prvIPNetworkUpCalls_Generic( ucAddress, eIPv6_UniqueLocal, ipHAS_IPV6 | ipHAS_METHOD | ipHAS_INTERFACE );
4438+
prvIPNetworkUpCalls_Generic( ucAddress, eIPv6_UniqueLocal, ipHAS_IPV6 | ipHAS_INTERFACE );
4439+
prvIPNetworkUpCalls_Generic( ucAddress, eIPv6_UniqueLocal, ipHAS_IPV6 | ipHAS_METHOD );
4440+
}
4441+
44224442
void test_prvIPNetworkUpCalls_Multicast()
44234443
{
44244444
/* Use the multicast address "ff02::fb",

test/unit-test/FreeRTOS_IPv6_Utils/FreeRTOS_IPv6_Utils_utest.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,19 @@ void test_vManageSolicitedNodeAddress_NetworkGoingUp( void )
748748

749749
TEST_ASSERT_EQUAL( pdTRUE, xMACAddFunctionCalled );
750750

751+
/* Happy path eIPv6_UniqueLocal */
752+
xInterface.pfAddAllowedMAC = &pfAddAllowedMAC;
753+
xInterface.pfRemoveAllowedMAC = &pfRemoveAllowedMAC;
754+
xInterface.pxEndPoint = &xEndPoint;
755+
756+
xMACAddFunctionCalled = pdFALSE;
757+
758+
xIPv6_GetIPType_ExpectAndReturn( &xEndPoint.ipv6_settings.xIPAddress, eIPv6_UniqueLocal );
759+
760+
vManageSolicitedNodeAddress( &xEndPoint, pdTRUE );
761+
762+
TEST_ASSERT_EQUAL( pdTRUE, xMACAddFunctionCalled );
763+
751764
/* Happy path eIPv6_Global */
752765
xInterface.pfAddAllowedMAC = &pfAddAllowedMAC;
753766
xInterface.pfRemoveAllowedMAC = &pfRemoveAllowedMAC;
@@ -843,6 +856,19 @@ void test_vManageSolicitedNodeAddress_NetworkGoingDown( void )
843856

844857
TEST_ASSERT_EQUAL( pdTRUE, xMACRemoveFunctionCalled );
845858

859+
/* Happy path eIPv6_UniqueLocal */
860+
xInterface.pfAddAllowedMAC = &pfAddAllowedMAC;
861+
xInterface.pfRemoveAllowedMAC = &pfRemoveAllowedMAC;
862+
xInterface.pxEndPoint = &xEndPoint;
863+
864+
xMACRemoveFunctionCalled = pdFALSE;
865+
866+
xIPv6_GetIPType_ExpectAndReturn( &xEndPoint.ipv6_settings.xIPAddress, eIPv6_UniqueLocal );
867+
868+
vManageSolicitedNodeAddress( &xEndPoint, pdFALSE );
869+
870+
TEST_ASSERT_EQUAL( pdTRUE, xMACRemoveFunctionCalled );
871+
846872
/* Happy path eIPv6_Global */
847873
xInterface.pfAddAllowedMAC = &pfAddAllowedMAC;
848874
xInterface.pfRemoveAllowedMAC = &pfRemoveAllowedMAC;

test/unit-test/FreeRTOS_Routing/FreeRTOS_Routing_utest.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2645,6 +2645,24 @@ void test_xIPv6_GetIPType_SiteLocal()
26452645
TEST_ASSERT_EQUAL( eIPv6_SiteLocal, xReturn );
26462646
}
26472647

2648+
/**
2649+
* @brief xIPv6_GetIPType returns eIPv6_UniqueLocal if input address matches FC00::/7.
2650+
*
2651+
* Test step:
2652+
* - Create 1 IPv6 address.
2653+
* - Set the IP address to FD12:3456:789A:1::1.
2654+
* - Call xIPv6_GetIPType to check IP type.
2655+
* - Check if it returns eIPv6_UniqueLocal.
2656+
*/
2657+
void test_xIPv6_GetIPType_UniqueLocal()
2658+
{
2659+
const IPv6_Address_t xIPv6Address = { 0xFD, 0x12, 0x34, 0x56, 0x78, 0x9A, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0x01 };
2660+
IPv6_Type_t xReturn;
2661+
2662+
xReturn = xIPv6_GetIPType( &xIPv6Address );
2663+
TEST_ASSERT_EQUAL( eIPv6_UniqueLocal, xReturn );
2664+
}
2665+
26482666
/**
26492667
* @brief xIPv6_GetIPType returns eIPv6_Multicast if input address matches FF00::/8.
26502668
*

0 commit comments

Comments
 (0)