[slaac] enhance and simplify SLAAC support (#3621)

This commit enhances the SLAAC support in OpenThread core. It contains
the following changes and features:

The `Utils::Slaac` class is updated to include all the related code
for managing SLAAC addresses (e.g., `Slaac` class maintains the
address buffer and directly subscribes to `Notifier` to listen for
Network Data changes to update SLAAC addresses).

The SLAAC address module is changed to support and use semantically
opaque IID generation algorithm (RFC 7217) instead of random IID
generation. This ensures that SLAAC addresses are random but stable
(i.e., the same SLAAC address is added on a device for the same
prefix) and aligns the implementation with Thread specification
requirement.

The semantically opaque IID generation logic is updated to follow RFC
7217 with SHA-256 as the pseudo-random function, and a 256 bit secret
key (generated once using true random number generator and saved in
non-volatile settings).

A new feature is added to allow SLAAC support to be enabled or
disabled during network operation. When enabled, SLAAC addresses are
generated and added to the interface. When disabled, any previously
added SLAAC address is removed.

This commit also adds "SLAAC prefix filter" feature which allows
OpenThread users to register a filter handler with SLAAC module. The
handler is invoked by SLAAC module when it is about to add a SLAAC
address based on a prefix. The returned boolean value from the handler
determines whether the address should be filtered or not.
This commit is contained in:
Abtin Keshavarzian
2019-03-11 09:35:07 -07:00
committed by Jonathan Hui
parent 6453c9f033
commit 58f144a7f7
11 changed files with 459 additions and 318 deletions
+48 -55
View File
@@ -132,24 +132,6 @@ typedef enum otNetifInterfaceId
OT_NETIF_INTERFACE_ID_THREAD = 1, ///< The Thread Network interface ID.
} otNetifInterfaceId;
/**
* This structure represents data used by Semantically Opaque IID Generator.
*
*/
typedef struct
{
uint8_t *mInterfaceId; ///< String of bytes representing interface ID. Like "eth0" or "wlan0".
uint8_t mInterfaceIdLength; ///< Length of interface ID string.
uint8_t *mNetworkId; ///< Network ID (or name). Can be null if mNetworkIdLength is 0.
uint8_t mNetworkIdLength; ///< Length of Network ID string.
uint8_t mDadCounter; ///< Duplicate address detection counter.
uint8_t *mSecretKey; ///< Secret key used to create IID. Cannot be null.
uint16_t mSecretKeyLength; ///< Secret key length in bytes. Should be at least 16 bytes == 128 bits.
} otSemanticallyOpaqueIidGeneratorData;
/**
* This structure represents an IPv6 socket address.
*
@@ -306,43 +288,6 @@ bool otIp6IsMulticastPromiscuousEnabled(otInstance *aInstance);
*/
void otIp6SetMulticastPromiscuousEnabled(otInstance *aInstance, bool aEnabled);
/**
* Create random IID for given IPv6 address.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[inout] aAddresses A pointer to structure containing IPv6 address for which IID is being created.
* @param[in] aContext A pointer to unused data.
*
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
*
*/
otError otIp6CreateRandomIid(otInstance *aInstance, otNetifAddress *aAddresses, void *aContext);
/**
* Create IID for given IPv6 address using extended MAC address.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[inout] aAddresses A pointer to structure containing IPv6 address for which IID is being created.
* @param[in] aContext A pointer to unused data.
*
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
*
*/
otError otIp6CreateMacIid(otInstance *aInstance, otNetifAddress *aAddresses, void *aContext);
/**
* Create semantically opaque IID for given IPv6 address.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[inout] aAddresses A pointer to structure containing IPv6 address for which IID is being created.
* @param[inout] aContext A pointer to a otSemanticallyOpaqueIidGeneratorData structure.
*
* @retval OT_ERROR_NONE Created valid IID for given IPv6 address.
* @retval OT_ERROR_IP6_ADDRESS_CREATION_FAILURE Could not create valid IID for given IPv6 address.
*
*/
otError otIp6CreateSemanticallyOpaqueIid(otInstance *aInstance, otNetifAddress *aAddresses, void *aContext);
/**
* Allocate a new message buffer for sending an IPv6 message.
*
@@ -577,6 +522,54 @@ bool otIp6IsAddressUnspecified(const otIp6Address *aAddress);
*/
otError otIp6SelectSourceAddress(otInstance *aInstance, otMessageInfo *aMessageInfo);
/**
* This function enables/disables the SLAAC module.
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_ENABLE_SLAAC` to be enabled.
*
* When SLAAC module is enabled, SLAAC addresses (based on on-mesh prefixes in Network Data) are added to the interface.
* When SLAAC module is disabled any previously added SLAAC address is removed.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aEnabled TRUE to enable, FALSE to disable.
*
*/
void otIp6SetSlaacEnabled(otInstance *aInstance, bool aEnabled);
/**
* This function pointer allows user to filter prefixes and not allow an SLAAC address based on a prefix to be added.
*
* `otIp6SetSlaacPrefixFilter()` can be used to set the filter handler. The filter handler is invoked by SLAAC module
* when it is about to add a SLAAC address based on a prefix. Its boolean return value determines whether the address
* is filtered (not added) or not.
*
* @param[in] aInstacne A pointer to an OpenThread instance.
* @param[in] aPrefix A pointer to prefix for which SLAAC address is about to be added.
*
* @retval TRUE Indicates that the SLAAC address based on the prefix should be filtered and NOT added.
* @retval FALSE Indicates that the SLAAC address based on the prefix should be added.
*
*/
typedef bool (*otIp6SlaacPrefixFilter)(otInstance *aInstance, const otIp6Prefix *aPrefix);
/**
* This function sets the SLAAC module filter handler.
*
* This function requires the build-time feature `OPENTHREAD_CONFIG_ENABLE_SLAAC` to be enabled.
*
* The filter handler is called by SLAAC module when it is about to add a SLAAC address based on a prefix to decide
* whether the address should be added or not.
*
* A NULL filter handler disables filtering and allows all SLAAC addresses to be added.
*
* If this function is not called, the default filter used by SLAAC module will be NULL (filtering is disabled).
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aFilter A pointer to SLAAC prefix filter handler, or NULL to disable filtering.
*
*/
void otIp6SetSlaacPrefixFilter(otInstance *aInstance, otIp6SlaacPrefixFilter aFilter);
/**
* @}
*