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 manipulating Thread Network Data managed by the Thread Leader.
32  */
33 
34 #ifndef NETWORK_DATA_LEADER_HPP_
35 #define NETWORK_DATA_LEADER_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdint.h>
40 
41 #include "coap/coap.hpp"
42 #include "common/const_cast.hpp"
43 #include "common/non_copyable.hpp"
44 #include "common/numeric_limits.hpp"
45 #include "common/timer.hpp"
46 #include "net/ip6_address.hpp"
47 #include "thread/mle_router.hpp"
48 #include "thread/network_data.hpp"
49 #include "thread/tmf.hpp"
50 
51 namespace ot {
52 
53 namespace NetworkData {
54 
55 /**
56  * @addtogroup core-netdata-leader
57  *
58  * @brief
59  *   This module includes definitions for manipulating Thread Network Data managed by the Thread Leader.
60  *
61  * @{
62  *
63  */
64 
65 /**
66  * Implements the Thread Network Data maintained by the Leader.
67  *
68  */
69 class Leader : public MutableNetworkData, private NonCopyable
70 {
71     friend class Tmf::Agent;
72     friend class Notifier;
73 
74 public:
75     /**
76      * Initializes the object.
77      *
78      * @param[in]  aInstance     A reference to the OpenThread instance.
79      *
80      */
81     explicit Leader(Instance &aInstance);
82 
83     /**
84      * Reset the Thread Network Data.
85      *
86      */
87     void Reset(void);
88 
89     /**
90      * Returns the maximum observed Network Data length since OT stack initialization or since the last
91      * call to `ResetMaxLength()`.
92      *
93      * @returns The maximum observed Network Data length (high water mark for Network Data length).
94      *
95      */
GetMaxLength(void) const96     uint8_t GetMaxLength(void) const { return mMaxLength; }
97 
98     /**
99      * Resets the tracked maximum Network Data Length.
100      *
101      * @sa GetMaxLength
102      *
103      */
ResetMaxLength(void)104     void ResetMaxLength(void) { mMaxLength = GetLength(); }
105 
106     /**
107      * Returns the Data Version value for a type (full set or stable subset).
108      *
109      * @param[in] aType   The Network Data type (full set or stable subset).
110      *
111      * @returns The Data Version value for @p aType.
112      *
113      */
GetVersion(Type aType) const114     uint8_t GetVersion(Type aType) const { return (aType == kFullSet) ? mVersion : mStableVersion; }
115 
116     /**
117      * Retrieves the 6LoWPAN Context information based on a given IPv6 address.
118      *
119      * @param[in]   aAddress  A reference to an IPv6 address.
120      * @param[out]  aContext  A reference to 6LoWPAN Context information.
121      *
122      * @retval kErrorNone       Successfully retrieved 6LoWPAN Context information.
123      * @retval kErrorNotFound   Could not find the 6LoWPAN Context information.
124      *
125      */
126     Error GetContext(const Ip6::Address &aAddress, Lowpan::Context &aContext) const;
127 
128     /**
129      * Retrieves the 6LoWPAN Context information based on a given Context ID.
130      *
131      * @param[in]   aContextId  The Context ID value.
132      * @param[out]  aContext    A reference to the 6LoWPAN Context information.
133      *
134      * @retval kErrorNone       Successfully retrieved 6LoWPAN Context information.
135      * @retval kErrorNotFound   Could not find the 6LoWPAN Context information.
136      *
137      */
138     Error GetContext(uint8_t aContextId, Lowpan::Context &aContext) const;
139 
140     /**
141      * Indicates whether or not the given IPv6 address is on-mesh.
142      *
143      * @param[in]  aAddress  A reference to an IPv6 address.
144      *
145      * @retval TRUE   If @p aAddress is on-link.
146      * @retval FALSE  If @p aAddress if not on-link.
147      *
148      */
149     bool IsOnMesh(const Ip6::Address &aAddress) const;
150 
151     /**
152      * Performs a route lookup using the Network Data.
153      *
154      * @param[in]   aSource             A reference to the IPv6 source address.
155      * @param[in]   aDestination        A reference to the IPv6 destination address.
156      * @param[out]  aRloc16             A reference to return the RLOC16 for the selected route.
157      *
158      * @retval kErrorNone      Successfully found a route. @p aRloc16 is updated.
159      * @retval kErrorNoRoute   No valid route was found.
160      *
161      */
162     Error RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint16_t &aRloc16) const;
163 
164     /**
165      * Is used by non-Leader devices to set Network Data by reading it from a message from Leader.
166      *
167      * @param[in]  aVersion        The Version value.
168      * @param[in]  aStableVersion  The Stable Version value.
169      * @param[in]  aType           The Network Data type to set, the full set or stable subset.
170      * @param[in]  aMessage        A reference to the message.
171      * @param[in]  aOffset         The offset in @p aMessage pointing to start of Network Data.
172      * @param[in]  aLength         The length of Network Data.
173      *
174      * @retval kErrorNone   Successfully set the network data.
175      * @retval kErrorParse  Network Data in @p aMessage is not valid.
176      *
177      */
178     Error SetNetworkData(uint8_t        aVersion,
179                          uint8_t        aStableVersion,
180                          Type           aType,
181                          const Message &aMessage,
182                          uint16_t       aOffset,
183                          uint16_t       aLength);
184 
185     /**
186      * Gets the Commissioning Dataset from Network Data.
187      *
188      * @param[out] aDataset    A reference to a `MeshCoP::CommissioningDataset` to populate.
189      *
190      */
191     void GetCommissioningDataset(MeshCoP::CommissioningDataset &aDataset) const;
192 
193     /**
194      * Searches for given sub-TLV in Commissioning Data TLV.
195      *
196      * @tparam SubTlvType    The sub-TLV type to search for.
197      *
198      * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no such sub-TLV exists.
199      *
200      */
FindInCommissioningData(void) const201     template <typename SubTlvType> const SubTlvType *FindInCommissioningData(void) const
202     {
203         return As<SubTlvType>(FindCommissioningDataSubTlv(SubTlvType::kType));
204     }
205 
206     /**
207      * Searches for given sub-TLV in Commissioning Data TLV.
208      *
209      * @tparam SubTlvType    The sub-TLV type to search for.
210      *
211      * @returns A pointer to the Commissioning Data Sub-TLV or `nullptr` if no such sub-TLV exists.
212      *
213      */
FindInCommissioningData(void)214     template <typename SubTlvType> SubTlvType *FindInCommissioningData(void)
215     {
216         return As<SubTlvType>(FindCommissioningDataSubTlv(SubTlvType::kType));
217     }
218 
219     /**
220      * Finds and reads the Commissioning Session ID in Commissioning Data TLV.
221      *
222      * @param[out] aSessionId  A reference to return the read session ID.
223      *
224      * @retval kErrorNone       Successfully read the session ID, @p aSessionId is updated.
225      * @retval kErrorNotFound   Did not find Session ID sub-TLV.
226      * @retval kErrorParse      Failed to parse Commissioning Data TLV (invalid format).
227      *
228      */
229     Error FindCommissioningSessionId(uint16_t &aSessionId) const;
230 
231     /**
232      * Finds and reads the Border Agent RLOC16 in Commissioning Data TLV.
233      *
234      * @param[out] aRloc16  A reference to return the read RLOC16.
235      *
236      * @retval kErrorNone       Successfully read the Border Agent RLOC16, @p aRloc16 is updated.
237      * @retval kErrorNotFound   Did not find Border Agent RLOC16 sub-TLV.
238      * @retval kErrorParse      Failed to parse Commissioning Data TLV (invalid format).
239      *
240      */
241     Error FindBorderAgentRloc(uint16_t &aRloc16) const;
242 
243     /**
244      * Finds and reads the Joiner UDP Port in Commissioning Data TLV.
245      *
246      * @param[out] aPort  A reference to return the read port number.
247      *
248      * @retval kErrorNone       Successfully read the Joiner UDP port, @p aPort is updated.
249      * @retval kErrorNotFound   Did not find Joiner UDP Port sub-TLV.
250      * @retval kErrorParse      Failed to parse Commissioning Data TLV (invalid format).
251      *
252      */
253     Error FindJoinerUdpPort(uint16_t &aPort) const;
254 
255     /**
256      * Finds and read the Steering Data in Commissioning Data TLV.
257      *
258      * @param[out] aSteeringData  A reference to return the read Steering Data.
259      *
260      * @retval kErrorNone       Successfully read the Steering Data, @p aSteeringData is updated.
261      * @retval kErrorNotFound   Did not find Steering Data sub-TLV.
262      *
263      */
264     Error FindSteeringData(MeshCoP::SteeringData &aSteeringData) const;
265 
266     /**
267      * Indicates whether or not the Commissioning Data TLV indicates Joining is allowed.
268      *
269      * Joining is allowed if a Border Agent Locator TLV exist and the Steering Data TLV is non-zero.
270      *
271      * @retval TRUE    If joining is allowed.
272      * @retval FALSE   If joining is not allowed.
273      *
274      */
275     bool IsJoiningAllowed(void) const;
276 
277     /**
278      * Checks if the steering data includes a Joiner.
279      *
280      * @param[in]  aEui64             A reference to the Joiner's IEEE EUI-64.
281      *
282      * @retval kErrorNone          @p aEui64 is in the bloom filter.
283      * @retval kErrorInvalidState  No steering data present.
284      * @retval kErrorNotFound      @p aEui64 is not in the bloom filter.
285      *
286      */
287     Error SteeringDataCheckJoiner(const Mac::ExtAddress &aEui64) const;
288 
289     /**
290      * Checks if the steering data includes a Joiner with a given discerner value.
291      *
292      * @param[in]  aDiscerner         A reference to the Joiner Discerner.
293      *
294      * @retval kErrorNone          @p aDiscerner is in the bloom filter.
295      * @retval kErrorInvalidState  No steering data present.
296      * @retval kErrorNotFound      @p aDiscerner is not in the bloom filter.
297      *
298      */
299     Error SteeringDataCheckJoiner(const MeshCoP::JoinerDiscerner &aDiscerner) const;
300 
301     /**
302      * Gets the Service ID for the specified service.
303      *
304      * @param[in]  aEnterpriseNumber  Enterprise Number (IANA-assigned) for Service TLV
305      * @param[in]  aServiceData       The Service Data.
306      * @param[in]  aServerStable      The Stable flag value for Server TLV.
307      * @param[out] aServiceId         A reference where to put the Service ID.
308      *
309      * @retval kErrorNone       Successfully got the Service ID.
310      * @retval kErrorNotFound   The specified service was not found.
311      *
312      */
313     Error GetServiceId(uint32_t           aEnterpriseNumber,
314                        const ServiceData &aServiceData,
315                        bool               aServerStable,
316                        uint8_t           &aServiceId) const;
317 
318     /**
319      * Gets the preferred NAT64 prefix from network data.
320      *
321      * The returned prefix is the highest preference external route entry in Network Data with NAT64 flag set. If there
322      * are multiple such entries the first one is returned.
323      *
324      * @param[out] aConfig      A reference to an `ExternalRouteConfig` to return the prefix.
325      *
326      * @retval kErrorNone       Found the NAT64 prefix and updated @p aConfig.
327      * @retval kErrorNotFound   Could not find any NAT64 entry.
328      *
329      */
330     Error GetPreferredNat64Prefix(ExternalRouteConfig &aConfig) const;
331 
332 #if OPENTHREAD_FTD
333     /**
334      * Defines the match mode constants to compare two RLOC16 values.
335      *
336      */
337     enum MatchMode : uint8_t
338     {
339         kMatchModeRloc16,   ///< Perform exact RLOC16 match.
340         kMatchModeRouterId, ///< Perform Router ID match (match the router and any of its children).
341     };
342 
343     /**
344      * Starts the Leader services.
345      *
346      * The start mode indicates whether device is starting normally as leader or restoring its role as leader after
347      * reset. In the latter case, we do not accept any new registrations (`HandleServerData()`) and wait for
348      * `HandleNetworkDataRestoredAfterReset()` to indicate that the leader has successfully recovered the Network Data
349      * before allowing new Network Data registrations.
350      *
351      * @param[in] aStartMode   The start mode.
352      *
353      */
354     void Start(Mle::LeaderStartMode aStartMode);
355 
356     /**
357      * Increments the Thread Network Data version.
358      *
359      */
360     void IncrementVersion(void);
361 
362     /**
363      * Increments both the Thread Network Data version and stable version.
364      *
365      */
366     void IncrementVersionAndStableVersion(void);
367 
368     /**
369      * Returns CONTEXT_ID_RESUSE_DELAY value.
370      *
371      * @returns The CONTEXT_ID_REUSE_DELAY value (in seconds).
372      *
373      */
GetContextIdReuseDelay(void) const374     uint32_t GetContextIdReuseDelay(void) const { return mContextIds.GetReuseDelay(); }
375 
376     /**
377      * Sets CONTEXT_ID_RESUSE_DELAY value.
378      *
379      * @warning This method should only be used for testing.
380      *
381      * @param[in]  aDelay  The CONTEXT_ID_REUSE_DELAY value (in seconds).
382      *
383      */
SetContextIdReuseDelay(uint32_t aDelay)384     void SetContextIdReuseDelay(uint32_t aDelay) { mContextIds.SetReuseDelay(aDelay); }
385 
386     /**
387      * Removes Network Data entries matching with a given RLOC16.
388      *
389      * @param[in]  aRloc16    A RLOC16 value.
390      * @param[in]  aMatchMode A match mode (@sa MatchMode).
391      *
392      */
393     void RemoveBorderRouter(uint16_t aRloc16, MatchMode aMatchMode);
394 
395     /**
396      * Updates Commissioning Data in Network Data.
397      *
398      * @param[in]  aData        A pointer to the Commissioning Data.
399      * @param[in]  aDataLength  The length of @p aData.
400      *
401      * @retval kErrorNone     Successfully updated the Commissioning Data.
402      * @retval kErrorNoBufs   Insufficient space to add the Commissioning Data.
403      *
404      */
405     Error SetCommissioningData(const void *aData, uint8_t aDataLength);
406 
407     /**
408      * Synchronizes internal 6LoWPAN Context ID Set with recently obtained Thread Network Data.
409      *
410      * Note that this method should be called only by the Leader once after reset.
411      *
412      */
413     void HandleNetworkDataRestoredAfterReset(void);
414 
415     /**
416      * Scans network data for given Service ID and returns pointer to the respective TLV, if present.
417      *
418      * @param aServiceId Service ID to look for.
419      * @return Pointer to the Service TLV for given Service ID, or nullptr if not present.
420      *
421      */
422     const ServiceTlv *FindServiceById(uint8_t aServiceId) const;
423 
424 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
425     /**
426      * Indicates whether a given Prefix can act as a valid OMR prefix and exists in the network data.
427      *
428      * @param[in]  aPrefix   The OMR prefix to check.
429      *
430      * @retval TRUE  If @p aPrefix is a valid OMR prefix and Network Data contains @p aPrefix.
431      * @retval FALSE Otherwise.
432      *
433      */
434     bool ContainsOmrPrefix(const Ip6::Prefix &aPrefix);
435 #endif
436 
437 #endif // OPENTHREAD_FTD
438 
439 private:
440     using FilterIndexes = MeshCoP::SteeringData::HashBitIndexes;
441 
442     const PrefixTlv *FindNextMatchingPrefixTlv(const Ip6::Address &aAddress, const PrefixTlv *aPrevTlv) const;
443 
444     template <typename EntryType> int CompareRouteEntries(const EntryType &aFirst, const EntryType &aSecond) const;
445     int                               CompareRouteEntries(int8_t   aFirstPreference,
446                                                           uint16_t aFirstRloc,
447                                                           int8_t   aSecondPreference,
448                                                           uint16_t aSecondRloc) const;
449 
450     Error ExternalRouteLookup(uint8_t aDomainId, const Ip6::Address &aDestination, uint16_t &aRloc16) const;
451     Error DefaultRouteLookup(const PrefixTlv &aPrefix, uint16_t &aRloc16) const;
452     Error SteeringDataCheck(const FilterIndexes &aFilterIndexes) const;
453     void  GetContextForMeshLocalPrefix(Lowpan::Context &aContext) const;
454     Error ReadCommissioningDataUint16SubTlv(MeshCoP::Tlv::Type aType, uint16_t &aValue) const;
455     void  SignalNetDataChanged(void);
456     const CommissioningDataTlv *FindCommissioningData(void) const;
FindCommissioningData(void)457     CommissioningDataTlv *FindCommissioningData(void) { return AsNonConst(AsConst(this)->FindCommissioningData()); }
458     const MeshCoP::Tlv   *FindCommissioningDataSubTlv(uint8_t aType) const;
FindCommissioningDataSubTlv(uint8_t aType)459     MeshCoP::Tlv         *FindCommissioningDataSubTlv(uint8_t aType)
460     {
461         return AsNonConst(AsConst(this)->FindCommissioningDataSubTlv(aType));
462     }
463 
464 #if OPENTHREAD_FTD
465     static constexpr uint32_t kMaxNetDataSyncWait = 60 * 1000; // Maximum time to wait for netdata sync in msec.
466     static constexpr uint8_t  kMinServiceId       = 0x00;
467     static constexpr uint8_t  kMaxServiceId       = 0x0f;
468 
469     class ChangedFlags
470     {
471     public:
ChangedFlags(void)472         ChangedFlags(void)
473             : mChanged(false)
474             , mStableChanged(false)
475         {
476         }
477 
Update(const NetworkDataTlv & aTlv)478         void Update(const NetworkDataTlv &aTlv)
479         {
480             mChanged       = true;
481             mStableChanged = (mStableChanged || aTlv.IsStable());
482         }
483 
DidChange(void) const484         bool DidChange(void) const { return mChanged; }
DidStableChange(void) const485         bool DidStableChange(void) const { return mStableChanged; }
486 
487     private:
488         bool mChanged;       // Any (stable or not) network data change (add/remove).
489         bool mStableChanged; // Stable network data change (add/remove).
490     };
491 
492     enum UpdateStatus : uint8_t
493     {
494         kTlvRemoved, // TLV contained no sub TLVs and therefore is removed.
495         kTlvUpdated, // TLV stable flag is updated based on its sub TLVs.
496     };
497 
498     class ContextIds : public InstanceLocator
499     {
500     public:
501         // This class tracks Context IDs. A Context ID can be in one
502         // of the 3 states: It is unallocated, or it is allocated
503         // and in-use, or it scheduled to be removed (after reuse delay
504         // interval is passed).
505 
506         static constexpr uint8_t kInvalidId = NumericLimits<uint8_t>::kMax;
507 
508         explicit ContextIds(Instance &aInstance);
509 
510         void     Clear(void);
511         Error    GetUnallocatedId(uint8_t &aId);
MarkAsInUse(uint8_t aId)512         void     MarkAsInUse(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kInUse); }
513         void     ScheduleToRemove(uint8_t aId);
GetReuseDelay(void) const514         uint32_t GetReuseDelay(void) const { return mReuseDelay; }
SetReuseDelay(uint32_t aDelay)515         void     SetReuseDelay(uint32_t aDelay) { mReuseDelay = aDelay; }
516         void     HandleTimer(void);
517 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
MarkAsClone(void)518         void MarkAsClone(void) { mIsClone = true; }
519 #endif
520 
521     private:
522         static constexpr uint32_t kReuseDelay = 5 * 60; // 5 minutes (in seconds).
523 
524         static constexpr uint8_t kMinId = 1;
525         static constexpr uint8_t kMaxId = 15;
526 
527         // The `mRemoveTimes[id]` is used to track the state of a
528         // Context ID and its remove time. Two specific values
529         // `kUnallocated` and `kInUse` are used to indicate ID is in
530         // unallocated or in-use states. Other values indicate we
531         // are in remove state waiting to remove it at `mRemoveTime`.
532 
533         static constexpr uint32_t kUnallocated = 0;
534         static constexpr uint32_t kInUse       = 1;
535 
IsUnallocated(uint8_t aId) const536         bool      IsUnallocated(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kUnallocated; }
IsInUse(uint8_t aId) const537         bool      IsInUse(uint8_t aId) const { return mRemoveTimes[aId - kMinId].GetValue() == kInUse; }
GetRemoveTime(uint8_t aId) const538         TimeMilli GetRemoveTime(uint8_t aId) const { return mRemoveTimes[aId - kMinId]; }
539         void      SetRemoveTime(uint8_t aId, TimeMilli aTime);
MarkAsUnallocated(uint8_t aId)540         void      MarkAsUnallocated(uint8_t aId) { mRemoveTimes[aId - kMinId].SetValue(kUnallocated); }
541 
542         TimeMilli mRemoveTimes[kMaxId - kMinId + 1];
543         uint32_t  mReuseDelay;
544 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
545         bool mIsClone;
546 #endif
547     };
548 
549     template <Uri kUri> void HandleTmf(Coap::Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
550 
551     void HandleTimer(void);
552 
553     void RegisterNetworkData(uint16_t aRloc16, const NetworkData &aNetworkData);
554 
555     Error AddPrefix(const PrefixTlv &aPrefix, ChangedFlags &aChangedFlags);
556     Error AddHasRoute(const HasRouteTlv &aHasRoute, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
557     Error AddBorderRouter(const BorderRouterTlv &aBorderRouter, PrefixTlv &aDstPrefix, ChangedFlags &aChangedFlags);
558     Error AddService(const ServiceTlv &aService, ChangedFlags &aChangedFlags);
559     Error AddServer(const ServerTlv &aServer, ServiceTlv &aDstService, ChangedFlags &aChangedFlags);
560 
561     Error AllocateServiceId(uint8_t &aServiceId) const;
562 
563     void RemoveContext(uint8_t aContextId);
564     void RemoveContext(PrefixTlv &aPrefix, uint8_t aContextId);
565 
566     void RemoveCommissioningData(void);
567 
568     void RemoveRloc(uint16_t aRloc16, MatchMode aMatchMode, ChangedFlags &aChangedFlags);
569     void RemoveRloc(uint16_t           aRloc16,
570                     MatchMode          aMatchMode,
571                     const NetworkData &aExcludeNetworkData,
572                     ChangedFlags      &aChangedFlags);
573     void RemoveRlocInPrefix(PrefixTlv       &aPrefix,
574                             uint16_t         aRloc16,
575                             MatchMode        aMatchMode,
576                             const PrefixTlv *aExcludePrefix,
577                             ChangedFlags    &aChangedFlags);
578     void RemoveRlocInService(ServiceTlv       &aService,
579                              uint16_t          aRloc16,
580                              MatchMode         aMatchMode,
581                              const ServiceTlv *aExcludeService,
582                              ChangedFlags     &aChangedFlags);
583     void RemoveRlocInHasRoute(PrefixTlv       &aPrefix,
584                               HasRouteTlv     &aHasRoute,
585                               uint16_t         aRloc16,
586                               MatchMode        aMatchMode,
587                               const PrefixTlv *aExcludePrefix,
588                               ChangedFlags    &aChangedFlags);
589     void RemoveRlocInBorderRouter(PrefixTlv       &aPrefix,
590                                   BorderRouterTlv &aBorderRouter,
591                                   uint16_t         aRloc16,
592                                   MatchMode        aMatchMode,
593                                   const PrefixTlv *aExcludePrefix,
594                                   ChangedFlags    &aChangedFlags);
595 
596     static bool RlocMatch(uint16_t aFirstRloc16, uint16_t aSecondRloc16, MatchMode aMatchMode);
597 
598     static Error Validate(const NetworkData &aNetworkData, uint16_t aRloc16);
599     static Error ValidatePrefix(const PrefixTlv &aPrefix, uint16_t aRloc16);
600     static Error ValidateService(const ServiceTlv &aService, uint16_t aRloc16);
601 
602     static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const HasRouteEntry &aEntry);
603     static bool ContainsMatchingEntry(const HasRouteTlv *aHasRoute, const HasRouteEntry &aEntry);
604     static bool ContainsMatchingEntry(const PrefixTlv *aPrefix, bool aStable, const BorderRouterEntry &aEntry);
605     static bool ContainsMatchingEntry(const BorderRouterTlv *aBorderRouter, const BorderRouterEntry &aEntry);
606     static bool ContainsMatchingServer(const ServiceTlv *aService, const ServerTlv &aServer);
607 
608     UpdateStatus UpdatePrefix(PrefixTlv &aPrefix);
609     UpdateStatus UpdateService(ServiceTlv &aService);
610     UpdateStatus UpdateTlv(NetworkDataTlv &aTlv, const NetworkDataTlv *aSubTlvs);
611 
612     Error UpdateCommissioningData(uint16_t aDataLength, CommissioningDataTlv *&aDataTlv);
613     Error SetCommissioningData(const Message &aMessage);
614 
615     void SendCommissioningSetResponse(const Coap::Message     &aRequest,
616                                       const Ip6::MessageInfo  &aMessageInfo,
617                                       MeshCoP::StateTlv::State aState);
618     void IncrementVersions(bool aIncludeStable);
619     void IncrementVersions(const ChangedFlags &aFlags);
620 
621 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
622     void CheckForNetDataGettingFull(const NetworkData &aNetworkData, uint16_t aOldRloc16);
623     void MarkAsClone(void);
624 #endif
625 
626     using UpdateTimer = TimerMilliIn<Leader, &Leader::HandleTimer>;
627 #endif // OPENTHREAD_FTD
628 
629     uint8_t mStableVersion;
630     uint8_t mVersion;
631     uint8_t mTlvBuffer[kMaxSize];
632     uint8_t mMaxLength;
633 
634 #if OPENTHREAD_FTD
635 #if OPENTHREAD_CONFIG_BORDER_ROUTER_SIGNAL_NETWORK_DATA_FULL
636     bool mIsClone;
637 #endif
638     bool        mWaitingForNetDataSync;
639     ContextIds  mContextIds;
640     UpdateTimer mTimer;
641 #endif
642 };
643 
644 #if OPENTHREAD_FTD
645 DeclareTmfHandler(Leader, kUriServerData);
646 DeclareTmfHandler(Leader, kUriCommissionerGet);
647 DeclareTmfHandler(Leader, kUriCommissionerSet);
648 #endif
649 
650 /**
651  * @}
652  */
653 
654 } // namespace NetworkData
655 } // namespace ot
656 
657 #endif // NETWORK_DATA_LEADER_HPP_
658