1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker * Copyright (c) 2024, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker * All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker *
5*4a64e381SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker *
16*4a64e381SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker */
28*4a64e381SAndroid Build Coastguard Worker
29*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "NETIF"
30*4a64e381SAndroid Build Coastguard Worker
31*4a64e381SAndroid Build Coastguard Worker #include "netif.hpp"
32*4a64e381SAndroid Build Coastguard Worker
33*4a64e381SAndroid Build Coastguard Worker #include <errno.h>
34*4a64e381SAndroid Build Coastguard Worker #include <fcntl.h>
35*4a64e381SAndroid Build Coastguard Worker #include <net/if.h>
36*4a64e381SAndroid Build Coastguard Worker #include <net/if_arp.h>
37*4a64e381SAndroid Build Coastguard Worker #include <netinet/in.h>
38*4a64e381SAndroid Build Coastguard Worker #include <stdio.h>
39*4a64e381SAndroid Build Coastguard Worker #include <string.h>
40*4a64e381SAndroid Build Coastguard Worker #include <sys/ioctl.h>
41*4a64e381SAndroid Build Coastguard Worker #include <sys/socket.h>
42*4a64e381SAndroid Build Coastguard Worker #include <unistd.h>
43*4a64e381SAndroid Build Coastguard Worker
44*4a64e381SAndroid Build Coastguard Worker #include <algorithm>
45*4a64e381SAndroid Build Coastguard Worker
46*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
47*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
48*4a64e381SAndroid Build Coastguard Worker #include "common/types.hpp"
49*4a64e381SAndroid Build Coastguard Worker #include "utils/socket_utils.hpp"
50*4a64e381SAndroid Build Coastguard Worker
51*4a64e381SAndroid Build Coastguard Worker namespace otbr {
52*4a64e381SAndroid Build Coastguard Worker
Netif(void)53*4a64e381SAndroid Build Coastguard Worker Netif::Netif(void)
54*4a64e381SAndroid Build Coastguard Worker : mTunFd(-1)
55*4a64e381SAndroid Build Coastguard Worker , mIpFd(-1)
56*4a64e381SAndroid Build Coastguard Worker , mNetlinkFd(-1)
57*4a64e381SAndroid Build Coastguard Worker , mNetlinkSequence(0)
58*4a64e381SAndroid Build Coastguard Worker , mNetifIndex(0)
59*4a64e381SAndroid Build Coastguard Worker {
60*4a64e381SAndroid Build Coastguard Worker }
61*4a64e381SAndroid Build Coastguard Worker
Init(const std::string & aInterfaceName,const Ip6SendFunc & aIp6SendFunc)62*4a64e381SAndroid Build Coastguard Worker otbrError Netif::Init(const std::string &aInterfaceName, const Ip6SendFunc &aIp6SendFunc)
63*4a64e381SAndroid Build Coastguard Worker {
64*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
65*4a64e381SAndroid Build Coastguard Worker
66*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aIp6SendFunc, error = OTBR_ERROR_INVALID_ARGS);
67*4a64e381SAndroid Build Coastguard Worker mIp6SendFunc = aIp6SendFunc;
68*4a64e381SAndroid Build Coastguard Worker
69*4a64e381SAndroid Build Coastguard Worker mIpFd = SocketWithCloseExec(AF_INET6, SOCK_DGRAM, IPPROTO_IP, kSocketNonBlock);
70*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mIpFd >= 0, error = OTBR_ERROR_ERRNO);
71*4a64e381SAndroid Build Coastguard Worker
72*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = CreateTunDevice(aInterfaceName));
73*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = InitNetlink());
74*4a64e381SAndroid Build Coastguard Worker
75*4a64e381SAndroid Build Coastguard Worker mNetifIndex = if_nametoindex(mNetifName.c_str());
76*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mNetifIndex > 0, error = OTBR_ERROR_INVALID_STATE);
77*4a64e381SAndroid Build Coastguard Worker
78*4a64e381SAndroid Build Coastguard Worker PlatformSpecificInit();
79*4a64e381SAndroid Build Coastguard Worker
80*4a64e381SAndroid Build Coastguard Worker exit:
81*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
82*4a64e381SAndroid Build Coastguard Worker {
83*4a64e381SAndroid Build Coastguard Worker Clear();
84*4a64e381SAndroid Build Coastguard Worker }
85*4a64e381SAndroid Build Coastguard Worker return error;
86*4a64e381SAndroid Build Coastguard Worker }
87*4a64e381SAndroid Build Coastguard Worker
Deinit(void)88*4a64e381SAndroid Build Coastguard Worker void Netif::Deinit(void)
89*4a64e381SAndroid Build Coastguard Worker {
90*4a64e381SAndroid Build Coastguard Worker Clear();
91*4a64e381SAndroid Build Coastguard Worker }
92*4a64e381SAndroid Build Coastguard Worker
Process(const MainloopContext * aContext)93*4a64e381SAndroid Build Coastguard Worker void Netif::Process(const MainloopContext *aContext)
94*4a64e381SAndroid Build Coastguard Worker {
95*4a64e381SAndroid Build Coastguard Worker if (FD_ISSET(mTunFd, &aContext->mErrorFdSet))
96*4a64e381SAndroid Build Coastguard Worker {
97*4a64e381SAndroid Build Coastguard Worker close(mTunFd);
98*4a64e381SAndroid Build Coastguard Worker DieNow("Error on Tun Fd!");
99*4a64e381SAndroid Build Coastguard Worker }
100*4a64e381SAndroid Build Coastguard Worker
101*4a64e381SAndroid Build Coastguard Worker if (FD_ISSET(mTunFd, &aContext->mReadFdSet))
102*4a64e381SAndroid Build Coastguard Worker {
103*4a64e381SAndroid Build Coastguard Worker ProcessIp6Send();
104*4a64e381SAndroid Build Coastguard Worker }
105*4a64e381SAndroid Build Coastguard Worker }
106*4a64e381SAndroid Build Coastguard Worker
UpdateFdSet(MainloopContext * aContext)107*4a64e381SAndroid Build Coastguard Worker void Netif::UpdateFdSet(MainloopContext *aContext)
108*4a64e381SAndroid Build Coastguard Worker {
109*4a64e381SAndroid Build Coastguard Worker assert(aContext != nullptr);
110*4a64e381SAndroid Build Coastguard Worker assert(mTunFd >= 0);
111*4a64e381SAndroid Build Coastguard Worker assert(mIpFd >= 0);
112*4a64e381SAndroid Build Coastguard Worker
113*4a64e381SAndroid Build Coastguard Worker aContext->AddFdToSet(mTunFd, MainloopContext::kErrorFdSet | MainloopContext::kReadFdSet);
114*4a64e381SAndroid Build Coastguard Worker }
115*4a64e381SAndroid Build Coastguard Worker
UpdateIp6UnicastAddresses(const std::vector<Ip6AddressInfo> & aAddrInfos)116*4a64e381SAndroid Build Coastguard Worker void Netif::UpdateIp6UnicastAddresses(const std::vector<Ip6AddressInfo> &aAddrInfos)
117*4a64e381SAndroid Build Coastguard Worker {
118*4a64e381SAndroid Build Coastguard Worker // Remove stale addresses
119*4a64e381SAndroid Build Coastguard Worker for (const Ip6AddressInfo &addrInfo : mIp6UnicastAddresses)
120*4a64e381SAndroid Build Coastguard Worker {
121*4a64e381SAndroid Build Coastguard Worker if (std::find(aAddrInfos.begin(), aAddrInfos.end(), addrInfo) == aAddrInfos.end())
122*4a64e381SAndroid Build Coastguard Worker {
123*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Remove address: %s", Ip6Address(addrInfo.mAddress).ToString().c_str());
124*4a64e381SAndroid Build Coastguard Worker // TODO: Verify success of the addition or deletion in Netlink response.
125*4a64e381SAndroid Build Coastguard Worker ProcessUnicastAddressChange(addrInfo, false);
126*4a64e381SAndroid Build Coastguard Worker }
127*4a64e381SAndroid Build Coastguard Worker }
128*4a64e381SAndroid Build Coastguard Worker
129*4a64e381SAndroid Build Coastguard Worker // Add new addresses
130*4a64e381SAndroid Build Coastguard Worker for (const Ip6AddressInfo &addrInfo : aAddrInfos)
131*4a64e381SAndroid Build Coastguard Worker {
132*4a64e381SAndroid Build Coastguard Worker if (std::find(mIp6UnicastAddresses.begin(), mIp6UnicastAddresses.end(), addrInfo) == mIp6UnicastAddresses.end())
133*4a64e381SAndroid Build Coastguard Worker {
134*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Add address: %s", Ip6Address(addrInfo.mAddress).ToString().c_str());
135*4a64e381SAndroid Build Coastguard Worker // TODO: Verify success of the addition or deletion in Netlink response.
136*4a64e381SAndroid Build Coastguard Worker ProcessUnicastAddressChange(addrInfo, true);
137*4a64e381SAndroid Build Coastguard Worker }
138*4a64e381SAndroid Build Coastguard Worker }
139*4a64e381SAndroid Build Coastguard Worker
140*4a64e381SAndroid Build Coastguard Worker mIp6UnicastAddresses.assign(aAddrInfos.begin(), aAddrInfos.end());
141*4a64e381SAndroid Build Coastguard Worker }
142*4a64e381SAndroid Build Coastguard Worker
UpdateIp6MulticastAddresses(const std::vector<Ip6Address> & aAddrs)143*4a64e381SAndroid Build Coastguard Worker otbrError Netif::UpdateIp6MulticastAddresses(const std::vector<Ip6Address> &aAddrs)
144*4a64e381SAndroid Build Coastguard Worker {
145*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
146*4a64e381SAndroid Build Coastguard Worker
147*4a64e381SAndroid Build Coastguard Worker // Remove stale addresses
148*4a64e381SAndroid Build Coastguard Worker for (const Ip6Address &address : mIp6MulticastAddresses)
149*4a64e381SAndroid Build Coastguard Worker {
150*4a64e381SAndroid Build Coastguard Worker if (std::find(aAddrs.begin(), aAddrs.end(), address) == aAddrs.end())
151*4a64e381SAndroid Build Coastguard Worker {
152*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Remove address: %s", Ip6Address(address).ToString().c_str());
153*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = ProcessMulticastAddressChange(address, /* aIsAdded */ false));
154*4a64e381SAndroid Build Coastguard Worker }
155*4a64e381SAndroid Build Coastguard Worker }
156*4a64e381SAndroid Build Coastguard Worker
157*4a64e381SAndroid Build Coastguard Worker // Add new addresses
158*4a64e381SAndroid Build Coastguard Worker for (const Ip6Address &address : aAddrs)
159*4a64e381SAndroid Build Coastguard Worker {
160*4a64e381SAndroid Build Coastguard Worker if (std::find(mIp6MulticastAddresses.begin(), mIp6MulticastAddresses.end(), address) ==
161*4a64e381SAndroid Build Coastguard Worker mIp6MulticastAddresses.end())
162*4a64e381SAndroid Build Coastguard Worker {
163*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Add address: %s", Ip6Address(address).ToString().c_str());
164*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = ProcessMulticastAddressChange(address, /* aIsAdded */ true));
165*4a64e381SAndroid Build Coastguard Worker }
166*4a64e381SAndroid Build Coastguard Worker }
167*4a64e381SAndroid Build Coastguard Worker
168*4a64e381SAndroid Build Coastguard Worker mIp6MulticastAddresses.assign(aAddrs.begin(), aAddrs.end());
169*4a64e381SAndroid Build Coastguard Worker
170*4a64e381SAndroid Build Coastguard Worker exit:
171*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
172*4a64e381SAndroid Build Coastguard Worker {
173*4a64e381SAndroid Build Coastguard Worker mIp6MulticastAddresses.clear();
174*4a64e381SAndroid Build Coastguard Worker }
175*4a64e381SAndroid Build Coastguard Worker return error;
176*4a64e381SAndroid Build Coastguard Worker }
177*4a64e381SAndroid Build Coastguard Worker
ProcessMulticastAddressChange(const Ip6Address & aAddress,bool aIsAdded)178*4a64e381SAndroid Build Coastguard Worker otbrError Netif::ProcessMulticastAddressChange(const Ip6Address &aAddress, bool aIsAdded)
179*4a64e381SAndroid Build Coastguard Worker {
180*4a64e381SAndroid Build Coastguard Worker struct ipv6_mreq mreq;
181*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
182*4a64e381SAndroid Build Coastguard Worker int err;
183*4a64e381SAndroid Build Coastguard Worker
184*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mIpFd >= 0, error = OTBR_ERROR_INVALID_STATE);
185*4a64e381SAndroid Build Coastguard Worker memcpy(&mreq.ipv6mr_multiaddr, &aAddress, sizeof(mreq.ipv6mr_multiaddr));
186*4a64e381SAndroid Build Coastguard Worker mreq.ipv6mr_interface = mNetifIndex;
187*4a64e381SAndroid Build Coastguard Worker
188*4a64e381SAndroid Build Coastguard Worker err = setsockopt(mIpFd, IPPROTO_IPV6, (aIsAdded ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP), &mreq, sizeof(mreq));
189*4a64e381SAndroid Build Coastguard Worker
190*4a64e381SAndroid Build Coastguard Worker if (err != 0)
191*4a64e381SAndroid Build Coastguard Worker {
192*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("%s failure (%d)", aIsAdded ? "IPV6_JOIN_GROUP" : "IPV6_LEAVE_GROUP", errno);
193*4a64e381SAndroid Build Coastguard Worker ExitNow(error = OTBR_ERROR_ERRNO);
194*4a64e381SAndroid Build Coastguard Worker }
195*4a64e381SAndroid Build Coastguard Worker
196*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("%s multicast address %s", aIsAdded ? "Added" : "Removed", Ip6Address(aAddress).ToString().c_str());
197*4a64e381SAndroid Build Coastguard Worker
198*4a64e381SAndroid Build Coastguard Worker exit:
199*4a64e381SAndroid Build Coastguard Worker return error;
200*4a64e381SAndroid Build Coastguard Worker }
201*4a64e381SAndroid Build Coastguard Worker
SetNetifState(bool aState)202*4a64e381SAndroid Build Coastguard Worker void Netif::SetNetifState(bool aState)
203*4a64e381SAndroid Build Coastguard Worker {
204*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
205*4a64e381SAndroid Build Coastguard Worker struct ifreq ifr;
206*4a64e381SAndroid Build Coastguard Worker bool ifState = false;
207*4a64e381SAndroid Build Coastguard Worker
208*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mIpFd >= 0);
209*4a64e381SAndroid Build Coastguard Worker memset(&ifr, 0, sizeof(ifr));
210*4a64e381SAndroid Build Coastguard Worker strncpy(ifr.ifr_name, mNetifName.c_str(), IFNAMSIZ - 1);
211*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(ioctl(mIpFd, SIOCGIFFLAGS, &ifr) == 0, error = OTBR_ERROR_ERRNO);
212*4a64e381SAndroid Build Coastguard Worker
213*4a64e381SAndroid Build Coastguard Worker ifState = ((ifr.ifr_flags & IFF_UP) == IFF_UP) ? true : false;
214*4a64e381SAndroid Build Coastguard Worker
215*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Changing interface state to %s%s.", aState ? "up" : "down",
216*4a64e381SAndroid Build Coastguard Worker (ifState == aState) ? " (already done, ignoring)" : "");
217*4a64e381SAndroid Build Coastguard Worker
218*4a64e381SAndroid Build Coastguard Worker if (ifState != aState)
219*4a64e381SAndroid Build Coastguard Worker {
220*4a64e381SAndroid Build Coastguard Worker ifr.ifr_flags = aState ? (ifr.ifr_flags | IFF_UP) : (ifr.ifr_flags & ~IFF_UP);
221*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(ioctl(mIpFd, SIOCSIFFLAGS, &ifr) == 0, error = OTBR_ERROR_ERRNO);
222*4a64e381SAndroid Build Coastguard Worker }
223*4a64e381SAndroid Build Coastguard Worker
224*4a64e381SAndroid Build Coastguard Worker exit:
225*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
226*4a64e381SAndroid Build Coastguard Worker {
227*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("Failed to update state %s", otbrErrorString(error));
228*4a64e381SAndroid Build Coastguard Worker }
229*4a64e381SAndroid Build Coastguard Worker }
230*4a64e381SAndroid Build Coastguard Worker
Ip6Receive(const uint8_t * aBuf,uint16_t aLen)231*4a64e381SAndroid Build Coastguard Worker void Netif::Ip6Receive(const uint8_t *aBuf, uint16_t aLen)
232*4a64e381SAndroid Build Coastguard Worker {
233*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
234*4a64e381SAndroid Build Coastguard Worker
235*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(aLen <= kIp6Mtu, error = OTBR_ERROR_DROPPED);
236*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mTunFd > 0, error = OTBR_ERROR_INVALID_STATE);
237*4a64e381SAndroid Build Coastguard Worker
238*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Packet from NCP (%u bytes)", aLen);
239*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(write(mTunFd, aBuf, aLen) == aLen, error = OTBR_ERROR_ERRNO);
240*4a64e381SAndroid Build Coastguard Worker
241*4a64e381SAndroid Build Coastguard Worker exit:
242*4a64e381SAndroid Build Coastguard Worker if (error != OTBR_ERROR_NONE)
243*4a64e381SAndroid Build Coastguard Worker {
244*4a64e381SAndroid Build Coastguard Worker otbrLogWarning("Failed to receive, error:%s", otbrErrorString(error));
245*4a64e381SAndroid Build Coastguard Worker }
246*4a64e381SAndroid Build Coastguard Worker }
247*4a64e381SAndroid Build Coastguard Worker
ProcessIp6Send(void)248*4a64e381SAndroid Build Coastguard Worker void Netif::ProcessIp6Send(void)
249*4a64e381SAndroid Build Coastguard Worker {
250*4a64e381SAndroid Build Coastguard Worker ssize_t rval;
251*4a64e381SAndroid Build Coastguard Worker uint8_t packet[kIp6Mtu];
252*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
253*4a64e381SAndroid Build Coastguard Worker
254*4a64e381SAndroid Build Coastguard Worker rval = read(mTunFd, packet, sizeof(packet));
255*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(rval > 0, error = OTBR_ERROR_ERRNO);
256*4a64e381SAndroid Build Coastguard Worker
257*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Send packet (%hu bytes)", static_cast<uint16_t>(rval));
258*4a64e381SAndroid Build Coastguard Worker
259*4a64e381SAndroid Build Coastguard Worker if (mIp6SendFunc != nullptr)
260*4a64e381SAndroid Build Coastguard Worker {
261*4a64e381SAndroid Build Coastguard Worker error = mIp6SendFunc(packet, rval);
262*4a64e381SAndroid Build Coastguard Worker }
263*4a64e381SAndroid Build Coastguard Worker exit:
264*4a64e381SAndroid Build Coastguard Worker if (error == OTBR_ERROR_ERRNO)
265*4a64e381SAndroid Build Coastguard Worker {
266*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Error reading from Tun Fd: %s", strerror(errno));
267*4a64e381SAndroid Build Coastguard Worker }
268*4a64e381SAndroid Build Coastguard Worker }
269*4a64e381SAndroid Build Coastguard Worker
Clear(void)270*4a64e381SAndroid Build Coastguard Worker void Netif::Clear(void)
271*4a64e381SAndroid Build Coastguard Worker {
272*4a64e381SAndroid Build Coastguard Worker if (mTunFd != -1)
273*4a64e381SAndroid Build Coastguard Worker {
274*4a64e381SAndroid Build Coastguard Worker close(mTunFd);
275*4a64e381SAndroid Build Coastguard Worker mTunFd = -1;
276*4a64e381SAndroid Build Coastguard Worker }
277*4a64e381SAndroid Build Coastguard Worker
278*4a64e381SAndroid Build Coastguard Worker if (mIpFd != -1)
279*4a64e381SAndroid Build Coastguard Worker {
280*4a64e381SAndroid Build Coastguard Worker close(mIpFd);
281*4a64e381SAndroid Build Coastguard Worker mIpFd = -1;
282*4a64e381SAndroid Build Coastguard Worker }
283*4a64e381SAndroid Build Coastguard Worker
284*4a64e381SAndroid Build Coastguard Worker if (mNetlinkFd != -1)
285*4a64e381SAndroid Build Coastguard Worker {
286*4a64e381SAndroid Build Coastguard Worker close(mNetlinkFd);
287*4a64e381SAndroid Build Coastguard Worker mNetlinkFd = -1;
288*4a64e381SAndroid Build Coastguard Worker }
289*4a64e381SAndroid Build Coastguard Worker
290*4a64e381SAndroid Build Coastguard Worker mNetifIndex = 0;
291*4a64e381SAndroid Build Coastguard Worker mIp6UnicastAddresses.clear();
292*4a64e381SAndroid Build Coastguard Worker mIp6MulticastAddresses.clear();
293*4a64e381SAndroid Build Coastguard Worker mIp6SendFunc = nullptr;
294*4a64e381SAndroid Build Coastguard Worker }
295*4a64e381SAndroid Build Coastguard Worker
296*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
297