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