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