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