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