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