1 /* 2 * Copyright (c) 2016, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file includes definitions for Thread global IPv6 address configuration with SLAAC. 32 */ 33 34 #ifndef SLAAC_ADDRESS_HPP_ 35 #define SLAAC_ADDRESS_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 40 41 #include "common/locator.hpp" 42 #include "common/non_copyable.hpp" 43 #include "common/notifier.hpp" 44 #include "net/netif.hpp" 45 #include "thread/network_data.hpp" 46 47 namespace ot { 48 namespace Utils { 49 50 /** 51 * @addtogroup core-slaac-address 52 * 53 * @brief 54 * This module includes definitions for Thread global IPv6 address configuration with SLAAC. 55 * 56 * @{ 57 */ 58 59 /** 60 * Implements the SLAAC utility for Thread protocol. 61 * 62 */ 63 class Slaac : public InstanceLocator, private NonCopyable 64 { 65 friend class ot::Notifier; 66 67 public: 68 typedef otIp6SlaacPrefixFilter PrefixFilter; ///< Prefix filter function pointer. 69 70 /** 71 * Represents the secret key used for generating semantically opaque IID (per RFC 7217). 72 * 73 */ 74 struct IidSecretKey 75 { 76 static constexpr uint16_t kSize = 32; ///< Secret key size for generating semantically opaque IID. 77 78 uint8_t m8[kSize]; 79 }; 80 81 /** 82 * Initializes the SLAAC manager object. 83 * 84 * Note that SLAAC module starts enabled. 85 * 86 * @param[in] aInstance A reference to the OpenThread instance. 87 * 88 */ 89 explicit Slaac(Instance &aInstance); 90 91 /** 92 * Enables the SLAAC module. 93 * 94 * When enabled, new SLAAC addresses are generated and added from on-mesh prefixes in network data. 95 * 96 */ 97 void Enable(void); 98 99 /** 100 * Disables the SLAAC module. 101 * 102 * When disabled, any previously added SLAAC address by this module is removed. 103 * 104 */ 105 void Disable(void); 106 107 /** 108 * Indicates whether SLAAC module is enabled or not. 109 * 110 * @retval TRUE SLAAC module is enabled. 111 * @retval FALSE SLAAC module is disabled. 112 * 113 */ IsEnabled(void) const114 bool IsEnabled(void) const { return mEnabled; } 115 116 /** 117 * Sets a SLAAC prefix filter handler. 118 * 119 * The handler is invoked by SLAAC module when it is about to add a SLAAC address based on a prefix. The return 120 * boolean value from handler determines whether the address is filtered or added (TRUE to filter the address, 121 * FALSE to add address). 122 * 123 * The filter can be set to `nullptr` to disable filtering (i.e., allow SLAAC addresses for all prefixes). 124 * 125 * @param[in] aFilter The filter to use. 126 * 127 */ 128 void SetFilter(PrefixFilter aFilter); 129 130 /** 131 * Generates the IID of an IPv6 address. 132 * 133 * @param[in,out] aAddress A reference to the address that will be filled with the IID generated. 134 * Note the prefix of the address must already be filled and will be used 135 * to generate the IID. 136 * @param[in,out] aDadCounter The DAD_Counter that is employed to resolve Duplicate Address Detection 137 * conflicts. 138 * 139 * @retval kErrorNone If successfully generated the IID. 140 * @retval kErrorFailed If no valid IID was generated. 141 * 142 */ 143 Error GenerateIid(Ip6::Netif::UnicastAddress &aAddress, uint8_t &aDadCounter) const; 144 145 /** 146 * Searches in the list of deprecating SLAAC prefixes for a match to a given address and if found, returns the 147 * Domain ID from the Prefix TLV in the Network Data for this SLAAC prefix. 148 * 149 * The `Slaac` module keeps track of the associated Domain IDs for deprecating SLAAC prefixes, even if the related 150 * Prefix TLV has already been removed from the Network Data. This information is used during external route lookup 151 * if a deprecating SLAAC address is used as the source address in an outbound message. 152 * 153 * @param[in] aAddress The address to search for. 154 * @param[out] aDomainId A reference to return the Domain ID. 155 * 156 * @retval kErrorNone Found a match for @p aAddress and updated @p aDomainId. 157 * @retval kErrorNotFound Could not find a match for @p aAddress in deprecating SLAAC prefixes. 158 * 159 */ 160 Error FindDomainIdFor(const Ip6::Address &aAddress, uint8_t &aDomainId) const; 161 162 private: 163 static constexpr uint16_t kNumSlaacAddresses = OPENTHREAD_CONFIG_IP6_SLAAC_NUM_ADDRESSES; 164 165 static constexpr uint16_t kMaxIidCreationAttempts = 256; // Maximum number of attempts when generating IID. 166 167 static constexpr uint32_t kDeprecationInterval = 168 TimeMilli::SecToMsec(OPENTHREAD_CONFIG_IP6_SLAAC_DEPRECATION_INTERVAL); 169 170 enum Action : uint8_t 171 { 172 kAdding, 173 kRemoving, 174 kDeprecating, 175 }; 176 177 class SlaacAddress : public Ip6::Netif::UnicastAddress 178 { 179 public: IsInUse(void) const180 bool IsInUse(void) const { return mValid; } MarkAsNotInUse(void)181 void MarkAsNotInUse(void) { mValid = false; } GetDomainId(void) const182 uint8_t GetDomainId(void) const { return mDomainId; } SetDomainId(uint8_t aDomainId)183 void SetDomainId(uint8_t aDomainId) { mDomainId = aDomainId; } IsDeprecating(void) const184 bool IsDeprecating(void) const { return (mExpirationTime.GetValue() != kNotDeprecated); }; MarkAsNotDeprecating(void)185 void MarkAsNotDeprecating(void) { mExpirationTime.SetValue(kNotDeprecated); } GetExpirationTime(void) const186 TimeMilli GetExpirationTime(void) const { return mExpirationTime; } SetExpirationTime(TimeMilli aTime)187 void SetExpirationTime(TimeMilli aTime) 188 { 189 mExpirationTime = aTime; 190 191 if (mExpirationTime.GetValue() == kNotDeprecated) 192 { 193 mExpirationTime.SetValue(kNotDeprecated + 1); 194 } 195 } 196 197 private: 198 static constexpr uint32_t kNotDeprecated = 0; // Special `mExpirationTime` value to indicate not deprecated. 199 200 uint8_t mDomainId; 201 TimeMilli mExpirationTime; 202 }; 203 204 bool IsSlaac(const NetworkData::OnMeshPrefixConfig &aConfig) const; 205 bool IsFiltered(const NetworkData::OnMeshPrefixConfig &aConfig) const; 206 void RemoveOrDeprecateAddresses(void); 207 void RemoveAllAddresses(void); 208 void AddAddresses(void); 209 void DeprecateAddress(SlaacAddress &aAddress); 210 void RemoveAddress(SlaacAddress &aAddress); 211 void AddAddressFor(const NetworkData::OnMeshPrefixConfig &aConfig); 212 void HandleTimer(void); 213 void GetIidSecretKey(IidSecretKey &aKey) const; 214 void HandleNotifierEvents(Events aEvents); 215 void LogAddress(Action aAction, const SlaacAddress &aAddress); 216 static bool DoesConfigMatchNetifAddr(const NetworkData::OnMeshPrefixConfig &aConfig, 217 const Ip6::Netif::UnicastAddress &aAddr); 218 219 using ExpireTimer = TimerMilliIn<Slaac, &Slaac::HandleTimer>; 220 221 bool mEnabled; 222 PrefixFilter mFilter; 223 ExpireTimer mTimer; 224 SlaacAddress mSlaacAddresses[kNumSlaacAddresses]; 225 }; 226 227 /** 228 * @} 229 */ 230 231 } // namespace Utils 232 } // namespace ot 233 234 #endif // OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE 235 236 #endif // SLAAC_ADDRESS_HPP_ 237