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 implements the Thread network interface.
32 */
33
34 #include "thread_netif.hpp"
35
36 #include "common/code_utils.hpp"
37 #include "common/encoding.hpp"
38 #include "common/instance.hpp"
39 #include "common/locator_getters.hpp"
40 #include "common/message.hpp"
41 #include "net/ip6.hpp"
42 #include "net/netif.hpp"
43 #include "net/udp6.hpp"
44 #include "thread/mle.hpp"
45 #include "thread/thread_tlvs.hpp"
46 #include "thread/uri_paths.hpp"
47
48 namespace ot {
49
ThreadNetif(Instance & aInstance)50 ThreadNetif::ThreadNetif(Instance &aInstance)
51 : Netif(aInstance)
52 , mTmfAgent(aInstance)
53 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
54 , mDhcp6Client(aInstance)
55 #endif
56 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
57 , mDhcp6Server(aInstance)
58 #endif
59 #if OPENTHREAD_CONFIG_NEIGHBOR_DISCOVERY_AGENT_ENABLE
60 , mNeighborDiscoveryAgent(aInstance)
61 #endif
62 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
63 , mSlaac(aInstance)
64 #endif
65 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
66 , mDnsClient(aInstance)
67 #endif
68 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
69 , mSrpClient(aInstance)
70 #endif
71 #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE
72 , mSrpClientBuffers(aInstance)
73 #endif
74 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
75 , mDnssdServer(aInstance)
76 #endif
77 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
78 , mSntpClient(aInstance)
79 #endif
80 , mActiveDataset(aInstance)
81 , mPendingDataset(aInstance)
82 , mIp6Filter(aInstance)
83 , mKeyManager(aInstance)
84 , mLowpan(aInstance)
85 , mMac(aInstance)
86 , mMeshForwarder(aInstance)
87 , mMleRouter(aInstance)
88 , mDiscoverScanner(aInstance)
89 #if OPENTHREAD_CONFIG_MULTI_RADIO
90 , mRadioSelector(aInstance)
91 #endif
92 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
93 , mNetworkDataLocal(aInstance)
94 #endif
95 , mNetworkDataLeader(aInstance)
96 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
97 , mNetworkDataNotifier(aInstance)
98 #endif
99 #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
100 , mNetworkDataPublisher(aInstance)
101 #endif
102 , mNetworkDataServiceManager(aInstance)
103 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
104 , mNetworkDiagnostic(aInstance)
105 #endif
106 , mIsUp(false)
107 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
108 , mBorderAgent(aInstance)
109 #endif
110 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
111 , mCommissioner(aInstance)
112 #endif
113 #if OPENTHREAD_CONFIG_DTLS_ENABLE
114 , mCoapSecure(aInstance)
115 #endif
116 #if OPENTHREAD_CONFIG_JOINER_ENABLE
117 , mJoiner(aInstance)
118 #endif
119 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
120 , mJamDetector(aInstance)
121 #endif
122 #if OPENTHREAD_FTD
123 , mJoinerRouter(aInstance)
124 , mLeader(aInstance)
125 , mAddressResolver(aInstance)
126 #endif
127 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
128 , mBackboneRouterLeader(aInstance)
129 #endif
130 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
131 , mBackboneRouterLocal(aInstance)
132 , mBackboneRouterManager(aInstance)
133 #endif
134 #if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
135 , mMlrManager(aInstance)
136 #endif
137
138 #if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
139 , mDuaManager(aInstance)
140 #endif
141 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
142 , mSrpServer(aInstance)
143 #endif
144
145 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
146 #if OPENTHREAD_FTD
147 , mChildSupervisor(aInstance)
148 #endif
149 , mSupervisionListener(aInstance)
150 #endif
151 , mAnnounceBegin(aInstance)
152 , mPanIdQuery(aInstance)
153 , mEnergyScan(aInstance)
154 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
155 , mTimeSync(aInstance)
156 #endif
157 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
158 , mLinkMetrics(aInstance)
159 #endif
160 {
161 }
162
Up(void)163 void ThreadNetif::Up(void)
164 {
165 VerifyOrExit(!mIsUp);
166
167 // Enable the MAC just in case it was disabled while the Interface was down.
168 Get<Mac::Mac>().SetEnabled(true);
169 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
170 IgnoreError(Get<Utils::ChannelMonitor>().Start());
171 #endif
172 Get<MeshForwarder>().Start();
173
174 mIsUp = true;
175
176 SubscribeAllNodesMulticast();
177 IgnoreError(Get<Mle::MleRouter>().Enable());
178 IgnoreError(Get<Tmf::Agent>().Start());
179 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
180 IgnoreError(Get<Dns::ServiceDiscovery::Server>().Start());
181 #endif
182 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
183 IgnoreError(Get<Dns::Client>().Start());
184 #endif
185 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
186 IgnoreError(Get<Sntp::Client>().Start());
187 #endif
188 Get<Notifier>().Signal(kEventThreadNetifStateChanged);
189
190 exit:
191 return;
192 }
193
Down(void)194 void ThreadNetif::Down(void)
195 {
196 VerifyOrExit(mIsUp);
197
198 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
199 Get<Dns::Client>().Stop();
200 #endif
201 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
202 IgnoreError(Get<Sntp::Client>().Stop());
203 #endif
204 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
205 Get<Dns::ServiceDiscovery::Server>().Stop();
206 #endif
207 #if OPENTHREAD_CONFIG_DTLS_ENABLE
208 Get<Coap::CoapSecure>().Stop();
209 #endif
210 IgnoreError(Get<Tmf::Agent>().Stop());
211 IgnoreError(Get<Mle::MleRouter>().Disable());
212 RemoveAllExternalUnicastAddresses();
213 UnsubscribeAllExternalMulticastAddresses();
214 UnsubscribeAllRoutersMulticast();
215 UnsubscribeAllNodesMulticast();
216
217 mIsUp = false;
218 Get<MeshForwarder>().Stop();
219 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
220 IgnoreError(Get<Utils::ChannelMonitor>().Stop());
221 #endif
222 Get<Notifier>().Signal(kEventThreadNetifStateChanged);
223
224 exit:
225 return;
226 }
227
RouteLookup(const Ip6::Address & aSource,const Ip6::Address & aDestination,uint8_t * aPrefixMatch)228 Error ThreadNetif::RouteLookup(const Ip6::Address &aSource, const Ip6::Address &aDestination, uint8_t *aPrefixMatch)
229 {
230 Error error;
231 uint16_t rloc;
232
233 SuccessOrExit(error = Get<NetworkData::Leader>().RouteLookup(aSource, aDestination, aPrefixMatch, &rloc));
234
235 if (rloc == Get<Mle::MleRouter>().GetRloc16())
236 {
237 error = kErrorNoRoute;
238 }
239
240 exit:
241 return error;
242 }
243
IsOnMesh(const Ip6::Address & aAddress) const244 bool ThreadNetif::IsOnMesh(const Ip6::Address &aAddress) const
245 {
246 return Get<NetworkData::Leader>().IsOnMesh(aAddress);
247 }
248
249 } // namespace ot
250