xref: /aosp_15_r20/external/openthread/src/core/thread/network_data_types.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2016-21, 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 implements Thread Network Data related types and constants.
32  */
33 
34 #include "network_data_types.hpp"
35 
36 #include "instance/instance.hpp"
37 #include "thread/network_data_tlvs.hpp"
38 
39 namespace ot {
40 namespace NetworkData {
41 
42 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
43 
IsPrefixValid(Instance & aInstance,const Ip6::Prefix & aPrefix)44 static bool IsPrefixValid(Instance &aInstance, const Ip6::Prefix &aPrefix)
45 {
46     // Check that prefix length is within the valid range and the prefix
47     // does not overlap with the mesh-local prefix.
48 
49     return aPrefix.IsValid() && !aPrefix.ContainsPrefix(aInstance.Get<Mle::Mle>().GetMeshLocalPrefix());
50 }
51 
IsValid(Instance & aInstance) const52 bool OnMeshPrefixConfig::IsValid(Instance &aInstance) const
53 {
54     bool isValid = false;
55 
56     if (mDhcp && mSlaac)
57     {
58         // A valid prefix MUST NOT allow both DHCPv6 and SLAAC for
59         // address configuration.
60         ExitNow();
61     }
62 
63     if (mSlaac)
64     {
65         // An IPv6 address prefix used for stateless auto-configuration
66         // [RFC4862] of an IEEE 802.15.4 interface MUST have a length of
67         // 64 bits.
68         VerifyOrExit(GetPrefix().GetLength() == Ip6::NetworkPrefix::kLength);
69     }
70 
71     VerifyOrExit(IsRoutePreferenceValid(mPreference));
72     VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
73     VerifyOrExit(GetPrefix().GetLength() > 0);
74 
75     isValid = true;
76 
77 exit:
78     return isValid;
79 }
80 
ConvertToTlvFlags(void) const81 uint16_t OnMeshPrefixConfig::ConvertToTlvFlags(void) const
82 {
83     uint16_t flags = 0;
84 
85     if (mPreferred)
86     {
87         flags |= BorderRouterEntry::kPreferredFlag;
88     }
89 
90     if (mSlaac)
91     {
92         flags |= BorderRouterEntry::kSlaacFlag;
93     }
94 
95     if (mDhcp)
96     {
97         flags |= BorderRouterEntry::kDhcpFlag;
98     }
99 
100     if (mConfigure)
101     {
102         flags |= BorderRouterEntry::kConfigureFlag;
103     }
104 
105     if (mDefaultRoute)
106     {
107         flags |= BorderRouterEntry::kDefaultRouteFlag;
108     }
109 
110     if (mOnMesh)
111     {
112         flags |= BorderRouterEntry::kOnMeshFlag;
113     }
114 
115     if (mNdDns)
116     {
117         flags |= BorderRouterEntry::kNdDnsFlag;
118     }
119 
120 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
121     if (mDp)
122     {
123         flags |= BorderRouterEntry::kDpFlag;
124     }
125 #endif
126 
127     flags |= (static_cast<uint16_t>(RoutePreferenceToValue(mPreference)) << BorderRouterEntry::kPreferenceOffset);
128 
129     return flags;
130 }
131 
132 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
133 
SetFrom(const PrefixTlv & aPrefixTlv,const BorderRouterTlv & aBorderRouterTlv,const BorderRouterEntry & aBorderRouterEntry)134 void OnMeshPrefixConfig::SetFrom(const PrefixTlv         &aPrefixTlv,
135                                  const BorderRouterTlv   &aBorderRouterTlv,
136                                  const BorderRouterEntry &aBorderRouterEntry)
137 {
138     Clear();
139 
140     aPrefixTlv.CopyPrefixTo(GetPrefix());
141     SetFromTlvFlags(aBorderRouterEntry.GetFlags());
142     mRloc16 = aBorderRouterEntry.GetRloc();
143     mStable = aBorderRouterTlv.IsStable();
144 }
145 
SetFromTlvFlags(uint16_t aFlags)146 void OnMeshPrefixConfig::SetFromTlvFlags(uint16_t aFlags)
147 {
148     mPreferred    = ((aFlags & BorderRouterEntry::kPreferredFlag) != 0);
149     mSlaac        = ((aFlags & BorderRouterEntry::kSlaacFlag) != 0);
150     mDhcp         = ((aFlags & BorderRouterEntry::kDhcpFlag) != 0);
151     mConfigure    = ((aFlags & BorderRouterEntry::kConfigureFlag) != 0);
152     mDefaultRoute = ((aFlags & BorderRouterEntry::kDefaultRouteFlag) != 0);
153     mOnMesh       = ((aFlags & BorderRouterEntry::kOnMeshFlag) != 0);
154     mNdDns        = ((aFlags & BorderRouterEntry::kNdDnsFlag) != 0);
155     mDp           = ((aFlags & BorderRouterEntry::kDpFlag) != 0);
156     mPreference   = RoutePreferenceFromValue(static_cast<uint8_t>(aFlags >> BorderRouterEntry::kPreferenceOffset));
157 }
158 
159 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
IsValid(Instance & aInstance) const160 bool ExternalRouteConfig::IsValid(Instance &aInstance) const
161 {
162     bool isValid = false;
163 
164     if (mNat64)
165     {
166         VerifyOrExit(GetPrefix().IsValidNat64());
167     }
168 
169     VerifyOrExit(IsRoutePreferenceValid(mPreference));
170     VerifyOrExit(IsPrefixValid(aInstance, GetPrefix()));
171 
172     isValid = true;
173 
174 exit:
175     return isValid;
176 }
177 
ConvertToTlvFlags(void) const178 uint8_t ExternalRouteConfig::ConvertToTlvFlags(void) const
179 {
180     uint8_t flags = 0;
181 
182     if (mNat64)
183     {
184         flags |= HasRouteEntry::kNat64Flag;
185     }
186 
187     if (mAdvPio)
188     {
189         flags |= HasRouteEntry::kAdvPioFlag;
190     }
191 
192     flags |= (RoutePreferenceToValue(mPreference) << HasRouteEntry::kPreferenceOffset);
193 
194     return flags;
195 }
196 
197 #endif // OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
198 
SetFrom(Instance & aInstance,const PrefixTlv & aPrefixTlv,const HasRouteTlv & aHasRouteTlv,const HasRouteEntry & aHasRouteEntry)199 void ExternalRouteConfig::SetFrom(Instance            &aInstance,
200                                   const PrefixTlv     &aPrefixTlv,
201                                   const HasRouteTlv   &aHasRouteTlv,
202                                   const HasRouteEntry &aHasRouteEntry)
203 {
204     Clear();
205 
206     aPrefixTlv.CopyPrefixTo(GetPrefix());
207     SetFromTlvFlags(aHasRouteEntry.GetFlags());
208     mStable              = aHasRouteTlv.IsStable();
209     mRloc16              = aHasRouteEntry.GetRloc();
210     mNextHopIsThisDevice = (aHasRouteEntry.GetRloc() == aInstance.Get<Mle::MleRouter>().GetRloc16());
211 }
212 
SetFromTlvFlags(uint8_t aFlags)213 void ExternalRouteConfig::SetFromTlvFlags(uint8_t aFlags)
214 {
215     mNat64      = ((aFlags & HasRouteEntry::kNat64Flag) != 0);
216     mAdvPio     = ((aFlags & HasRouteEntry::kAdvPioFlag) != 0);
217     mPreference = RoutePreferenceFromValue(aFlags >> HasRouteEntry::kPreferenceOffset);
218 }
219 
operator ==(const ServerConfig & aOther) const220 bool ServiceConfig::ServerConfig::operator==(const ServerConfig &aOther) const
221 {
222     return (mStable == aOther.mStable) && (mServerDataLength == aOther.mServerDataLength) &&
223            (memcmp(mServerData, aOther.mServerData, mServerDataLength) == 0);
224 }
225 
SetFrom(const ServerTlv & aServerTlv)226 void ServiceConfig::ServerConfig::SetFrom(const ServerTlv &aServerTlv)
227 {
228     ServerData serverData;
229 
230     aServerTlv.GetServerData(serverData);
231     mStable           = aServerTlv.IsStable();
232     mRloc16           = aServerTlv.GetServer16();
233     mServerDataLength = serverData.GetLength();
234     serverData.CopyBytesTo(mServerData);
235 }
236 
operator ==(const ServiceConfig & aOther) const237 bool ServiceConfig::operator==(const ServiceConfig &aOther) const
238 {
239     return (mEnterpriseNumber == aOther.mEnterpriseNumber) && (mServiceDataLength == aOther.mServiceDataLength) &&
240            (memcmp(mServiceData, aOther.mServiceData, mServiceDataLength) == 0) &&
241            (GetServerConfig() == aOther.GetServerConfig());
242 }
243 
SetFrom(const ServiceTlv & aServiceTlv,const ServerTlv & aServerTlv)244 void ServiceConfig::SetFrom(const ServiceTlv &aServiceTlv, const ServerTlv &aServerTlv)
245 {
246     ServiceData serviceData;
247 
248     Clear();
249 
250     aServiceTlv.GetServiceData(serviceData);
251     mServiceId         = aServiceTlv.GetServiceId();
252     mEnterpriseNumber  = aServiceTlv.GetEnterpriseNumber();
253     mServiceDataLength = serviceData.GetLength();
254     serviceData.CopyBytesTo(mServiceData);
255     GetServerConfig().SetFrom(aServerTlv);
256 }
257 
SetFrom(const PrefixTlv & aPrefixTlv,const ContextTlv & aContextTlv)258 void LowpanContextInfo::SetFrom(const PrefixTlv &aPrefixTlv, const ContextTlv &aContextTlv)
259 {
260     mContextId    = aContextTlv.GetContextId();
261     mCompressFlag = aContextTlv.IsCompress();
262     aPrefixTlv.CopyPrefixTo(GetPrefix());
263     GetPrefix().SetLength(aContextTlv.GetContextLength());
264 }
265 
266 } // namespace NetworkData
267 } // namespace ot
268