1 /* 2 * Copyright (c) 2021-2022 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 <arpa/inet.h> 17 #include <cstdint> 18 #include <cstring> 19 #include <iostream> 20 #include <linux/fib_rules.h> 21 #include <linux/netlink.h> 22 #include <linux/rtnetlink.h> 23 #include <map> 24 #include <mutex> 25 #include <net/if.h> 26 #include <netlink_socket.h> 27 #include <sstream> 28 #include <sys/ioctl.h> 29 #include <sys/socket.h> 30 #include <sys/uio.h> 31 #include <unistd.h> 32 33 #include "fwmark.h" 34 #include "net_manager_constants.h" 35 #include "netlink_manager.h" 36 #include "netlink_msg.h" 37 #include "netmanager_base_common_utils.h" 38 #include "netnative_log_wrapper.h" 39 #include "securec.h" 40 41 #include "route_manager.h" 42 43 using namespace OHOS::NetManagerStandard; 44 using namespace OHOS::NetManagerStandard::CommonUtils; 45 namespace OHOS { 46 namespace nmd { 47 namespace { 48 constexpr int32_t RULE_LEVEL_CLAT_TUN = 8000; 49 constexpr int32_t RULE_LEVEL_VPN_OUTPUT_TO_LOCAL = 9000; 50 constexpr int32_t RULE_LEVEL_SECURE_VPN = 10000; 51 constexpr int32_t RULE_LEVEL_VNIC_NETWORK = 10500; 52 constexpr int32_t RULE_LEVEL_EXPLICIT_NETWORK = 11000; 53 constexpr int32_t RULE_LEVEL_OUTPUT_IFACE_VPN = 11500; 54 constexpr int32_t RULE_LEVEL_OUTPUT_INTERFACE = 12000; 55 constexpr int32_t RULE_LEVEL_LOCAL_NETWORK = 13000; 56 constexpr int32_t RULE_LEVEL_SHARING = 14000; 57 constexpr int32_t RULE_LEVEL_DEFAULT = 16000; 58 constexpr uint32_t ROUTE_VNIC_TABLE = 97; 59 constexpr uint32_t ROUTE_VPN_NETWORK_TABLE = 98; 60 constexpr uint32_t ROUTE_LOCAL_NETWORK_TABLE = 99; 61 constexpr uint32_t ROUTE_INTERNAL_DEFAULT_TABLE = 1; 62 constexpr uint32_t OUTPUT_MAX = 128; 63 constexpr uint32_t BIT_32_LEN = 32; 64 constexpr uint32_t BIT_MAX_LEN = 255; 65 constexpr uint32_t DECIMAL_DIGITAL = 10; 66 constexpr uint32_t BYTE_ALIGNMENT = 8; 67 constexpr uint32_t THOUSAND_LEN = 100; 68 constexpr uint16_t LOCAL_NET_ID = 99; 69 constexpr uint16_t NETID_UNSET = 0; 70 constexpr uint32_t MARK_UNSET = 0; 71 constexpr uid_t UID_ROOT = 0; 72 constexpr std::pair<uid_t, uid_t> UID_ALLOW_INTERNAL = {7023, 7023}; 73 constexpr uint32_t ROUTEMANAGER_SUCCESS = 0; 74 constexpr uint32_t ROUTEMANAGER_ERROR = -1; 75 constexpr bool ADD_CONTROL = true; 76 constexpr bool DEL_CONTROL = false; 77 const std::string RULEIIF_LOOPBACK = "lo"; 78 const std::string RULEIIF_NULL = ""; 79 const std::string RULEOIF_NULL = ""; 80 const std::string LOCAL_MANGLE_INPUT = "routectrl_mangle_INPUT"; 81 constexpr const char *NETSYS_ROUTE_INIT_DIR_PATH = "/data/service/el1/public/netmanager/route"; 82 83 struct FibRuleUidRange { 84 __u32 start; 85 __u32 end; 86 }; 87 } // namespace 88 89 std::mutex RouteManager::interfaceToTableLock_; 90 std::map<std::string, uint32_t> RouteManager::interfaceToTable_; 91 RouteManager()92 RouteManager::RouteManager() 93 { 94 Init(); 95 } 96 UpdateVnicRoute(const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop,bool add)97 int32_t RouteManager::UpdateVnicRoute(const std::string &interfaceName, const std::string &destinationName, 98 const std::string &nextHop, bool add) 99 { 100 NETNATIVE_LOGI( 101 "VnicChangeRoute,interfaceName:%{public}s,destination:%{public}s, nextHop:%{public}s, add:%{public}d ", 102 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str(), add); 103 104 RouteInfo routeInfo; 105 routeInfo.routeTable = ROUTE_VNIC_TABLE; 106 routeInfo.routeInterfaceName = interfaceName; 107 routeInfo.routeDestinationName = destinationName; 108 routeInfo.routeNextHop = nextHop; 109 uint16_t flags = add ? (NLM_F_CREATE | NLM_F_EXCL) : NLM_F_EXCL; 110 uint16_t action = add ? RTM_NEWROUTE : RTM_DELROUTE; 111 112 return UpdateRouteRule(action, flags, routeInfo); 113 } 114 AddRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)115 int32_t RouteManager::AddRoute(TableType tableType, const std::string &interfaceName, 116 const std::string &destinationName, const std::string &nextHop) 117 { 118 NETNATIVE_LOGI("AddRoute,interfaceName:%{public}s,destination:%{public}s, nextHop:%{public}s", 119 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str()); 120 121 // This is a user-defined structure used to integrate the information required for setting up routes. 122 RouteInfo routeInfo; 123 if (SetRouteInfo(tableType, interfaceName, destinationName, nextHop, routeInfo) != 0) { 124 return -1; 125 } 126 127 return UpdateRouteRule(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, routeInfo); 128 } 129 RemoveRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)130 int32_t RouteManager::RemoveRoute(TableType tableType, const std::string &interfaceName, 131 const std::string &destinationName, const std::string &nextHop) 132 { 133 NETNATIVE_LOGI("RemoveRoute,interfaceName:%{public}s,destination:%{public}s,nextHop:%{public}s", 134 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str()); 135 136 RouteInfo routeInfo; 137 if (SetRouteInfo(tableType, interfaceName, destinationName, nextHop, routeInfo) != 0) { 138 return -1; 139 } 140 return UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo); 141 } 142 UpdateRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)143 int32_t RouteManager::UpdateRoute(TableType tableType, const std::string &interfaceName, 144 const std::string &destinationName, const std::string &nextHop) 145 { 146 NETNATIVE_LOGI("UpdateRoute,interfaceName:%{public}s,destination:%{public}s,nextHop:%{public}s", 147 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str()); 148 149 RouteInfo routeInfo; 150 if (SetRouteInfo(tableType, interfaceName, destinationName, nextHop, routeInfo) != 0) { 151 return -1; 152 } 153 return UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo); 154 } 155 AddInterfaceToDefaultNetwork(const std::string & interfaceName,NetworkPermission permission)156 int32_t RouteManager::AddInterfaceToDefaultNetwork(const std::string &interfaceName, NetworkPermission permission) 157 { 158 NETNATIVE_LOGI("AddInterfaceToDefaultNetwork, %{public}s;permission:%{public}d;", interfaceName.c_str(), 159 permission); 160 uint32_t table = FindTableByInterfacename(interfaceName); 161 if (table == RT_TABLE_UNSPEC) { 162 return -1; 163 } 164 Fwmark fwmark; 165 fwmark.netId = NETID_UNSET; 166 fwmark.permission = permission; 167 168 Fwmark mask; 169 mask.netId = FWMARK_NET_ID_MASK; 170 mask.permission = permission; 171 172 // This is a user-defined structure used to integrate the information required for setting up rules. 173 RuleInfo ruleInfo; 174 ruleInfo.ruleTable = table; 175 ruleInfo.rulePriority = RULE_LEVEL_DEFAULT; 176 ruleInfo.ruleFwmark = fwmark.intValue; 177 ruleInfo.ruleMask = mask.intValue; 178 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 179 ruleInfo.ruleOif = RULEOIF_NULL; 180 return UpdateRuleInfo(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo); 181 } 182 RemoveInterfaceFromDefaultNetwork(const std::string & interfaceName,NetworkPermission permission)183 int32_t RouteManager::RemoveInterfaceFromDefaultNetwork(const std::string &interfaceName, NetworkPermission permission) 184 { 185 NETNATIVE_LOGI("RemoveInterfaceFromDefaultNetwork, %{public}s;permission:%{public}d;", interfaceName.c_str(), 186 permission); 187 uint32_t table = FindTableByInterfacename(interfaceName); 188 if (table == RT_TABLE_UNSPEC) { 189 return -1; 190 } 191 192 Fwmark fwmark; 193 fwmark.netId = NETID_UNSET; 194 fwmark.permission = permission; 195 196 Fwmark mask; 197 mask.netId = FWMARK_NET_ID_MASK; 198 mask.permission = permission; 199 200 RuleInfo ruleInfo; 201 ruleInfo.ruleTable = table; 202 ruleInfo.rulePriority = RULE_LEVEL_DEFAULT; 203 ruleInfo.ruleFwmark = fwmark.intValue; 204 ruleInfo.ruleMask = mask.intValue; 205 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 206 ruleInfo.ruleOif = RULEOIF_NULL; 207 return UpdateRuleInfo(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo); 208 } 209 AddInterfaceToPhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission)210 int32_t RouteManager::AddInterfaceToPhysicalNetwork(uint16_t netId, const std::string &interfaceName, 211 NetworkPermission permission) 212 { 213 NETNATIVE_LOGI("AddInterfaceToPhysicalNetwork, netId:%{public}d;interfaceName:%{public}s;permission:%{public}d;", 214 netId, interfaceName.c_str(), permission); 215 return UpdatePhysicalNetwork(netId, interfaceName, permission, ADD_CONTROL); 216 } 217 RemoveInterfaceFromPhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission)218 int32_t RouteManager::RemoveInterfaceFromPhysicalNetwork(uint16_t netId, const std::string &interfaceName, 219 NetworkPermission permission) 220 { 221 NETNATIVE_LOGI("RemoveInterfacePhysicalNetwork, netId:%{public}d;interfaceName:%{public}s;permission:%{public}d;", 222 netId, interfaceName.c_str(), permission); 223 if (int32_t ret = UpdatePhysicalNetwork(netId, interfaceName, permission, DEL_CONTROL)) { 224 NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret); 225 return ret; 226 } 227 if (int32_t ret = ClearRoutes(interfaceName, netId)) { 228 NETNATIVE_LOGE("ClearRoutes err, error is %{public}d", ret); 229 return ret; 230 } 231 if (NetManagerStandard::IsInternalNetId(netId)) { 232 NETNATIVE_LOGI("InternalNetId skip"); 233 return 0; 234 } 235 if (int32_t ret = ClearSharingRules(interfaceName)) { 236 NETNATIVE_LOGE("ClearSharingRules err, error is %{public}d", ret); 237 return ret; 238 } 239 240 return 0; 241 } 242 ModifyPhysicalNetworkPermission(uint16_t netId,const std::string & interfaceName,NetworkPermission oldPermission,NetworkPermission newPermission)243 int32_t RouteManager::ModifyPhysicalNetworkPermission(uint16_t netId, const std::string &interfaceName, 244 NetworkPermission oldPermission, NetworkPermission newPermission) 245 { 246 NETNATIVE_LOGI("ModifyPhysicalNetworkPermission, %{public}s", interfaceName.c_str()); 247 if (int32_t ret = UpdatePhysicalNetwork(netId, interfaceName, newPermission, ADD_CONTROL)) { 248 NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret); 249 return ret; 250 } 251 252 return UpdatePhysicalNetwork(netId, interfaceName, newPermission, DEL_CONTROL); 253 } 254 AddInterfaceToVirtualNetwork(int32_t netId,const std::string & interfaceName)255 int32_t RouteManager::AddInterfaceToVirtualNetwork(int32_t netId, const std::string &interfaceName) 256 { 257 return ModifyVirtualNetBasedRules(netId, interfaceName, true); 258 } 259 RemoveInterfaceFromVirtualNetwork(int32_t netId,const std::string & interfaceName)260 int32_t RouteManager::RemoveInterfaceFromVirtualNetwork(int32_t netId, const std::string &interfaceName) 261 { 262 if (ModifyVirtualNetBasedRules(netId, interfaceName, false) != ROUTEMANAGER_SUCCESS) { 263 return ROUTEMANAGER_ERROR; 264 } 265 return ClearRouteInfo(RTM_GETROUTE, ROUTE_VPN_NETWORK_TABLE); 266 } 267 ModifyVirtualNetBasedRules(int32_t netId,const std::string & ifaceName,bool add)268 int32_t RouteManager::ModifyVirtualNetBasedRules(int32_t netId, const std::string &ifaceName, bool add) 269 { 270 NETNATIVE_LOGI("ModifyVirtualNetBasedRules,add===%{public}d", add); 271 uint32_t table = GetRouteTableFromType(RouteManager::VPN_NETWORK, ifaceName); 272 if (table == RT_TABLE_UNSPEC) { 273 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error"); 274 return ROUTEMANAGER_ERROR; 275 } 276 277 // If the rule fails to be added, continue to execute the next rule 278 int32_t ret = UpdateVpnOutputToLocalRule(ifaceName, add); 279 ret += UpdateVpnSystemPermissionRule(netId, table, add); 280 ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add); 281 return ret; 282 } 283 UpdateVpnOutputToLocalRule(const std::string & interfaceName,bool add)284 int32_t RouteManager::UpdateVpnOutputToLocalRule(const std::string &interfaceName, bool add) 285 { 286 RuleInfo ruleInfo; 287 ruleInfo.ruleTable = ROUTE_LOCAL_NETWORK_TABLE; 288 ruleInfo.rulePriority = RULE_LEVEL_VPN_OUTPUT_TO_LOCAL; 289 ruleInfo.ruleFwmark = MARK_UNSET; 290 ruleInfo.ruleMask = MARK_UNSET; 291 if (interfaceName.find("vpn") == std::string::npos) { 292 ruleInfo.ruleIif = interfaceName; 293 } 294 ruleInfo.ruleOif = RULEOIF_NULL; 295 296 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID); 297 } 298 UpdateVpnSystemPermissionRule(int32_t netId,uint32_t table,bool add)299 int32_t RouteManager::UpdateVpnSystemPermissionRule(int32_t netId, uint32_t table, bool add) 300 { 301 Fwmark fwmark; 302 fwmark.netId = netId; 303 NetworkPermission permission = NetworkPermission::PERMISSION_SYSTEM; 304 fwmark.permission = permission; 305 306 Fwmark mask; 307 mask.netId = FWMARK_NET_ID_MASK; 308 mask.permission = permission; 309 310 RuleInfo ruleInfo; 311 ruleInfo.ruleTable = table; 312 ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN; 313 ruleInfo.ruleFwmark = fwmark.intValue; 314 ruleInfo.ruleMask = mask.intValue; 315 ruleInfo.ruleIif = RULEIIF_NULL; 316 ruleInfo.ruleOif = RULEOIF_NULL; 317 318 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID); 319 } 320 AddUsersToVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges)321 int32_t RouteManager::AddUsersToVirtualNetwork(int32_t netId, const std::string &interfaceName, 322 const std::vector<NetManagerStandard::UidRange> &uidRanges) 323 { 324 return UpdateVirtualNetwork(netId, interfaceName, uidRanges, true); 325 } 326 RemoveUsersFromVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges)327 int32_t RouteManager::RemoveUsersFromVirtualNetwork(int32_t netId, const std::string &interfaceName, 328 const std::vector<NetManagerStandard::UidRange> &uidRanges) 329 { 330 return UpdateVirtualNetwork(netId, interfaceName, uidRanges, false); 331 } 332 UpdateVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges,bool add)333 int32_t RouteManager::UpdateVirtualNetwork(int32_t netId, const std::string &interfaceName, 334 const std::vector<NetManagerStandard::UidRange> &uidRanges, bool add) 335 { 336 NETNATIVE_LOGI("UpdateVirtualNetwork, add == %{public}d", add); 337 uint32_t table = GetRouteTableFromType(RouteManager::VPN_NETWORK, interfaceName); 338 if (table == RT_TABLE_UNSPEC) { 339 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error"); 340 return ROUTEMANAGER_ERROR; 341 } 342 int32_t ret = ROUTEMANAGER_SUCCESS; 343 for (auto range : uidRanges) { 344 // If the rule fails to be added, continue to execute the next rule 345 ret += UpdateVpnUidRangeRule(table, range.begin_, range.end_, add); 346 ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, range.begin_, range.end_, add); 347 ret += UpdateOutputInterfaceRulesWithUid(interfaceName, table, PERMISSION_NONE, range.begin_, range.end_, add); 348 } 349 return ret; 350 } 351 UpdateVnicUidRangesRule(const std::vector<NetManagerStandard::UidRange> & uidRanges,bool add)352 int32_t RouteManager::UpdateVnicUidRangesRule(const std::vector<NetManagerStandard::UidRange> &uidRanges, bool add) 353 { 354 int32_t ret = ROUTEMANAGER_SUCCESS; 355 for (const auto &range : uidRanges) { 356 Fwmark fwmark; 357 Fwmark mask; 358 fwmark.protectedFromVpn = false; 359 mask.protectedFromVpn = false; 360 361 RuleInfo ruleInfo; 362 ruleInfo.ruleTable = ROUTE_VNIC_TABLE; 363 ruleInfo.rulePriority = RULE_LEVEL_VNIC_NETWORK; 364 ruleInfo.ruleFwmark = fwmark.intValue; 365 ruleInfo.ruleMask = mask.intValue; 366 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 367 ruleInfo.ruleOif = RULEOIF_NULL; 368 ret += UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, range.begin_, range.end_); 369 } 370 return ret; 371 } 372 UpdateVpnUidRangeRule(uint32_t table,uid_t uidStart,uid_t uidEnd,bool add)373 int32_t RouteManager::UpdateVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd, bool add) 374 { 375 Fwmark fwmark; 376 Fwmark mask; 377 fwmark.protectedFromVpn = false; 378 mask.protectedFromVpn = true; 379 380 RuleInfo ruleInfo; 381 ruleInfo.ruleTable = table; 382 ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN; 383 ruleInfo.ruleFwmark = fwmark.intValue; 384 ruleInfo.ruleMask = mask.intValue; 385 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 386 ruleInfo.ruleOif = RULEOIF_NULL; 387 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd); 388 } 389 UpdateExplicitNetworkRuleWithUid(int32_t netId,uint32_t table,NetworkPermission permission,uid_t uidStart,uid_t uidEnd,bool add)390 int32_t RouteManager::UpdateExplicitNetworkRuleWithUid(int32_t netId, uint32_t table, NetworkPermission permission, 391 uid_t uidStart, uid_t uidEnd, bool add) 392 { 393 NETNATIVE_LOGI("UpdateExplicitNetworkRuleWithUid"); 394 Fwmark fwmark; 395 fwmark.netId = netId; 396 fwmark.explicitlySelected = true; 397 fwmark.permission = permission; 398 399 Fwmark mask; 400 mask.netId = FWMARK_NET_ID_MASK; 401 mask.explicitlySelected = true; 402 mask.permission = permission; 403 404 RuleInfo ruleInfo; 405 ruleInfo.ruleTable = table; 406 ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK; 407 ruleInfo.ruleFwmark = fwmark.intValue; 408 ruleInfo.ruleMask = mask.intValue; 409 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 410 ruleInfo.ruleOif = RULEOIF_NULL; 411 412 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd); 413 } 414 UpdateOutputInterfaceRulesWithUid(const std::string & interface,uint32_t table,NetworkPermission permission,uid_t uidStart,uid_t uidEnd,bool add)415 int32_t RouteManager::UpdateOutputInterfaceRulesWithUid(const std::string &interface, uint32_t table, 416 NetworkPermission permission, uid_t uidStart, uid_t uidEnd, 417 bool add) 418 { 419 NETNATIVE_LOGI("UpdateOutputInterfaceRulesWithUid interface:%{public}s", interface.c_str()); 420 Fwmark fwmark; 421 fwmark.permission = permission; 422 423 Fwmark mask; 424 mask.permission = permission; 425 426 RuleInfo ruleInfo; 427 ruleInfo.ruleTable = table; 428 ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_IFACE_VPN; 429 ruleInfo.ruleFwmark = fwmark.intValue; 430 ruleInfo.ruleMask = mask.intValue; 431 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 432 ruleInfo.ruleOif = interface; 433 434 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd); 435 } 436 AddInterfaceToLocalNetwork(uint16_t netId,const std::string & interfaceName)437 int32_t RouteManager::AddInterfaceToLocalNetwork(uint16_t netId, const std::string &interfaceName) 438 { 439 NETNATIVE_LOGI("AddInterfaceToLocalNetwork, %{public}s", interfaceName.c_str()); 440 if (int32_t ret = UpdateLocalNetwork(netId, interfaceName, ADD_CONTROL)) { 441 NETNATIVE_LOGE("UpdateLocalNetwork err, error is %{public}d", ret); 442 return ret; 443 } 444 std::lock_guard lock(interfaceToTableLock_); 445 interfaceToTable_[interfaceName] = ROUTE_LOCAL_NETWORK_TABLE; 446 447 return 0; 448 } 449 RemoveInterfaceFromLocalNetwork(uint16_t netId,const std::string & interfaceName)450 int32_t RouteManager::RemoveInterfaceFromLocalNetwork(uint16_t netId, const std::string &interfaceName) 451 { 452 NETNATIVE_LOGI("RemoveInterfaceFromLocalNetwork"); 453 if (int32_t ret = UpdateLocalNetwork(netId, interfaceName, DEL_CONTROL)) { 454 NETNATIVE_LOGE("UpdateLocalNetwork err, error is %{public}d", ret); 455 return ret; 456 } 457 std::lock_guard lock(interfaceToTableLock_); 458 interfaceToTable_.erase(interfaceName); 459 460 return 0; 461 } 462 EnableSharing(const std::string & inputInterface,const std::string & outputInterface)463 int32_t RouteManager::EnableSharing(const std::string &inputInterface, const std::string &outputInterface) 464 { 465 return UpdateSharingNetwork(RTM_NEWRULE, inputInterface, outputInterface); 466 } 467 DisableSharing(const std::string & inputInterface,const std::string & outputInterface)468 int32_t RouteManager::DisableSharing(const std::string &inputInterface, const std::string &outputInterface) 469 { 470 return UpdateSharingNetwork(RTM_DELRULE, inputInterface, outputInterface); 471 } 472 ReadAddrGw(const std::string & addr,InetAddr * res)473 int32_t RouteManager::ReadAddrGw(const std::string &addr, InetAddr *res) 474 { 475 if (res == nullptr) { 476 return -1; 477 } 478 479 std::string addressString(addr.c_str()); 480 if (strchr(addr.c_str(), ':')) { 481 res->family = AF_INET6; 482 res->bitlen = OUTPUT_MAX; 483 } else { 484 res->family = AF_INET; 485 res->bitlen = BIT_32_LEN; 486 } 487 488 return inet_pton(res->family, addressString.c_str(), res->data); 489 } 490 ReadAddr(const std::string & addr,InetAddr * res)491 int32_t RouteManager::ReadAddr(const std::string &addr, InetAddr *res) 492 { 493 if (res == nullptr) { 494 return -EINVAL; 495 } 496 497 const char *slashStr = strchr(addr.c_str(), '/'); 498 if (slashStr == nullptr) { 499 return -EINVAL; 500 } 501 502 const char *maskLenStr = slashStr + 1; 503 if (*maskLenStr == 0) { 504 return -EINVAL; 505 } 506 507 char *endptr = nullptr; 508 unsigned templen = strtoul(maskLenStr, &endptr, DECIMAL_DIGITAL); 509 if ((endptr == nullptr) || (templen > BIT_MAX_LEN)) { 510 return -EINVAL; 511 } 512 res->prefixlen = templen; 513 514 std::string addressString(addr.c_str(), slashStr - addr.c_str()); 515 if (strchr(addr.c_str(), ':')) { 516 res->family = AF_INET6; 517 res->bitlen = OUTPUT_MAX; 518 } else { 519 res->family = AF_INET; 520 res->bitlen = BIT_32_LEN; 521 } 522 523 return inet_pton(res->family, addressString.c_str(), res->data); 524 } 525 AddClatTunInterface(const std::string & interfaceName,const std::string & dstAddr,const std::string & nxtHop)526 int32_t RouteManager::AddClatTunInterface(const std::string &interfaceName, const std::string &dstAddr, 527 const std::string &nxtHop) 528 { 529 NETNATIVE_LOGI("AddClatTunInterface, interfaceName:%{public}s; dstAddr:%{public}s; nxtHop:%{public}s;", 530 interfaceName.c_str(), dstAddr.c_str(), nxtHop.c_str()); 531 if (int32_t ret = AddRoute(RouteManager::INTERFACE, interfaceName, dstAddr, nxtHop)) { 532 NETNATIVE_LOGE("AddRoute err, error is %{public}d", ret); 533 return ret; 534 } 535 return UpdateClatTunInterface(interfaceName, PERMISSION_NONE, ADD_CONTROL); 536 } 537 RemoveClatTunInterface(const std::string & interfaceName)538 int32_t RouteManager::RemoveClatTunInterface(const std::string &interfaceName) 539 { 540 NETNATIVE_LOGI("RemoveClatTunInterface, interfaceName:%{public}s", interfaceName.c_str()); 541 if (int32_t ret = UpdateClatTunInterface(interfaceName, PERMISSION_NONE, DEL_CONTROL)) { 542 NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret); 543 return ret; 544 } 545 if (int32_t ret = ClearRoutes(interfaceName)) { 546 NETNATIVE_LOGE("ClearRoutes err, error is %{public}d", ret); 547 return ret; 548 } 549 if (int32_t ret = ClearSharingRules(interfaceName)) { 550 NETNATIVE_LOGE("ClearSharingRules err, error is %{public}d", ret); 551 return ret; 552 } 553 554 return 0; 555 } 556 UpdateClatTunInterface(const std::string & interfaceName,NetworkPermission permission,bool add)557 int32_t RouteManager::UpdateClatTunInterface(const std::string &interfaceName, NetworkPermission permission, bool add) 558 { 559 NETNATIVE_LOGI("UpdateClatTunInterface, interfaceName: %{public}s, permission: %{public}d, add: %{public}d", 560 interfaceName.c_str(), static_cast<int32_t>(permission), add); 561 uint32_t table = FindTableByInterfacename(interfaceName); 562 if (table == RT_TABLE_UNSPEC) { 563 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error"); 564 return -1; 565 } 566 567 Fwmark fwmark; 568 fwmark.permission = permission; 569 570 Fwmark mask; 571 mask.permission = permission; 572 573 RuleInfo ruleInfo; 574 ruleInfo.ruleTable = table; 575 ruleInfo.rulePriority = RULE_LEVEL_CLAT_TUN; 576 ruleInfo.ruleFwmark = fwmark.intValue; 577 ruleInfo.ruleMask = mask.intValue; 578 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 579 ruleInfo.ruleOif = RULEOIF_NULL; 580 581 if (int32_t ret = UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo)) { 582 NETNATIVE_LOGE("UpdateRuleInfo failed, err is %{public}d", ret); 583 return ret; 584 } 585 586 return 0; 587 } 588 Init()589 int32_t RouteManager::Init() 590 { 591 NETNATIVE_LOGI("Init"); 592 // need to call IptablesWrapper's RunCommand function. 593 std::string commandNew; 594 commandNew.append(" -t mangle -N "); 595 commandNew.append(LOCAL_MANGLE_INPUT); 596 597 std::string commandJump; 598 commandJump.append(" -A INPUT -j "); 599 commandJump.append(LOCAL_MANGLE_INPUT); 600 601 if (int32_t ret = ClearRules()) { 602 NETNATIVE_LOGE("ClearRules failed, err is %{public}d", ret); 603 return ret; 604 } 605 606 if (access(NETSYS_ROUTE_INIT_DIR_PATH, F_OK) == 0) { 607 if (int32_t ret = AddLocalNetworkRules()) { 608 NETNATIVE_LOGE("AddLocalNetworkRules failed, err is %{public}d", ret); 609 return ret; 610 } 611 } else { 612 NETNATIVE_LOGI("AddLocalNetworkRules init ok, do not need repeat"); 613 } 614 615 return 0; 616 } 617 ClearRules()618 int32_t RouteManager::ClearRules() 619 { 620 return ClearRouteInfo(RTM_GETRULE, 0) >= 0 ? 0 : -1; 621 } 622 ClearRoutes(const std::string & interfaceName,int32_t netId)623 int32_t RouteManager::ClearRoutes(const std::string &interfaceName, int32_t netId) 624 { 625 std::lock_guard lock(RouteManager::interfaceToTableLock_); 626 uint32_t table = FindTableByInterfacename(interfaceName, netId); 627 NETNATIVE_LOGI("ClearRoutes--table==:%{public}d", table); 628 if (table == RT_TABLE_UNSPEC) { 629 return -1; 630 } 631 int32_t ret = ClearRouteInfo(RTM_GETROUTE, table); 632 if (ret == 0 && table != ROUTE_INTERNAL_DEFAULT_TABLE) { 633 interfaceToTable_.erase(interfaceName); 634 } 635 636 return 0; 637 } 638 AddLocalNetworkRules()639 int32_t RouteManager::AddLocalNetworkRules() 640 { 641 NETNATIVE_LOGI("AddLocalNetworkRules"); 642 if (int32_t ret = 643 UpdateExplicitNetworkRule(LOCAL_NET_ID, ROUTE_LOCAL_NETWORK_TABLE, PERMISSION_NONE, ADD_CONTROL)) { 644 NETNATIVE_LOGE("UpdateExplicitNetworkRule failed, err is %{public}d", ret); 645 return ret; 646 } 647 Fwmark fwmark; 648 fwmark.explicitlySelected = false; 649 650 Fwmark mask; 651 mask.explicitlySelected = true; 652 653 RuleInfo ruleInfo; 654 ruleInfo.ruleTable = ROUTE_LOCAL_NETWORK_TABLE; 655 ruleInfo.rulePriority = RULE_LEVEL_LOCAL_NETWORK; 656 ruleInfo.ruleFwmark = fwmark.intValue; 657 ruleInfo.ruleMask = mask.intValue; 658 ruleInfo.ruleIif = RULEIIF_NULL; 659 ruleInfo.ruleOif = RULEOIF_NULL; 660 661 return UpdateRuleInfo(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo); 662 } 663 UpdatePhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission,bool add)664 int32_t RouteManager::UpdatePhysicalNetwork(uint16_t netId, const std::string &interfaceName, 665 NetworkPermission permission, bool add) 666 { 667 NETNATIVE_LOGI("UpdatePhysicalNetwork,add===%{public}d", add); 668 uint32_t table = FindTableByInterfacename(interfaceName, netId); 669 if (table == RT_TABLE_UNSPEC) { 670 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error"); 671 return -1; 672 } 673 674 if (int32_t ret = UpdateExplicitNetworkRule(netId, table, permission, add)) { 675 NETNATIVE_LOGE("UpdateExplicitNetworkRule failed, err is %{public}d", ret); 676 return ret; 677 } 678 679 if (int32_t ret = UpdateOutputInterfaceRules(interfaceName, table, permission, add)) { 680 NETNATIVE_LOGE("UpdateOutputInterfaceRules failed, err is %{public}d", ret); 681 return ret; 682 } 683 684 return 0; 685 } 686 UpdateLocalNetwork(uint16_t netId,const std::string & interfaceName,bool add)687 int32_t RouteManager::UpdateLocalNetwork(uint16_t netId, const std::string &interfaceName, bool add) 688 { 689 NETNATIVE_LOGI("UpdateLocalNetwork"); 690 return UpdateOutputInterfaceRules(interfaceName, ROUTE_LOCAL_NETWORK_TABLE, PERMISSION_NONE, add); 691 } 692 UpdateIncomingPacketMark(uint16_t netId,const std::string & interfaceName,NetworkPermission permission,bool add)693 int32_t RouteManager::UpdateIncomingPacketMark(uint16_t netId, const std::string &interfaceName, 694 NetworkPermission permission, bool add) 695 { 696 NETNATIVE_LOGI("UpdateIncomingPacketMark"); 697 Fwmark fwmark; 698 fwmark.netId = netId; 699 fwmark.explicitlySelected = true; 700 fwmark.protectedFromVpn = true; 701 fwmark.permission = permission; 702 const uint32_t mask = ~Fwmark::GetUidBillingMask(); 703 std::string action = ""; 704 if (add) { 705 action = " -A "; 706 } else { 707 action = " -D "; 708 } 709 std::stringstream ss; 710 ss << action << LOCAL_MANGLE_INPUT << " -i " << interfaceName << " -j MARK --set-mark 0x" << std::nouppercase 711 << std::hex << fwmark.intValue << "/0x" << std::nouppercase << std::hex << mask; 712 // need to call IptablesWrapper's RunCommand function. 713 714 return 0; 715 } 716 UpdateExplicitNetworkRule(uint16_t netId,uint32_t table,NetworkPermission permission,bool add)717 int32_t RouteManager::UpdateExplicitNetworkRule(uint16_t netId, uint32_t table, NetworkPermission permission, bool add) 718 { 719 NETNATIVE_LOGI("UpdateExplicitNetworkRule"); 720 Fwmark fwmark; 721 fwmark.netId = netId; 722 fwmark.explicitlySelected = true; 723 fwmark.permission = permission; 724 725 Fwmark mask; 726 mask.netId = FWMARK_NET_ID_MASK; 727 mask.explicitlySelected = true; 728 mask.permission = permission; 729 730 RuleInfo ruleInfo; 731 ruleInfo.ruleTable = table; 732 ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK; 733 ruleInfo.ruleFwmark = fwmark.intValue; 734 ruleInfo.ruleMask = mask.intValue; 735 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 736 ruleInfo.ruleOif = RULEOIF_NULL; 737 738 if (NetManagerStandard::IsInternalNetId(netId)) { 739 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, UID_ALLOW_INTERNAL.first, 740 UID_ALLOW_INTERNAL.second); 741 } 742 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo); 743 } 744 UpdateOutputInterfaceRules(const std::string & interfaceName,uint32_t table,NetworkPermission permission,bool add)745 int32_t RouteManager::UpdateOutputInterfaceRules(const std::string &interfaceName, uint32_t table, 746 NetworkPermission permission, bool add) 747 { 748 NETNATIVE_LOGI("UpdateOutputInterfaceRules"); 749 Fwmark fwmark; 750 fwmark.permission = permission; 751 752 Fwmark mask; 753 mask.permission = permission; 754 755 RuleInfo ruleInfo; 756 ruleInfo.ruleTable = table; 757 ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_INTERFACE; 758 ruleInfo.ruleFwmark = fwmark.intValue; 759 ruleInfo.ruleMask = mask.intValue; 760 ruleInfo.ruleIif = RULEIIF_LOOPBACK; 761 ruleInfo.ruleOif = interfaceName; 762 763 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo); 764 } 765 UpdateSharingNetwork(uint16_t action,const std::string & inputInterface,const std::string & outputInterface)766 int32_t RouteManager::UpdateSharingNetwork(uint16_t action, const std::string &inputInterface, 767 const std::string &outputInterface) 768 { 769 NETNATIVE_LOGI("UpdateSharingNetwork"); 770 uint32_t table = FindTableByInterfacename(outputInterface); 771 if (table == RT_TABLE_UNSPEC) { 772 return -1; 773 } 774 775 RuleInfo ruleInfo; 776 ruleInfo.ruleTable = table; 777 ruleInfo.rulePriority = RULE_LEVEL_SHARING; 778 ruleInfo.ruleFwmark = MARK_UNSET; 779 ruleInfo.ruleMask = MARK_UNSET; 780 ruleInfo.ruleIif = inputInterface; 781 ruleInfo.ruleOif = RULEOIF_NULL; 782 783 return UpdateRuleInfo(action, FR_ACT_TO_TBL, ruleInfo); 784 } 785 ClearSharingRules(const std::string & inputInterface)786 int32_t RouteManager::ClearSharingRules(const std::string &inputInterface) 787 { 788 NETNATIVE_LOGI("ClearSharingRules"); 789 790 RuleInfo ruleInfo; 791 ruleInfo.ruleTable = 0; 792 ruleInfo.rulePriority = RULE_LEVEL_SHARING; 793 ruleInfo.ruleFwmark = MARK_UNSET; 794 ruleInfo.ruleMask = MARK_UNSET; 795 ruleInfo.ruleIif = inputInterface; 796 ruleInfo.ruleOif = RULEOIF_NULL; 797 798 return UpdateRuleInfo(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo); 799 } 800 UpdateRuleInfo(uint32_t action,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)801 int32_t RouteManager::UpdateRuleInfo(uint32_t action, uint8_t ruleType, RuleInfo ruleInfo, uid_t uidStart, uid_t uidEnd) 802 { 803 NETNATIVE_LOGI("UpdateRuleInfo"); 804 if (ruleInfo.rulePriority < 0) { 805 NETNATIVE_LOGE("invalid IP-rule priority %{public}d", ruleInfo.rulePriority); 806 return ROUTEMANAGER_ERROR; 807 } 808 809 if (ruleInfo.ruleFwmark & ~ruleInfo.ruleMask) { 810 NETNATIVE_LOGE("mask 0x%{public}x does not select all the bits set in fwmark 0x%{public}x", ruleInfo.ruleMask, 811 ruleInfo.ruleFwmark); 812 return ROUTEMANAGER_ERROR; 813 } 814 815 if (ruleInfo.ruleTable == RT_TABLE_UNSPEC && ruleType == FR_ACT_TO_TBL && action != RTM_DELRULE) { 816 NETNATIVE_LOGE("RT_TABLE_UNSPEC only allowed when deleting rules"); 817 return -ENOTUNIQ; 818 } 819 820 // The main work is to assemble the structure required for rule. 821 for (const uint8_t family : {AF_INET, AF_INET6}) { 822 if (SendRuleToKernel(action, family, ruleType, ruleInfo, uidStart, uidEnd) < 0) { 823 NETNATIVE_LOGE("Update %{public}s rule info failed, action = %{public}d", 824 (family == AF_INET) ? "IPv4" : "IPv6", action); 825 return NETMANAGER_ERR_INTERNAL; 826 } 827 } 828 return NETMANAGER_SUCCESS; 829 } 830 SendRuleToKernel(uint32_t action,uint8_t family,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)831 int32_t RouteManager::SendRuleToKernel(uint32_t action, uint8_t family, uint8_t ruleType, RuleInfo ruleInfo, 832 uid_t uidStart, uid_t uidEnd) 833 { 834 struct fib_rule_hdr msg = {0}; 835 msg.action = ruleType; 836 msg.family = family; 837 uint16_t ruleFlag = (action == RTM_NEWRULE) ? NLM_F_CREATE : NLM_F_EXCL; 838 NetlinkMsg nlmsg(ruleFlag, NETLINK_MAX_LEN, getpid()); 839 nlmsg.AddRule(action, msg); 840 if (int32_t ret = nlmsg.AddAttr32(FRA_PRIORITY, ruleInfo.rulePriority)) { 841 return ret; 842 } 843 if (ruleInfo.ruleTable != RT_TABLE_UNSPEC) { 844 if (int32_t ret = nlmsg.AddAttr32(FRA_TABLE, ruleInfo.ruleTable)) { 845 return ret; 846 } 847 } 848 if (ruleInfo.ruleMask != 0) { 849 if (int32_t ret = nlmsg.AddAttr32(FRA_FWMARK, ruleInfo.ruleFwmark)) { 850 return ret; 851 } 852 if (int32_t ret = nlmsg.AddAttr32(FRA_FWMASK, ruleInfo.ruleMask)) { 853 return ret; 854 } 855 } 856 if ((uidStart != INVALID_UID) && (uidEnd != INVALID_UID)) { 857 FibRuleUidRange uidRange = {uidStart, uidEnd}; 858 if (int32_t ret = nlmsg.AddAttr(FRA_UID_RANGE, &uidRange, sizeof(uidRange))) { 859 NETNATIVE_LOGE("SendRuleToKernel FRA_UID_RANGE is error."); 860 return ret; 861 } 862 } 863 if (ruleInfo.ruleIif != RULEIIF_NULL) { 864 char ruleIifName[IFNAMSIZ] = {0}; 865 size_t ruleIifLength = strlcpy(ruleIifName, ruleInfo.ruleIif.c_str(), IFNAMSIZ) + 1; 866 if (int32_t ret = nlmsg.AddAttr(FRA_IIFNAME, ruleIifName, ruleIifLength)) { 867 return ret; 868 } 869 } 870 if (ruleInfo.ruleOif != RULEOIF_NULL) { 871 char ruleOifName[IFNAMSIZ] = {0}; 872 size_t ruleOifLength = strlcpy(ruleOifName, ruleInfo.ruleOif.c_str(), IFNAMSIZ) + 1; 873 if (int32_t ret = nlmsg.AddAttr(FRA_OIFNAME, ruleOifName, ruleOifLength)) { 874 return ret; 875 } 876 } 877 878 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage()); 879 } 880 UpdateRouteRule(uint16_t action,uint16_t flags,RouteInfo routeInfo)881 int32_t RouteManager::UpdateRouteRule(uint16_t action, uint16_t flags, RouteInfo routeInfo) 882 { 883 NETNATIVE_LOG_D("UpdateRouteRule"); 884 RouteInfo routeInfoModify = routeInfo; 885 // The main work is to assemble the structure required for route. 886 struct rtmsg msg; 887 (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg)); 888 msg.rtm_family = AF_INET; 889 msg.rtm_dst_len = BIT_32_LEN; 890 msg.rtm_protocol = RTPROT_STATIC; 891 msg.rtm_scope = RT_SCOPE_UNIVERSE; 892 msg.rtm_type = RTN_UNICAST; 893 msg.rtm_table = RT_TABLE_UNSPEC; 894 895 uint32_t index = 0; 896 if (!routeInfo.routeNextHop.empty() && !strcmp(routeInfo.routeNextHop.c_str(), "unreachable")) { 897 msg.rtm_type = RTN_UNREACHABLE; 898 routeInfoModify.routeInterfaceName = ""; 899 routeInfoModify.routeNextHop = ""; 900 } else if (!routeInfo.routeNextHop.empty() && !strcmp(routeInfo.routeNextHop.c_str(), "throw")) { 901 msg.rtm_type = RTN_THROW; 902 routeInfoModify.routeInterfaceName = ""; 903 routeInfoModify.routeNextHop = ""; 904 } else { 905 index = if_nametoindex(routeInfo.routeInterfaceName.c_str()); 906 } 907 908 int32_t ret = SendRouteToKernel(action, flags, msg, routeInfoModify, index); 909 if (ret < 0) { 910 NETNATIVE_LOGE("SendNetlinkMsgToKernel Error ret = %{public}d", ret); 911 return ret; 912 } 913 914 return 0; 915 } 916 SendRouteToKernel(uint16_t action,uint16_t routeFlag,rtmsg msg,RouteInfo routeInfo,uint32_t index)917 int32_t RouteManager::SendRouteToKernel(uint16_t action, uint16_t routeFlag, rtmsg msg, RouteInfo routeInfo, 918 uint32_t index) 919 { 920 InetAddr dst; 921 int32_t readAddrResult = ReadAddr(routeInfo.routeDestinationName, &dst); 922 if (readAddrResult != 1) { 923 NETNATIVE_LOGE("dest parse failed:%{public}d", readAddrResult); 924 return -1; 925 } 926 msg.rtm_family = static_cast<uint8_t>(dst.family); 927 msg.rtm_dst_len = static_cast<uint8_t>(dst.prefixlen); 928 if (dst.family == AF_INET) { 929 msg.rtm_scope = RT_SCOPE_LINK; 930 } else if (dst.family == AF_INET6) { 931 msg.rtm_scope = RT_SCOPE_UNIVERSE; 932 } 933 934 InetAddr gw = {0}; 935 if (!routeInfo.routeNextHop.empty() && ReadAddrGw(routeInfo.routeNextHop, &gw) <= 0) { 936 NETNATIVE_LOGE("gw parse failed:%{public}d", readAddrResult); 937 return -1; 938 } 939 if (gw.bitlen != 0) { 940 msg.rtm_scope = RT_SCOPE_UNIVERSE; 941 msg.rtm_family = static_cast<uint8_t>(gw.family); 942 } 943 NetlinkMsg nlmsg(routeFlag, NETLINK_MAX_LEN, getpid()); 944 nlmsg.AddRoute(action, msg); 945 if (int32_t ret = nlmsg.AddAttr32(RTA_TABLE, routeInfo.routeTable)) { 946 return ret; 947 } 948 if (int32_t ret = nlmsg.AddAttr(RTA_DST, dst.data, dst.bitlen / BYTE_ALIGNMENT)) { 949 return ret; 950 } 951 if (!routeInfo.routeNextHop.empty()) { 952 if (int32_t ret = nlmsg.AddAttr(RTA_GATEWAY, gw.data, gw.bitlen / BYTE_ALIGNMENT)) { 953 return ret; 954 } 955 } 956 if (!routeInfo.routeInterfaceName.empty()) { 957 NETNATIVE_LOGI("index is :%{public}d", index); 958 if (int32_t ret = nlmsg.AddAttr32(RTA_OIF, index)) { 959 return ret; 960 } 961 } 962 963 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage()); 964 } 965 FindTableByInterfacename(const std::string & interfaceName,int32_t netId)966 uint32_t RouteManager::FindTableByInterfacename(const std::string &interfaceName, int32_t netId) 967 { 968 NETNATIVE_LOGI("FindTableByInterfacename netId %{public}d", netId); 969 if (NetManagerStandard::IsInternalNetId(netId)) { 970 return ROUTE_INTERNAL_DEFAULT_TABLE; 971 } 972 auto iter = interfaceToTable_.find(interfaceName); 973 if (iter != interfaceToTable_.end()) { 974 return iter->second; 975 } 976 977 uint32_t table = if_nametoindex(interfaceName.c_str()); 978 if (table == 0) { 979 NETNATIVE_LOGE("RouteManager cannot find interface %{public}s", interfaceName.c_str()); 980 return RT_TABLE_UNSPEC; 981 } 982 table += THOUSAND_LEN; 983 interfaceToTable_[interfaceName] = table; 984 return table; 985 } 986 GetRouteTableFromType(TableType tableType,const std::string & interfaceName)987 uint32_t RouteManager::GetRouteTableFromType(TableType tableType, const std::string &interfaceName) 988 { 989 switch (tableType) { 990 case RouteManager::INTERFACE: 991 return FindTableByInterfacename(interfaceName); 992 case RouteManager::LOCAL_NETWORK: 993 return ROUTE_LOCAL_NETWORK_TABLE; 994 case RouteManager::VPN_NETWORK: 995 return ROUTE_VPN_NETWORK_TABLE; 996 case RouteManager::INTERNAL_DEFAULT: 997 return ROUTE_INTERNAL_DEFAULT_TABLE; 998 default: 999 NETNATIVE_LOGE("tableType [%{tableType}d] is error", tableType); 1000 return RT_TABLE_UNSPEC; 1001 } 1002 } 1003 SetRouteInfo(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop,RouteInfo & routeInfo)1004 int32_t RouteManager::SetRouteInfo(TableType tableType, const std::string &interfaceName, 1005 const std::string &destinationName, const std::string &nextHop, RouteInfo &routeInfo) 1006 { 1007 uint32_t table = GetRouteTableFromType(tableType, interfaceName); 1008 if (table == RT_TABLE_UNSPEC) { 1009 return -1; 1010 } 1011 1012 routeInfo.routeTable = table; 1013 routeInfo.routeInterfaceName = interfaceName; 1014 routeInfo.routeDestinationName = destinationName; 1015 routeInfo.routeNextHop = nextHop; 1016 return 0; 1017 } 1018 } // namespace nmd 1019 } // namespace OHOS 1020