xref: /aosp_15_r20/external/ot-br-posix/src/ncp/posix/netif.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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