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