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 IPv6 network interfaces. 32 */ 33 34 #ifndef NET_NETIF_HPP_ 35 #define NET_NETIF_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include "common/as_core_type.hpp" 40 #include "common/callback.hpp" 41 #include "common/clearable.hpp" 42 #include "common/code_utils.hpp" 43 #include "common/const_cast.hpp" 44 #include "common/iterator_utils.hpp" 45 #include "common/linked_list.hpp" 46 #include "common/locator.hpp" 47 #include "common/message.hpp" 48 #include "common/non_copyable.hpp" 49 #include "common/tasklet.hpp" 50 #include "mac/mac_types.hpp" 51 #include "net/ip6_address.hpp" 52 #include "net/socket.hpp" 53 #include "thread/mlr_types.hpp" 54 55 namespace ot { 56 namespace Ip6 { 57 58 class Ip6; 59 60 /** 61 * @addtogroup core-ip6-netif 62 * 63 * @brief 64 * This module includes definitions for IPv6 network interfaces. 65 * 66 * @{ 67 */ 68 69 /** 70 * Implements an IPv6 network interface. 71 */ 72 class Netif : public InstanceLocator, private NonCopyable 73 { 74 friend class Ip6; 75 friend class Address; 76 77 public: 78 /** 79 * Represent an address event (added or removed) 80 * 81 * The boolean values are used for `aIsAdded` parameter in the call of `otIp6AddressCallback`. 82 */ 83 enum AddressEvent : bool 84 { 85 kAddressRemoved = false, ///< Indicates that address was added. 86 kAddressAdded = true, ///< Indicates that address was removed. 87 }; 88 89 /** 90 * Represents the address origin. 91 */ 92 enum AddressOrigin : uint8_t 93 { 94 kOriginThread = OT_ADDRESS_ORIGIN_THREAD, ///< Thread assigned address (ALOC, RLOC, MLEID, etc) 95 kOriginSlaac = OT_ADDRESS_ORIGIN_SLAAC, ///< SLAAC assigned address 96 kOriginDhcp6 = OT_ADDRESS_ORIGIN_DHCPV6, ///< DHCPv6 assigned address 97 kOriginManual = OT_ADDRESS_ORIGIN_MANUAL, ///< Manually assigned address 98 }; 99 100 /** 101 * Implements an IPv6 network interface unicast address. 102 */ 103 class UnicastAddress : public otNetifAddress, 104 public LinkedListEntry<UnicastAddress>, 105 public Clearable<UnicastAddress> 106 { 107 friend class LinkedList<UnicastAddress>; 108 109 public: 110 /** 111 * Clears and initializes the unicast address as a preferred, valid, thread-origin address with 112 * 64-bit prefix length. 113 */ 114 void InitAsThreadOrigin(void); 115 116 /** 117 * Clears and initializes the unicast address as a valid (but not preferred), thread-origin, 118 * mesh-local address using the realm-local scope (overridden) address with 64-bit prefix length. 119 */ 120 void InitAsThreadOriginMeshLocal(void); 121 122 /** 123 * Clears and initializes the unicast address as a valid (but not preferred), thread-origin, global 124 * scope address. 125 */ 126 void InitAsThreadOriginGlobalScope(void); 127 128 /** 129 * Clears and initializes the unicast address as a valid, SLAAC-origin address with a given 130 * preferred flag and a given prefix length. 131 * 132 * @param[in] aPrefixLength The prefix length (in bits). 133 * @param[in] aPreferred The preferred flag. 134 */ 135 void InitAsSlaacOrigin(uint8_t aPrefixLength, bool aPreferred); 136 137 /** 138 * Returns the unicast address. 139 * 140 * @returns The unicast address. 141 */ GetAddress(void) const142 const Address &GetAddress(void) const { return AsCoreType(&mAddress); } 143 144 /** 145 * Returns the unicast address. 146 * 147 * @returns The unicast address. 148 */ GetAddress(void)149 Address &GetAddress(void) { return AsCoreType(&mAddress); } 150 151 /** 152 * Returns the address's prefix length (in bits). 153 * 154 * @returns The prefix length (in bits). 155 */ GetPrefixLength(void) const156 uint8_t GetPrefixLength(void) const { return mPrefixLength; } 157 158 /** 159 * Indicates whether the address has a given prefix (i.e. same prefix length and matches the 160 * prefix). 161 * 162 * @param[in] aPrefix A prefix to check against. 163 * 164 * @retval TRUE The address has and fully matches the @p aPrefix. 165 * @retval FALSE The address does not contain or match the @p aPrefix. 166 */ HasPrefix(const Prefix & aPrefix) const167 bool HasPrefix(const Prefix &aPrefix) const 168 { 169 return (mPrefixLength == aPrefix.GetLength()) && GetAddress().MatchesPrefix(aPrefix); 170 } 171 172 /** 173 * Returns the IPv6 scope value. 174 * 175 * @returns The IPv6 scope value. 176 */ GetScope(void) const177 uint8_t GetScope(void) const 178 { 179 return mScopeOverrideValid ? static_cast<uint8_t>(mScopeOverride) : GetAddress().GetScope(); 180 } 181 182 /** 183 * Sets the IPv6 scope override value. 184 * 185 * @param[in] aScope The IPv6 scope value. 186 */ SetScopeOverride(uint8_t aScope)187 void SetScopeOverride(uint8_t aScope) 188 { 189 mScopeOverride = aScope; 190 mScopeOverrideValid = true; 191 } 192 193 /** 194 * Gets the IPv6 address origin. 195 * 196 * @returns The address origin. 197 */ GetOrigin(void) const198 AddressOrigin GetOrigin(void) const { return static_cast<AddressOrigin>(mAddressOrigin); } 199 200 /** 201 * Returns the next unicast address. 202 * 203 * @returns A pointer to the next unicast address. 204 */ GetNext(void) const205 const UnicastAddress *GetNext(void) const { return static_cast<const UnicastAddress *>(mNext); } 206 207 /** 208 * Returns the next unicast address. 209 * 210 * @returns A pointer to the next unicast address. 211 */ GetNext(void)212 UnicastAddress *GetNext(void) { return static_cast<UnicastAddress *>(AsNonConst(mNext)); } 213 214 private: Matches(const Address & aAddress) const215 bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; } 216 }; 217 218 /** 219 * Implements an IPv6 network interface multicast address. 220 */ 221 class MulticastAddress : public otNetifMulticastAddress, 222 public LinkedListEntry<MulticastAddress>, 223 public Clearable<MulticastAddress> 224 { 225 friend class LinkedList<MulticastAddress>; 226 227 public: 228 /** 229 * Returns the multicast address. 230 * 231 * @returns The multicast address. 232 */ GetAddress(void) const233 const Address &GetAddress(void) const { return AsCoreType(&mAddress); } 234 235 /** 236 * Returns the multicast address. 237 * 238 * @returns The multicast address. 239 */ GetAddress(void)240 Address &GetAddress(void) { return AsCoreType(&mAddress); } 241 242 /** 243 * Returns the next multicast address subscribed to the interface. 244 * 245 * @returns A pointer to the next multicast address. 246 */ GetNext(void) const247 const MulticastAddress *GetNext(void) const { return static_cast<const MulticastAddress *>(mNext); } 248 249 /** 250 * Returns the next multicast address subscribed to the interface. 251 * 252 * @returns A pointer to the next multicast address. 253 */ GetNext(void)254 MulticastAddress *GetNext(void) { return static_cast<MulticastAddress *>(AsNonConst(mNext)); } 255 256 private: Matches(const Address & aAddress) const257 bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; } 258 }; 259 260 class ExternalMulticastAddress : public MulticastAddress 261 { 262 friend class Netif; 263 friend class LinkedList<ExternalMulticastAddress>; 264 265 public: 266 /** 267 * Represents an iterator for iterating external multicast addresses in a `Netif` instance. 268 */ 269 class Iterator : public ItemPtrIterator<ExternalMulticastAddress, Iterator> 270 { 271 friend class ItemPtrIterator<ExternalMulticastAddress, Iterator>; 272 friend class Netif; 273 274 public: 275 /** 276 * Initializes an `Iterator` instance to start from the first external multicast address 277 * that matches a given IPv6 address type filter. 278 * 279 * @param[in] aNetif A reference to the `Netif` instance. 280 * @param[in] aFilter The IPv6 address type filter. 281 */ 282 explicit Iterator(const Netif &aNetif, Address::TypeFilter aFilter = Address::kTypeAny); 283 284 private: 285 class Builder 286 { 287 public: Builder(const Netif & aNetif,Address::TypeFilter aFilter)288 Builder(const Netif &aNetif, Address::TypeFilter aFilter) 289 : mNetif(aNetif) 290 , mFilter(aFilter) 291 { 292 } 293 begin(void)294 Iterator begin(void) { return Iterator(mNetif, mFilter); } end(void)295 Iterator end(void) { return Iterator(mNetif, Iterator::kEndIterator); } 296 297 private: 298 const Netif &mNetif; 299 Address::TypeFilter mFilter; 300 }; 301 302 enum IteratorType : uint8_t 303 { 304 kEndIterator, 305 }; 306 Iterator(const Netif & aNetif,IteratorType)307 Iterator(const Netif &aNetif, IteratorType) 308 : mNetif(aNetif) 309 { 310 } 311 312 void AdvanceFrom(const MulticastAddress *aAddr); Advance(void)313 void Advance(void) { AdvanceFrom(mItem->GetNext()); } 314 315 const Netif &mNetif; 316 Address::TypeFilter mFilter; 317 }; 318 319 #if OPENTHREAD_CONFIG_MLR_ENABLE 320 /** 321 * Returns the current Multicast Listener Registration (MLR) state. 322 * 323 * @returns The current Multicast Listener Registration state. 324 */ GetMlrState(void) const325 MlrState GetMlrState(void) const { return mMlrState; } 326 327 /** 328 * Sets the Multicast Listener Registration (MLR) state. 329 * 330 * @param[in] aState The new Multicast Listener Registration state. 331 */ SetMlrState(MlrState aState)332 void SetMlrState(MlrState aState) { mMlrState = aState; } 333 #endif 334 335 private: GetNext(void)336 ExternalMulticastAddress *GetNext(void) { return static_cast<ExternalMulticastAddress *>(AsNonConst(mNext)); } 337 338 #if OPENTHREAD_CONFIG_MLR_ENABLE 339 MlrState mMlrState; 340 #endif 341 }; 342 343 /** 344 * Initializes the network interface. 345 * 346 * @param[in] aInstance A reference to the OpenThread instance. 347 */ 348 explicit Netif(Instance &aInstance); 349 350 /** 351 * Registers a callback to notify internal IPv6 address changes. 352 * 353 * @param[in] aCallback A pointer to a function that is called when an IPv6 address is added or removed. 354 * @param[in] aCallbackContext A pointer to application-specific context. 355 */ SetAddressCallback(otIp6AddressCallback aCallback,void * aCallbackContext)356 void SetAddressCallback(otIp6AddressCallback aCallback, void *aCallbackContext) 357 { 358 mAddressCallback.Set(aCallback, aCallbackContext); 359 } 360 361 /** 362 * Returns the linked list of unicast addresses. 363 * 364 * @returns The linked list of unicast addresses. 365 */ GetUnicastAddresses(void) const366 const LinkedList<UnicastAddress> &GetUnicastAddresses(void) const { return mUnicastAddresses; } 367 368 /** 369 * Returns the linked list of unicast addresses. 370 * 371 * @returns The linked list of unicast addresses. 372 */ GetUnicastAddresses(void)373 LinkedList<UnicastAddress> &GetUnicastAddresses(void) { return mUnicastAddresses; } 374 375 /** 376 * Adds a unicast address to the network interface. 377 * 378 * Is intended for addresses internal to OpenThread. The @p aAddress instance is directly added in the 379 * unicast address linked list. 380 * 381 * If @p aAddress is already added, the call to `AddUnicastAddress()` with the same address will perform no action. 382 * 383 * @param[in] aAddress A reference to the unicast address. 384 */ 385 void AddUnicastAddress(UnicastAddress &aAddress); 386 387 /** 388 * Removes a unicast address from the network interface. 389 * 390 * Is intended for addresses internal to OpenThread. The @p aAddress instance is removed from the 391 * unicast address linked list. 392 * 393 * If @p aAddress is not in the list, the call to `RemoveUnicastAddress()` will perform no action. 394 * 395 * @param[in] aAddress A reference to the unicast address. 396 */ 397 void RemoveUnicastAddress(UnicastAddress &aAddress); 398 399 /** 400 * Updates the preferred flag on a previously added (internal to OpenThread core) unicast address. 401 * 402 * If the address is not added to the network interface or the current preferred flag of @p aAddress is the same as 403 * the given @p aPreferred, no action is performed. 404 * 405 * @param[in] aAddress The unicast address 406 * @param[in] aPreferred The new value for preferred flag. 407 */ 408 void UpdatePreferredFlagOn(UnicastAddress &aAddress, bool aPreferred); 409 410 /** 411 * Indicates whether or not an address is assigned to the interface. 412 * 413 * @param[in] aAddress A reference to the unicast address. 414 * 415 * @retval TRUE If @p aAddress is assigned to the network interface. 416 * @retval FALSE If @p aAddress is not assigned to the network interface. 417 */ 418 bool HasUnicastAddress(const Address &aAddress) const; 419 420 /** 421 * Indicates whether or not a unicast address is assigned to the network interface. 422 * 423 * @param[in] aAddress A reference to the unicast address. 424 * 425 * @retval TRUE If @p aAddress is assigned to the network interface. 426 * @retval FALSE If @p aAddress is not assigned to the network interface. 427 */ HasUnicastAddress(const UnicastAddress & aAddress) const428 bool HasUnicastAddress(const UnicastAddress &aAddress) const { return mUnicastAddresses.Contains(aAddress); } 429 430 /** 431 * Indicates whether a unicast address is an external or internal address. 432 * 433 * @param[in] aAddress A reference to the unicast address. 434 * 435 * @retval TRUE The address is an external address. 436 * @retval FALSE The address is not an external address (it is an OpenThread internal address). 437 */ 438 bool IsUnicastAddressExternal(const UnicastAddress &aAddress) const; 439 440 /** 441 * Adds an external (to OpenThread) unicast address to the network interface. 442 * 443 * For external address, the @p aAddress instance is not directly used (i.e., it can be temporary). It is copied 444 * into a local entry (allocated from an internal pool) before being added in the unicast address linked list. 445 * The maximum number of external addresses is specified by `OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS`. 446 * 447 * @param[in] aAddress A reference to the unicast address. 448 * 449 * @retval kErrorNone Successfully added (or updated) the unicast address. 450 * @retval kErrorInvalidArgs The address indicated by @p aAddress is an internal address. 451 * @retval kErrorNoBufs The maximum number of allowed external addresses are already added. 452 */ 453 Error AddExternalUnicastAddress(const UnicastAddress &aAddress); 454 455 /** 456 * Removes a external (to OpenThread) unicast address from the network interface. 457 * 458 * @param[in] aAddress A reference to the unicast address. 459 * 460 * @retval kErrorNone Successfully removed the unicast address. 461 * @retval kErrorInvalidArgs The address indicated by @p aAddress is an internal address. 462 * @retval kErrorNotFound The unicast address was not found. 463 */ 464 Error RemoveExternalUnicastAddress(const Address &aAddress); 465 466 /** 467 * Removes all the previously added external (to OpenThread) unicast addresses from the 468 * network interface. 469 */ 470 void RemoveAllExternalUnicastAddresses(void); 471 472 /** 473 * Indicates whether or not the network interface is subscribed to a multicast address. 474 * 475 * @param[in] aAddress The multicast address to check. 476 * 477 * @retval TRUE If the network interface is subscribed to @p aAddress. 478 * @retval FALSE If the network interface is not subscribed to @p aAddress. 479 */ 480 bool IsMulticastSubscribed(const Address &aAddress) const; 481 482 /** 483 * Subscribes the network interface to the link-local and realm-local all routers addresses. 484 * 485 * @note This method MUST be called after `SubscribeAllNodesMulticast()` or its behavior is undefined. 486 */ 487 void SubscribeAllRoutersMulticast(void); 488 489 /** 490 * Unsubscribes the network interface to the link-local and realm-local all routers address. 491 */ 492 void UnsubscribeAllRoutersMulticast(void); 493 494 /** 495 * Returns the linked list of multicast addresses. 496 * 497 * @returns The linked list of multicast addresses. 498 */ GetMulticastAddresses(void) const499 const LinkedList<MulticastAddress> &GetMulticastAddresses(void) const { return mMulticastAddresses; } 500 501 /** 502 * Indicates whether a multicast address is an external or internal address. 503 * 504 * @param[in] aAddress A reference to the multicast address. 505 * 506 * @retval TRUE The address is an external address. 507 * @retval FALSE The address is not an external address (it is an OpenThread internal address). 508 */ 509 bool IsMulticastAddressExternal(const MulticastAddress &aAddress) const; 510 511 /** 512 * Subscribes the network interface to a multicast address. 513 * 514 * Is intended for addresses internal to OpenThread. The @p aAddress instance is directly added in the 515 * multicast address linked list. 516 * 517 * @param[in] aAddress A reference to the multicast address. 518 */ 519 void SubscribeMulticast(MulticastAddress &aAddress); 520 521 /** 522 * Unsubscribes the network interface to a multicast address. 523 * 524 * Is intended for addresses internal to OpenThread. The @p aAddress instance is directly removed from 525 * the multicast address linked list. 526 * 527 * @param[in] aAddress A reference to the multicast address. 528 */ 529 void UnsubscribeMulticast(const MulticastAddress &aAddress); 530 531 /** 532 * Subscribes the network interface to the external (to OpenThread) multicast address. 533 * 534 * For external address, the @p aAddress instance is not directly used (i.e., it can be temporary). It is copied 535 * into a local entry (allocated from an internal pool) before being added in the multicast address linked list. 536 * The maximum number of external addresses is specified by `OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS`. 537 * 538 * @param[in] aAddress A reference to the multicast address. 539 * 540 * @retval kErrorNone Successfully subscribed to @p aAddress. 541 * @retval kErrorAlready The multicast address is already subscribed. 542 * @retval kErrorInvalidArgs The IP Address indicated by @p aAddress is an invalid multicast address. 543 * @retval kErrorRejected The IP Address indicated by @p aAddress is an internal multicast address. 544 * @retval kErrorNoBufs The maximum number of allowed external multicast addresses are already added. 545 */ 546 Error SubscribeExternalMulticast(const Address &aAddress); 547 548 /** 549 * Unsubscribes the network interface to the external (to OpenThread) multicast address. 550 * 551 * @param[in] aAddress A reference to the multicast address. 552 * 553 * @retval kErrorNone Successfully unsubscribed to the unicast address. 554 * @retval kErrorRejected The address indicated by @p aAddress is an internal address. 555 * @retval kErrorNotFound The multicast address was not found. 556 */ 557 Error UnsubscribeExternalMulticast(const Address &aAddress); 558 559 /** 560 * Unsubscribes the network interface from all previously added external (to OpenThread) multicast 561 * addresses. 562 */ 563 void UnsubscribeAllExternalMulticastAddresses(void); 564 565 /** 566 * Enables range-based `for` loop iteration over external multicast addresses on the Netif that matches 567 * a given IPv6 address type filter. 568 * 569 * Should be used like follows: to iterate over all external multicast addresses 570 * 571 * for (Ip6::Netif::ExternalMulticastAddress &addr : Get<ThreadNetif>().IterateExternalMulticastAddresses()) 572 * { ... } 573 * 574 * or to iterate over a subset of external multicast addresses determined by a given address type filter 575 * 576 * for (Ip6::Netif::ExternalMulticastAddress &addr : 577 * Get<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal)) 578 * { ... } 579 * 580 * @param[in] aFilter The IPv6 address type filter. 581 * 582 * @returns An `ExternalMulticastAddress::Iterator::Builder` instance. 583 */ IterateExternalMulticastAddresses(Address::TypeFilter aFilter=Address::kTypeAny)584 ExternalMulticastAddress::Iterator::Builder IterateExternalMulticastAddresses( 585 Address::TypeFilter aFilter = Address::kTypeAny) 586 { 587 return ExternalMulticastAddress::Iterator::Builder(*this, aFilter); 588 } 589 590 /** 591 * Indicates whether or not the network interfaces is subscribed to any external multicast address. 592 * 593 * @retval TRUE The network interface is subscribed to at least one external multicast address. 594 * @retval FALSE The network interface is not subscribed to any external multicast address. 595 */ HasAnyExternalMulticastAddress(void) const596 bool HasAnyExternalMulticastAddress(void) const { return !ExternalMulticastAddress::Iterator(*this).IsDone(); } 597 598 /** 599 * Applies the new mesh local prefix. 600 * 601 * Updates all mesh-local unicast addresses and prefix-based multicast addresses of the network interface. 602 */ 603 void ApplyNewMeshLocalPrefix(void); 604 605 protected: 606 /** 607 * Subscribes the network interface to the realm-local all MPL forwarders, link-local, and realm-local 608 * all nodes address. 609 */ 610 void SubscribeAllNodesMulticast(void); 611 612 /** 613 * Unsubscribes the network interface from the realm-local all MPL forwarders, link-local and 614 * realm-local all nodes address. 615 * 616 * @note This method MUST be called after `UnsubscribeAllRoutersMulticast()` or its behavior is undefined 617 */ 618 void UnsubscribeAllNodesMulticast(void); 619 620 private: 621 typedef otIp6AddressInfo AddressInfo; 622 623 static constexpr uint8_t kMulticastPrefixLength = 128; // Multicast prefix length used in `AdressInfo`. 624 625 void SignalUnicastAddressChange(AddressEvent aEvent, const UnicastAddress &aAddress); 626 void SignalMulticastAddressChange(AddressEvent aEvent, const MulticastAddress &aAddress, AddressOrigin aOrigin); 627 void SignalMulticastAddressesChange(AddressEvent aEvent, 628 const MulticastAddress *aStart, 629 const MulticastAddress *aEnd); 630 631 LinkedList<UnicastAddress> mUnicastAddresses; 632 LinkedList<MulticastAddress> mMulticastAddresses; 633 634 Callback<otIp6AddressCallback> mAddressCallback; 635 636 Pool<UnicastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS> mExtUnicastAddressPool; 637 Pool<ExternalMulticastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS> mExtMulticastAddressPool; 638 639 static const otNetifMulticastAddress kRealmLocalAllMplForwardersMulticastAddress; 640 static const otNetifMulticastAddress kLinkLocalAllNodesMulticastAddress; 641 static const otNetifMulticastAddress kRealmLocalAllNodesMulticastAddress; 642 static const otNetifMulticastAddress kLinkLocalAllRoutersMulticastAddress; 643 static const otNetifMulticastAddress kRealmLocalAllRoutersMulticastAddress; 644 }; 645 646 /** 647 * @} 648 */ 649 650 } // namespace Ip6 651 652 DefineCoreType(otNetifAddress, Ip6::Netif::UnicastAddress); 653 DefineCoreType(otNetifMulticastAddress, Ip6::Netif::MulticastAddress); 654 655 } // namespace ot 656 657 #endif // NET_NETIF_HPP_ 658