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          * mesh-local address using the realm-local scope (overridden) address with 64-bit prefix length.
127          *
128          */
129         void InitAsThreadOriginMeshLocal(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         /**
219          * Returns the next unicast address.
220          *
221          * @returns A pointer to the next unicast address.
222          *
223          */
GetNext(void) const224         const UnicastAddress *GetNext(void) const { return static_cast<const UnicastAddress *>(mNext); }
225 
226         /**
227          * Returns the next unicast address.
228          *
229          * @returns A pointer to the next unicast address.
230          *
231          */
GetNext(void)232         UnicastAddress *GetNext(void) { return static_cast<UnicastAddress *>(AsNonConst(mNext)); }
233 
234     private:
Matches(const Address & aAddress) const235         bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; }
236     };
237 
238     /**
239      * Implements an IPv6 network interface multicast address.
240      *
241      */
242     class MulticastAddress : public otNetifMulticastAddress,
243                              public LinkedListEntry<MulticastAddress>,
244                              public Clearable<MulticastAddress>
245     {
246         friend class LinkedList<MulticastAddress>;
247 
248     public:
249         /**
250          * Returns the multicast address.
251          *
252          * @returns The multicast address.
253          *
254          */
GetAddress(void) const255         const Address &GetAddress(void) const { return AsCoreType(&mAddress); }
256 
257         /**
258          * Returns the multicast address.
259          *
260          * @returns The multicast address.
261          *
262          */
GetAddress(void)263         Address &GetAddress(void) { return AsCoreType(&mAddress); }
264 
265         /**
266          * Returns the next multicast address subscribed to the interface.
267          *
268          * @returns A pointer to the next multicast address.
269          *
270          */
GetNext(void) const271         const MulticastAddress *GetNext(void) const { return static_cast<const MulticastAddress *>(mNext); }
272 
273         /**
274          * Returns the next multicast address subscribed to the interface.
275          *
276          * @returns A pointer to the next multicast address.
277          *
278          */
GetNext(void)279         MulticastAddress *GetNext(void) { return static_cast<MulticastAddress *>(AsNonConst(mNext)); }
280 
281     private:
Matches(const Address & aAddress) const282         bool Matches(const Address &aAddress) const { return GetAddress() == aAddress; }
283     };
284 
285     class ExternalMulticastAddress : public MulticastAddress
286     {
287         friend class Netif;
288         friend class LinkedList<ExternalMulticastAddress>;
289 
290     public:
291         /**
292          * Represents an iterator for iterating external multicast addresses in a `Netif` instance.
293          *
294          */
295         class Iterator : public ItemPtrIterator<ExternalMulticastAddress, Iterator>
296         {
297             friend class ItemPtrIterator<ExternalMulticastAddress, Iterator>;
298             friend class Netif;
299 
300         public:
301             /**
302              * Initializes an `Iterator` instance to start from the first external multicast address
303              * that matches a given IPv6 address type filter.
304              *
305              * @param[in] aNetif   A reference to the `Netif` instance.
306              * @param[in] aFilter  The IPv6 address type filter.
307              *
308              */
309             explicit Iterator(const Netif &aNetif, Address::TypeFilter aFilter = Address::kTypeAny);
310 
311         private:
312             class Builder
313             {
314             public:
Builder(const Netif & aNetif,Address::TypeFilter aFilter)315                 Builder(const Netif &aNetif, Address::TypeFilter aFilter)
316                     : mNetif(aNetif)
317                     , mFilter(aFilter)
318                 {
319                 }
320 
begin(void)321                 Iterator begin(void) { return Iterator(mNetif, mFilter); }
end(void)322                 Iterator end(void) { return Iterator(mNetif, Iterator::kEndIterator); }
323 
324             private:
325                 const Netif        &mNetif;
326                 Address::TypeFilter mFilter;
327             };
328 
329             enum IteratorType : uint8_t
330             {
331                 kEndIterator,
332             };
333 
Iterator(const Netif & aNetif,IteratorType)334             Iterator(const Netif &aNetif, IteratorType)
335                 : mNetif(aNetif)
336             {
337             }
338 
339             void AdvanceFrom(const MulticastAddress *aAddr);
Advance(void)340             void Advance(void) { AdvanceFrom(mItem->GetNext()); }
341 
342             const Netif        &mNetif;
343             Address::TypeFilter mFilter;
344         };
345 
346 #if OPENTHREAD_CONFIG_MLR_ENABLE
347         /**
348          * Returns the current Multicast Listener Registration (MLR) state.
349          *
350          * @returns The current Multicast Listener Registration state.
351          *
352          */
GetMlrState(void) const353         MlrState GetMlrState(void) const { return mMlrState; }
354 
355         /**
356          * Sets the Multicast Listener Registration (MLR) state.
357          *
358          * @param[in] aState  The new Multicast Listener Registration state.
359          *
360          */
SetMlrState(MlrState aState)361         void SetMlrState(MlrState aState) { mMlrState = aState; }
362 #endif
363 
364     private:
GetNext(void)365         ExternalMulticastAddress *GetNext(void) { return static_cast<ExternalMulticastAddress *>(AsNonConst(mNext)); }
366 
367 #if OPENTHREAD_CONFIG_MLR_ENABLE
368         MlrState mMlrState;
369 #endif
370     };
371 
372     /**
373      * Initializes the network interface.
374      *
375      * @param[in]  aInstance        A reference to the OpenThread instance.
376      *
377      */
378     explicit Netif(Instance &aInstance);
379 
380     /**
381      * Registers a callback to notify internal IPv6 address changes.
382      *
383      * @param[in]  aCallback         A pointer to a function that is called when an IPv6 address is added or removed.
384      * @param[in]  aCallbackContext  A pointer to application-specific context.
385      *
386      */
SetAddressCallback(otIp6AddressCallback aCallback,void * aCallbackContext)387     void SetAddressCallback(otIp6AddressCallback aCallback, void *aCallbackContext)
388     {
389         mAddressCallback.Set(aCallback, aCallbackContext);
390     }
391 
392     /**
393      * Returns the linked list of unicast addresses.
394      *
395      * @returns The linked list of unicast addresses.
396      *
397      */
GetUnicastAddresses(void) const398     const LinkedList<UnicastAddress> &GetUnicastAddresses(void) const { return mUnicastAddresses; }
399 
400     /**
401      * Returns the linked list of unicast addresses.
402      *
403      * @returns The linked list of unicast addresses.
404      *
405      */
GetUnicastAddresses(void)406     LinkedList<UnicastAddress> &GetUnicastAddresses(void) { return mUnicastAddresses; }
407 
408     /**
409      * Adds a unicast address to the network interface.
410      *
411      * Is intended for addresses internal to OpenThread. The @p aAddress instance is directly added in the
412      * unicast address linked list.
413      *
414      * If @p aAddress is already added, the call to `AddUnicastAddress()` with the same address will perform no action.
415      *
416      * @param[in]  aAddress  A reference to the unicast address.
417      *
418      */
419     void AddUnicastAddress(UnicastAddress &aAddress);
420 
421     /**
422      * Removes a unicast address from the network interface.
423      *
424      * Is intended for addresses internal to OpenThread. The @p aAddress instance is removed from the
425      * unicast address linked list.
426      *
427      * If @p aAddress is not in the list, the call to `RemoveUnicastAddress()` will perform no action.
428      *
429      * @param[in]  aAddress  A reference to the unicast address.
430      *
431      */
432     void RemoveUnicastAddress(UnicastAddress &aAddress);
433 
434     /**
435      * Updates the preferred flag on a previously added (internal to OpenThread core) unicast address.
436      *
437      * If the address is not added to the network interface or the current preferred flag of @p aAddress is the same as
438      * the given @p aPreferred, no action is performed.
439      *
440      * @param[in] aAddress        The unicast address
441      * @param[in] aPreferred The new value for preferred flag.
442      *
443      */
444     void UpdatePreferredFlagOn(UnicastAddress &aAddress, bool aPreferred);
445 
446     /**
447      * Indicates whether or not an address is assigned to the interface.
448      *
449      * @param[in]  aAddress  A reference to the unicast address.
450      *
451      * @retval TRUE   If @p aAddress is assigned to the network interface.
452      * @retval FALSE  If @p aAddress is not assigned to the network interface.
453      *
454      */
455     bool HasUnicastAddress(const Address &aAddress) const;
456 
457     /**
458      * Indicates whether or not a unicast address is assigned to the network interface.
459      *
460      * @param[in]  aAddress  A reference to the unicast address.
461      *
462      * @retval TRUE   If @p aAddress is assigned to the network interface.
463      * @retval FALSE  If @p aAddress is not assigned to the network interface.
464      *
465      */
HasUnicastAddress(const UnicastAddress & aAddress) const466     bool HasUnicastAddress(const UnicastAddress &aAddress) const { return mUnicastAddresses.Contains(aAddress); }
467 
468     /**
469      * Indicates whether a unicast address is an external or internal address.
470      *
471      * @param[in] aAddress  A reference to the unicast address.
472      *
473      * @retval TRUE   The address is an external address.
474      * @retval FALSE  The address is not an external address (it is an OpenThread internal address).
475      *
476      */
477     bool IsUnicastAddressExternal(const UnicastAddress &aAddress) const;
478 
479     /**
480      * Adds an external (to OpenThread) unicast address to the network interface.
481      *
482      * For external address, the @p aAddress instance is not directly used (i.e., it can be temporary). It is copied
483      * into a local entry (allocated from an internal pool) before being added in the unicast address linked list.
484      * The maximum number of external addresses is specified by `OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS`.
485      *
486      * @param[in]  aAddress  A reference to the unicast address.
487      *
488      * @retval kErrorNone         Successfully added (or updated) the unicast address.
489      * @retval kErrorInvalidArgs  The address indicated by @p aAddress is an internal address.
490      * @retval kErrorNoBufs       The maximum number of allowed external addresses are already added.
491      *
492      */
493     Error AddExternalUnicastAddress(const UnicastAddress &aAddress);
494 
495     /**
496      * Removes a external (to OpenThread) unicast address from the network interface.
497      *
498      * @param[in]  aAddress  A reference to the unicast address.
499      *
500      * @retval kErrorNone         Successfully removed the unicast address.
501      * @retval kErrorInvalidArgs  The address indicated by @p aAddress is an internal address.
502      * @retval kErrorNotFound     The unicast address was not found.
503      *
504      */
505     Error RemoveExternalUnicastAddress(const Address &aAddress);
506 
507     /**
508      * Removes all the previously added external (to OpenThread) unicast addresses from the
509      * network interface.
510      *
511      */
512     void RemoveAllExternalUnicastAddresses(void);
513 
514     /**
515      * Indicates whether or not the network interface is subscribed to a multicast address.
516      *
517      * @param[in]  aAddress  The multicast address to check.
518      *
519      * @retval TRUE   If the network interface is subscribed to @p aAddress.
520      * @retval FALSE  If the network interface is not subscribed to @p aAddress.
521      *
522      */
523     bool IsMulticastSubscribed(const Address &aAddress) const;
524 
525     /**
526      * Subscribes the network interface to the link-local and realm-local all routers addresses.
527      *
528      * @note This method MUST be called after `SubscribeAllNodesMulticast()` or its behavior is undefined.
529      *
530      */
531     void SubscribeAllRoutersMulticast(void);
532 
533     /**
534      * Unsubscribes the network interface to the link-local and realm-local all routers address.
535      *
536      */
537     void UnsubscribeAllRoutersMulticast(void);
538 
539     /**
540      * Returns the linked list of multicast addresses.
541      *
542      * @returns The linked list of multicast addresses.
543      *
544      */
GetMulticastAddresses(void) const545     const LinkedList<MulticastAddress> &GetMulticastAddresses(void) const { return mMulticastAddresses; }
546 
547     /**
548      * Indicates whether a multicast address is an external or internal address.
549      *
550      * @param[in] aAddress  A reference to the multicast address.
551      *
552      * @retval TRUE   The address is an external address.
553      * @retval FALSE  The address is not an external address (it is an OpenThread internal address).
554      *
555      */
556     bool IsMulticastAddressExternal(const MulticastAddress &aAddress) const;
557 
558     /**
559      * Subscribes the network interface to a multicast address.
560      *
561      * Is intended for addresses internal to OpenThread. The @p aAddress instance is directly added in the
562      * multicast address linked list.
563      *
564      * @param[in]  aAddress  A reference to the multicast address.
565      *
566      */
567     void SubscribeMulticast(MulticastAddress &aAddress);
568 
569     /**
570      * Unsubscribes the network interface to a multicast address.
571      *
572      * Is intended for addresses internal to OpenThread. The @p aAddress instance is directly removed from
573      * the multicast address linked list.
574      *
575      * @param[in]  aAddress  A reference to the multicast address.
576      *
577      */
578     void UnsubscribeMulticast(const MulticastAddress &aAddress);
579 
580     /**
581      * Subscribes the network interface to the external (to OpenThread) multicast address.
582      *
583      * For external address, the @p aAddress instance is not directly used (i.e., it can be temporary). It is copied
584      * into a local entry (allocated from an internal pool) before being added in the multicast address linked list.
585      * The maximum number of external addresses is specified by `OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS`.
586      *
587      * @param[in]  aAddress  A reference to the multicast address.
588      *
589      * @retval kErrorNone          Successfully subscribed to @p aAddress.
590      * @retval kErrorAlready       The multicast address is already subscribed.
591      * @retval kErrorInvalidArgs   The IP Address indicated by @p aAddress is an invalid multicast address.
592      * @retval kErrorRejected      The IP Address indicated by @p aAddress is an internal multicast address.
593      * @retval kErrorNoBufs        The maximum number of allowed external multicast addresses are already added.
594      *
595      */
596     Error SubscribeExternalMulticast(const Address &aAddress);
597 
598     /**
599      * Unsubscribes the network interface to the external (to OpenThread) multicast address.
600      *
601      * @param[in]  aAddress  A reference to the multicast address.
602      *
603      * @retval kErrorNone         Successfully unsubscribed to the unicast address.
604      * @retval kErrorRejected     The address indicated by @p aAddress is an internal address.
605      * @retval kErrorNotFound     The multicast address was not found.
606      *
607      */
608     Error UnsubscribeExternalMulticast(const Address &aAddress);
609 
610     /**
611      * Unsubscribes the network interface from all previously added external (to OpenThread) multicast
612      * addresses.
613      *
614      */
615     void UnsubscribeAllExternalMulticastAddresses(void);
616 
617     /**
618      * Checks if multicast promiscuous mode is enabled on the network interface.
619      *
620      * @retval TRUE   If the multicast promiscuous mode is enabled.
621      * @retval FALSE  If the multicast promiscuous mode is disabled.
622      *
623      */
IsMulticastPromiscuousEnabled(void) const624     bool IsMulticastPromiscuousEnabled(void) const { return mMulticastPromiscuous; }
625 
626     /**
627      * Enables multicast promiscuous mode on the network interface.
628      *
629      * @param[in]  aEnabled  TRUE if Multicast Promiscuous mode is enabled, FALSE otherwise.
630      *
631      */
SetMulticastPromiscuous(bool aEnabled)632     void SetMulticastPromiscuous(bool aEnabled) { mMulticastPromiscuous = aEnabled; }
633 
634     /**
635      * Enables range-based `for` loop iteration over external multicast addresses on the Netif that matches
636      * a given IPv6 address type filter.
637      *
638      * Should be used like follows: to iterate over all external multicast addresses
639      *
640      *     for (Ip6::Netif::ExternalMulticastAddress &addr : Get<ThreadNetif>().IterateExternalMulticastAddresses())
641      *     { ... }
642      *
643      * or to iterate over a subset of external multicast addresses determined by a given address type filter
644      *
645      *     for (Ip6::Netif::ExternalMulticastAddress &addr :
646      *          Get<ThreadNetif>().IterateExternalMulticastAddresses(Ip6::Address::kTypeMulticastLargerThanRealmLocal))
647      *     { ... }
648      *
649      * @param[in] aFilter  The IPv6 address type filter.
650      *
651      * @returns An `ExternalMulticastAddress::Iterator::Builder` instance.
652      *
653      */
IterateExternalMulticastAddresses(Address::TypeFilter aFilter=Address::kTypeAny)654     ExternalMulticastAddress::Iterator::Builder IterateExternalMulticastAddresses(
655         Address::TypeFilter aFilter = Address::kTypeAny)
656     {
657         return ExternalMulticastAddress::Iterator::Builder(*this, aFilter);
658     }
659 
660     /**
661      * Indicates whether or not the network interfaces is subscribed to any external multicast address.
662      *
663      * @retval TRUE  The network interface is subscribed to at least one external multicast address.
664      * @retval FALSE The network interface is not subscribed to any external multicast address.
665      *
666      */
HasAnyExternalMulticastAddress(void) const667     bool HasAnyExternalMulticastAddress(void) const { return !ExternalMulticastAddress::Iterator(*this).IsDone(); }
668 
669     /**
670      * Applies the new mesh local prefix.
671      *
672      * Updates all mesh-local unicast addresses and prefix-based multicast addresses of the network interface.
673      *
674      */
675     void ApplyNewMeshLocalPrefix(void);
676 
677 protected:
678     /**
679      * Subscribes the network interface to the realm-local all MPL forwarders, link-local, and realm-local
680      * all nodes address.
681      *
682      */
683     void SubscribeAllNodesMulticast(void);
684 
685     /**
686      * Unsubscribes the network interface from the realm-local all MPL forwarders, link-local and
687      * realm-local all nodes address.
688      *
689      * @note This method MUST be called after `UnsubscribeAllRoutersMulticast()` or its behavior is undefined
690      *
691      */
692     void UnsubscribeAllNodesMulticast(void);
693 
694 private:
695     typedef otIp6AddressInfo AddressInfo;
696 
697     static constexpr uint8_t kMulticastPrefixLength = 128; // Multicast prefix length used in `AdressInfo`.
698 
699     void SignalUnicastAddressChange(AddressEvent aEvent, const UnicastAddress &aAddress);
700     void SignalMulticastAddressChange(AddressEvent aEvent, const MulticastAddress &aAddress, AddressOrigin aOrigin);
701     void SignalMulticastAddressesChange(AddressEvent            aEvent,
702                                         const MulticastAddress *aStart,
703                                         const MulticastAddress *aEnd);
704 
705     LinkedList<UnicastAddress>   mUnicastAddresses;
706     LinkedList<MulticastAddress> mMulticastAddresses;
707     bool                         mMulticastPromiscuous;
708 
709     Callback<otIp6AddressCallback> mAddressCallback;
710 
711     Pool<UnicastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_UCAST_ADDRS>           mExtUnicastAddressPool;
712     Pool<ExternalMulticastAddress, OPENTHREAD_CONFIG_IP6_MAX_EXT_MCAST_ADDRS> mExtMulticastAddressPool;
713 
714     static const otNetifMulticastAddress kRealmLocalAllMplForwardersMulticastAddress;
715     static const otNetifMulticastAddress kLinkLocalAllNodesMulticastAddress;
716     static const otNetifMulticastAddress kRealmLocalAllNodesMulticastAddress;
717     static const otNetifMulticastAddress kLinkLocalAllRoutersMulticastAddress;
718     static const otNetifMulticastAddress kRealmLocalAllRoutersMulticastAddress;
719 };
720 
721 /**
722  * @}
723  *
724  */
725 
726 } // namespace Ip6
727 
728 DefineCoreType(otNetifAddress, Ip6::Netif::UnicastAddress);
729 DefineCoreType(otNetifMulticastAddress, Ip6::Netif::MulticastAddress);
730 
731 } // namespace ot
732 
733 #endif // NET_NETIF_HPP_
734