• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "vnic_manager.h"
17 
18 #include <arpa/inet.h>
19 #include <fcntl.h>
20 #include <linux/if.h>
21 #include <linux/if_tun.h>
22 #include <linux/ipv6.h>
23 #include <netinet/in.h>
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <sys/un.h>
28 #include <thread>
29 #include <unistd.h>
30 
31 #include "init_socket.h"
32 #include "net_manager_constants.h"
33 #include "netlink_socket_diag.h"
34 #include "netmanager_base_common_utils.h"
35 #include "netnative_log_wrapper.h"
36 #include "route_manager.h"
37 #include "securec.h"
38 
39 #include "uid_range.h"
40 
41 namespace OHOS {
42 namespace NetManagerStandard {
43 
44 namespace {
45 constexpr const char *VNIC_TUN_CARD_NAME = "vnic-tun";
46 constexpr const char *VNIC_TUN_DEVICE_PATH = "/dev/tun";
47 constexpr int32_t NET_MASK_MAX_LENGTH = 32;
48 constexpr uint32_t MAX_VNIC_UID_ARRAY_SIZE = 20;
49 } // namespace
50 
51 
GetNetSock(bool ipv4)52 std::atomic_int& VnicManager::GetNetSock(bool ipv4)
53 {
54     if (ipv4) {
55         // LCOV_EXCL_START
56         if (net4Sock_ < 0) {
57             net4Sock_ = socket(AF_INET, SOCK_DGRAM, 0);
58         }
59         // LCOV_EXCL_STOP
60         return net4Sock_;
61     } else {
62         // LCOV_EXCL_START
63         if (net6Sock_ < 0) {
64             net6Sock_ = socket(AF_INET6, SOCK_DGRAM, 0);
65         }
66         // LCOV_EXCL_STOP
67         return net6Sock_;
68     }
69 }
70 
CreateVnicInterface()71 int32_t VnicManager::CreateVnicInterface()
72 {
73     // LCOV_EXCL_START
74     if (tunFd_ != 0) {
75         return NETMANAGER_SUCCESS;
76     }
77     // LCOV_EXCL_STOP
78 
79     ifreq ifr{};
80     if (InitIfreq(ifr, VNIC_TUN_CARD_NAME) != NETMANAGER_SUCCESS) {
81         return NETMANAGER_ERROR;
82     }
83 
84     int32_t tunfd = open(VNIC_TUN_DEVICE_PATH, O_RDWR | O_NONBLOCK);
85     // LCOV_EXCL_START
86     if (tunfd <= 0) {
87         NETNATIVE_LOGE("open virtual device failed: %{public}d", errno);
88         return NETMANAGER_ERROR;
89     }
90 
91     ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
92     if (ioctl(tunfd, TUNSETIFF, &ifr) < 0) {
93         close(tunfd);
94         NETNATIVE_LOGE("tun set iff error: %{public}d", errno);
95         return NETMANAGER_ERROR;
96     }
97 
98     net4Sock_ = socket(AF_INET, SOCK_DGRAM, 0);
99     if (net4Sock_ < 0) {
100         NETNATIVE_LOGE("create SOCK_DGRAM ipv4 failed: %{public}d", errno);
101     }
102     net6Sock_ = socket(AF_INET6, SOCK_DGRAM, 0);
103     if (net6Sock_ < 0) {
104         NETNATIVE_LOGE("create SOCK_DGRAM ipv6 failed: %{public}d", errno);
105     }
106 
107     if (net4Sock_ < 0 && net6Sock_ < 0) {
108         close(tunfd);
109         NETNATIVE_LOGE("create SOCK_DGRAM ip failed");
110         return NETMANAGER_ERROR;
111     }
112     // LCOV_EXCL_STOP
113 
114     NETNATIVE_LOGI("open virtual device successfully, [%{public}d]", tunfd);
115     tunFd_ = tunfd;
116     SetVnicUp();
117     return NETMANAGER_SUCCESS;
118 }
119 
DestroyVnicInterface()120 void VnicManager::DestroyVnicInterface()
121 {
122     SetVnicDown();
123     if (net4Sock_ != 0) {
124         close(net4Sock_);
125         net4Sock_ = 0;
126     }
127     if (net6Sock_ != 0) {
128         close(net6Sock_);
129         net6Sock_ = 0;
130     }
131     if (tunFd_ != 0) {
132         close(tunFd_);
133         tunFd_ = 0;
134     }
135 }
136 
SetVnicResult(std::atomic_int & fd,unsigned long cmd,ifreq & ifr)137 int32_t VnicManager::SetVnicResult(std::atomic_int &fd, unsigned long cmd, ifreq &ifr)
138 {
139     if (fd > 0) {
140         // LCOV_EXCL_START
141         if (ioctl(fd, cmd, &ifr) < 0) {
142             NETNATIVE_LOGE("set vnic error, errno:%{public}d", errno);
143             return NETMANAGER_ERROR;
144         }
145         // LCOV_EXCL_STOP
146     }
147     return NETMANAGER_SUCCESS;
148 }
149 
SetVnicMtu(const std::string & ifName,int32_t mtu)150 int32_t VnicManager::SetVnicMtu(const std::string &ifName, int32_t mtu)
151 {
152     if (mtu <= 0) {
153         NETNATIVE_LOGE("invalid mtu value");
154         return NETMANAGER_ERROR;
155     }
156 
157     ifreq ifr;
158     if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
159         return NETMANAGER_ERROR;
160     }
161 
162     ifr.ifr_mtu = mtu;
163     int32_t ret4 = SetVnicResult(GetNetSock(true), SIOCSIFMTU, ifr);
164     int32_t ret6 = SetVnicResult(GetNetSock(false), SIOCSIFMTU, ifr);
165     if (ret4 == NETMANAGER_ERROR || ret6 == NETMANAGER_ERROR || (GetNetSock(true) < 0 && GetNetSock(false) < 0)) {
166         NETNATIVE_LOGI("set MTU failed");
167         return NETMANAGER_ERROR;
168     } else {
169         NETNATIVE_LOGI("set MTU success");
170         return NETMANAGER_SUCCESS;
171     }
172 }
173 
SetVnicAddress(const std::string & ifName,const std::string & tunAddr,int32_t prefix)174 int32_t VnicManager::SetVnicAddress(const std::string &ifName, const std::string &tunAddr, int32_t prefix)
175 {
176     ifreq ifr{};
177     if (InitIfreq(ifr, ifName) != NETMANAGER_SUCCESS) {
178         return NETMANAGER_ERROR;
179     }
180 
181     bool isIpv6 = CommonUtils::IsValidIPV6(tunAddr);
182     if (isIpv6) {
183         struct in6_ifreq ifr6 = {};
184         if (ioctl(GetNetSock(false), SIOCGIFINDEX, &ifr) <0) {
185             NETNATIVE_LOGE(" get network interface ipv6 failed: %{public}d", errno);
186             return NETMANAGER_ERROR;
187         }
188         if (inet_pton(AF_INET6, tunAddr.c_str(), &ifr6.ifr6_addr) == 0) {
189             NETNATIVE_LOGE("inet_pton ipv6 address failed: %{public}d", errno);
190         }
191         ifr6.ifr6_prefixlen = static_cast<uint32_t>(prefix);
192         ifr6.ifr6_ifindex = ifr.ifr_ifindex;
193         if (ioctl(GetNetSock(false), SIOCSIFADDR, &ifr6) < 0) {
194             NETNATIVE_LOGE("ioctl set ipv6 address failed: %{public}d", errno);
195             return NETMANAGER_ERROR;
196         }
197     } else {
198         in_addr ipv4Addr = {};
199         if (inet_aton(tunAddr.c_str(), &ipv4Addr) == 0) {
200             NETNATIVE_LOGE("addr inet_aton error");
201             return NETMANAGER_ERROR;
202         }
203 
204         auto sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_addr);
205         sin->sin_family = AF_INET;
206         sin->sin_addr = ipv4Addr;
207         if (ioctl(GetNetSock(true), SIOCSIFADDR, &ifr) < 0) {
208             NETNATIVE_LOGE("ioctl set ipv4 address failed: %{public}d", errno);
209             return NETMANAGER_ERROR;
210         }
211 
212         if (prefix <= 0 || prefix >= NET_MASK_MAX_LENGTH) {
213             NETNATIVE_LOGE("prefix: %{public}d error", prefix);
214             return NETMANAGER_ERROR;
215         }
216         in_addr_t mask = prefix ? (0xFFFFFFFF << (NET_MASK_MAX_LENGTH - prefix)) : 0;
217         sin = reinterpret_cast<sockaddr_in *>(&ifr.ifr_netmask);
218         sin->sin_family = AF_INET;
219         sin->sin_addr.s_addr = htonl(mask);
220         if (ioctl(GetNetSock(true), SIOCSIFNETMASK, &ifr) < 0) {
221             NETNATIVE_LOGE("ioctl set ip mask failed: %{public}d", errno);
222             return NETMANAGER_ERROR;
223         }
224     }
225 
226     NETNATIVE_LOGI("set ip address success");
227     return NETMANAGER_SUCCESS;
228 }
229 
SetVnicUp()230 int32_t VnicManager::SetVnicUp()
231 {
232     ifreq ifr{};
233     if (InitIfreq(ifr, VNIC_TUN_CARD_NAME) != NETMANAGER_SUCCESS) {
234         return NETMANAGER_ERROR;
235     }
236 
237     ifr.ifr_flags = IFF_UP;
238     int32_t ret4 = SetVnicResult(GetNetSock(true), SIOCSIFFLAGS, ifr);
239     int32_t ret6 = SetVnicResult(GetNetSock(false), SIOCSIFFLAGS, ifr);
240     if (ret4 == NETMANAGER_ERROR || ret6 == NETMANAGER_ERROR || (GetNetSock(true) < 0 && GetNetSock(false) < 0)) {
241         NETNATIVE_LOGI("set iff up failed");
242         return NETMANAGER_ERROR;
243     } else {
244         NETNATIVE_LOGI("set iff up success");
245         return NETMANAGER_SUCCESS;
246     }
247 }
248 
SetVnicDown()249 int32_t VnicManager::SetVnicDown()
250 {
251     ifreq ifr{};
252     if (InitIfreq(ifr, VNIC_TUN_CARD_NAME) != NETMANAGER_SUCCESS) {
253         return NETMANAGER_ERROR;
254     }
255 
256     ifr.ifr_flags = (uint16_t)ifr.ifr_flags & ~IFF_UP;
257     int32_t ret4 = SetVnicResult(GetNetSock(true), SIOCSIFFLAGS, ifr);
258     int32_t ret6 = SetVnicResult(GetNetSock(false), SIOCSIFFLAGS, ifr);
259     if (ret4 == NETMANAGER_ERROR || ret6 == NETMANAGER_ERROR || (GetNetSock(true) < 0 && GetNetSock(false) < 0)) {
260         NETNATIVE_LOGI("set iff down failed");
261         return NETMANAGER_ERROR;
262     } else {
263         NETNATIVE_LOGI("set iff down success");
264         return NETMANAGER_SUCCESS;
265     }
266 }
267 
AddDefaultRoute()268 int32_t VnicManager::AddDefaultRoute()
269 {
270     const std::string interface = VNIC_TUN_CARD_NAME;
271     const std::string destinationName = "0.0.0.0/0";
272     const std::string nextHop = "0.0.0.0";
273     return nmd::RouteManager::UpdateVnicRoute(interface, destinationName, nextHop, true);
274 }
275 
DelDefaultRoute()276 int32_t VnicManager::DelDefaultRoute()
277 {
278     const std::string interface = VNIC_TUN_CARD_NAME;
279     const std::string destinationName = "0.0.0.0/0";
280     const std::string nextHop = "0.0.0.0";
281     return nmd::RouteManager::UpdateVnicRoute(interface, destinationName, nextHop, false);
282 }
283 
InitIfreq(ifreq & ifr,const std::string & cardName)284 int32_t VnicManager::InitIfreq(ifreq &ifr, const std::string &cardName)
285 {
286     if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
287         NETNATIVE_LOGE("memset_s ifr failed!");
288         return NETMANAGER_ERROR;
289     }
290     if (strncpy_s(ifr.ifr_name, IFNAMSIZ, cardName.c_str(), strlen(cardName.c_str())) != EOK) {
291         NETNATIVE_LOGE("strcpy_s ifr name fail");
292         return NETMANAGER_ERROR;
293     }
294     return NETMANAGER_SUCCESS;
295 }
296 
CreateVnic(uint16_t mtu,const std::string & tunAddr,int32_t prefix,const std::set<int32_t> & uids)297 int32_t VnicManager::CreateVnic(uint16_t mtu, const std::string &tunAddr, int32_t prefix,
298                                 const std::set<int32_t> &uids)
299 {
300     std::unique_lock<std::mutex> lock(vnicMutex_);
301     if (uids.size() > MAX_VNIC_UID_ARRAY_SIZE) {
302         NETNATIVE_LOGE("vnic uids's size is over the max size.");
303         return NETMANAGER_ERROR;
304     }
305 
306     uidRanges.clear();
307     for (const auto &uid: uids) {
308         uidRanges.push_back({uid, uid});
309     }
310 
311     if (CreateVnicInterface() != NETMANAGER_SUCCESS) {
312         return NETMANAGER_ERROR;
313     }
314     if (SetVnicMtu(VNIC_TUN_CARD_NAME, mtu) != NETMANAGER_SUCCESS ||
315         SetVnicAddress(VNIC_TUN_CARD_NAME, tunAddr, prefix) != NETMANAGER_SUCCESS ||
316         AddDefaultRoute() != NETMANAGER_SUCCESS) {
317         DestroyVnicInterface();
318         return NETMANAGER_ERROR;
319     }
320 
321     if (!uidRanges.empty() &&
322         nmd::RouteManager::UpdateVnicUidRangesRule(uidRanges, true) != NETMANAGER_SUCCESS) {
323         uidRanges.clear();
324         DelDefaultRoute();
325         DestroyVnicInterface();
326         return NETMANAGER_ERROR;
327     }
328 
329     nmd::NetLinkSocketDiag socketDiag;
330     for (auto const &uid : uidRanges) {
331         NETNATIVE_LOG_D("CreateVnic uid %{public}d", (uint32_t)uid.begin_);
332         socketDiag.DestroyLiveSocketsWithUid((uint32_t)uid.begin_);
333     }
334 
335     return NETMANAGER_SUCCESS;
336 }
337 
DestroyVnic()338 int32_t VnicManager::DestroyVnic()
339 {
340     std::unique_lock<std::mutex> lock(vnicMutex_);
341     nmd::NetLinkSocketDiag socketDiag;
342     nmd::RouteManager::UpdateVnicUidRangesRule(uidRanges, false);
343     DelDefaultRoute();
344     DestroyVnicInterface();
345     for (auto const &uid : uidRanges) {
346         NETNATIVE_LOG_D("DestroyVnic uid %{public}d", (uint32_t)uid.begin_);
347         socketDiag.DestroyLiveSocketsWithUid((uint32_t)uid.begin_);
348     }
349     uidRanges.clear();
350     return NETMANAGER_SUCCESS;
351 }
352 
353 } // namespace NetManagerStandard
354 } // namespace OHOS
355