• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <map>
21 #include <mutex>
22 #include <net/if.h>
23 #include <netlink_socket.h>
24 #include <sstream>
25 #include <sys/ioctl.h>
26 #include <sys/socket.h>
27 #include <sys/uio.h>
28 #include <unistd.h>
29 #include <linux/fib_rules.h>
30 #include <linux/netlink.h>
31 #include <linux/rtnetlink.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 #include "distributed_manager.h"
41 #ifdef SUPPORT_SYSVPN
42 #include "iptables_wrapper.h"
43 #endif // SUPPORT_SYSVPN
44 #include "route_manager.h"
45 
46 using namespace OHOS::NetManagerStandard;
47 using namespace OHOS::NetManagerStandard::CommonUtils;
48 namespace OHOS {
49 namespace nmd {
50 namespace {
51 constexpr int32_t RULE_LEVEL_CLAT_TUN = 8000;
52 constexpr int32_t RULE_LEVEL_VPN_OUTPUT_TO_LOCAL = 9000;
53 constexpr int32_t RULE_LEVEL_SECURE_VPN = 10000;
54 constexpr int32_t RULE_LEVEL_VNIC_NETWORK = 10500;
55 constexpr int32_t RULE_LEVEL_EXPLICIT_NETWORK = 11000;
56 constexpr int32_t RULE_LEVEL_OUTPUT_IFACE_VPN = 11500;
57 constexpr int32_t RULE_LEVEL_OUTPUT_INTERFACE = 12000;
58 constexpr int32_t RULE_LEVEL_LOCAL_NETWORK = 13000;
59 constexpr int32_t RULE_LEVEL_SHARING = 14000;
60 #ifdef FEATURE_ENTERPRISE_ROUTE_CUSTOM
61 constexpr int32_t RULE_LEVEL_ENTERPRISE = 15000;
62 #endif
63 constexpr int32_t RULE_LEVEL_DEFAULT = 16000;
64 constexpr int32_t RULE_LEVEL_DISTRIBUTE_COMMUNICATION = 16500;
65 constexpr uint32_t ROUTE_DISTRIBUTE_TO_CLIENT_TABLE = 90;
66 constexpr uint32_t ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE = 91;
67 constexpr uint32_t ROUTE_VNIC_TABLE = 97;
68 constexpr uint32_t ROUTE_VPN_NETWORK_TABLE = 98;
69 constexpr uint32_t ROUTE_LOCAL_NETWORK_TABLE = 99;
70 constexpr uint32_t OUTPUT_MAX = 128;
71 constexpr uint32_t BIT_32_LEN = 32;
72 constexpr uint32_t BIT_MAX_LEN = 255;
73 constexpr uint32_t DECIMAL_DIGITAL = 10;
74 constexpr uint32_t BYTE_ALIGNMENT = 8;
75 constexpr uint32_t THOUSAND_LEN = 100;
76 constexpr uint16_t LOCAL_NET_ID = 99;
77 constexpr uint16_t NETID_UNSET = 0;
78 constexpr uint32_t MARK_UNSET = 0;
79 #ifdef SUPPORT_SYSVPN
80 constexpr uint32_t DEFAULT_ROUTE_VPN_NETWORK_BASE_TABLE = 1000;
81 constexpr const char *XFRM_CARD_NAME = "xfrm-vpn";
82 constexpr const char *PPP_CARD_NAME = "ppp-vpn";
83 constexpr const char *TUN_CARD_NAME = "vpn-tun";
84 constexpr const char *MULTI_TUN_CARD_NAME = "multitun-vpn";
85 const std::string LOCAL_MANGLE_OUTPUT = "routectrl_mangle_OUTPUT";
86 #endif // SUPPORT_SYSVPN
87 constexpr uid_t UID_ROOT = 0;
88 constexpr std::pair<uid_t, uid_t> UID_ALLOW_INTERNAL = {7023, 7023};
89 constexpr int32_t ROUTEMANAGER_SUCCESS = 0;
90 constexpr int32_t ROUTEMANAGER_ERROR = -1;
91 constexpr bool ADD_CONTROL = true;
92 constexpr bool DEL_CONTROL = false;
93 const std::string RULEIIF_LOOPBACK = "lo";
94 const std::string RULEIIF_NULL = "";
95 const std::string RULEOIF_NULL = "";
96 const std::string RULEIP_NULL = "";
97 const std::string LOCAL_MANGLE_INPUT = "routectrl_mangle_INPUT";
98 constexpr const char *DISTRIBUTED_TUN_CARD_NAME = "virnic";
99 constexpr const char *NETSYS_ROUTE_INIT_DIR_PATH = "/data/service/el1/public/netmanager/route";
100 constexpr const char *DISTRIBUTED_TUN_CARD_NAME_VETH = "virnic-veth";
101 constexpr const char *IP_CMD_PATH = "/system/bin/ip";
102 
103 struct FibRuleUidRange {
104     __u32 start;
105     __u32 end;
106 };
107 } // namespace
108 
109 std::mutex RouteManager::interfaceToTableLock_;
110 std::map<std::string, uint32_t> RouteManager::interfaceToTable_;
111 
112 #ifdef SUPPORT_SYSVPN
113 bool RouteManager::vpnSysCall_ = true;
114 std::string RouteManager::defauleNetWorkName_ = "";
115 #endif // SUPPORT_SYSVPN
116 
RouteManager()117 RouteManager::RouteManager()
118 {
119     Init();
120 #ifdef SUPPORT_SYSVPN
121     InitOutcomingPacketMark();
122 #endif // SUPPORT_SYSVPN
123 }
124 
UpdateVnicRoute(const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop,bool add)125 int32_t RouteManager::UpdateVnicRoute(const std::string &interfaceName, const std::string &destinationName,
126                                       const std::string &nextHop, bool add)
127 {
128     NETNATIVE_LOGI(
129         "VnicChangeRoute,interfaceName:%{public}s,destination:%{public}s, nextHop:%{public}s, add:%{public}d ",
130         interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str(), add);
131 
132     RouteInfo routeInfo;
133     routeInfo.routeTable = ROUTE_VNIC_TABLE;
134     routeInfo.routeInterfaceName = interfaceName;
135     routeInfo.routeDestinationName = destinationName;
136     routeInfo.routeNextHop = nextHop;
137     uint16_t flags = add ? (NLM_F_CREATE | NLM_F_EXCL) : NLM_F_EXCL;
138     uint16_t action = add ? RTM_NEWROUTE : RTM_DELROUTE;
139 
140     return UpdateRouteRule(action, flags, routeInfo);
141 }
142 
AddRoute(TableType tableType,NetworkRouteInfo networkRouteInfo,bool & routeRepeat)143 int32_t RouteManager::AddRoute(TableType tableType, NetworkRouteInfo networkRouteInfo, bool& routeRepeat)
144 {
145     std::string interfaceName = networkRouteInfo.ifName;
146     std::string destinationName = networkRouteInfo.destination;
147     std::string nextHop = networkRouteInfo.nextHop;
148     bool isExcludedRoute = networkRouteInfo.isExcludedRoute;
149     NETNATIVE_LOGI("AddRoute,interfaceName:%{public}s,destination:%{public}s, nextHop:%{public}s, \
150         isExcludedRoute:%{public}d", interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(),
151         ToAnonymousIp(nextHop).c_str(), isExcludedRoute);
152 
153     // This is a user-defined structure used to integrate the information required for setting up routes.
154     RouteInfo routeInfo;
155     if (SetRouteInfo(tableType, networkRouteInfo, routeInfo) != 0) {
156         return -1;
157     }
158 
159     int32_t ret = UpdateRouteRule(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, routeInfo);
160     if (ret == EEXIST) {
161         routeRepeat = true;
162     } else {
163         routeRepeat = false;
164     }
165     return ret;
166 }
167 
RemoveRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)168 int32_t RouteManager::RemoveRoute(TableType tableType, const std::string &interfaceName,
169                                   const std::string &destinationName, const std::string &nextHop)
170 {
171     NETNATIVE_LOGI("RemoveRoute,interfaceName:%{public}s,destination:%{public}s,nextHop:%{public}s",
172                    interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str());
173 
174     NetworkRouteInfo networkRouteInfo;
175     networkRouteInfo.ifName = interfaceName;
176     networkRouteInfo.destination = destinationName;
177     networkRouteInfo.nextHop = nextHop;
178     RouteInfo routeInfo;
179     if (SetRouteInfo(tableType, networkRouteInfo, routeInfo) != 0) {
180         return -1;
181     }
182     return UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
183 }
184 
UpdateRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)185 int32_t RouteManager::UpdateRoute(TableType tableType, const std::string &interfaceName,
186                                   const std::string &destinationName, const std::string &nextHop)
187 {
188     NETNATIVE_LOGI("UpdateRoute,interfaceName:%{public}s,destination:%{public}s,nextHop:%{public}s",
189                    interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str());
190     NetworkRouteInfo networkRouteInfo;
191     networkRouteInfo.ifName = interfaceName;
192     networkRouteInfo.destination = destinationName;
193     networkRouteInfo.nextHop = nextHop;
194     RouteInfo routeInfo;
195     if (SetRouteInfo(tableType, networkRouteInfo, routeInfo) != 0) {
196         return -1;
197     }
198     return UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo);
199 }
200 
AddInterfaceToDefaultNetwork(const std::string & interfaceName,NetworkPermission permission)201 int32_t RouteManager::AddInterfaceToDefaultNetwork(const std::string &interfaceName, NetworkPermission permission)
202 {
203     NETNATIVE_LOGI("AddInterfaceToDefaultNetwork, %{public}s;permission:%{public}d;", interfaceName.c_str(),
204                    permission);
205 #ifdef SUPPORT_SYSVPN
206     defauleNetWorkName_ = interfaceName;
207 #endif // SUPPORT_SYSVPN
208     uint32_t table = FindTableByInterfacename(interfaceName);
209     if (table == RT_TABLE_UNSPEC) {
210         return -1;
211     }
212     Fwmark fwmark;
213     fwmark.netId = NETID_UNSET;
214     fwmark.permission = permission;
215 
216     Fwmark mask;
217     mask.netId = FWMARK_NET_ID_MASK;
218     mask.permission = permission;
219 
220     // This is a user-defined structure used to integrate the information required for setting up rules.
221     RuleInfo ruleInfo;
222     ruleInfo.ruleTable = table;
223     ruleInfo.rulePriority = RULE_LEVEL_DEFAULT;
224     ruleInfo.ruleFwmark = fwmark.intValue;
225     ruleInfo.ruleMask = mask.intValue;
226     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
227     ruleInfo.ruleOif = RULEOIF_NULL;
228     return UpdateRuleInfo(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo);
229 }
230 
RemoveInterfaceFromDefaultNetwork(const std::string & interfaceName,NetworkPermission permission)231 int32_t RouteManager::RemoveInterfaceFromDefaultNetwork(const std::string &interfaceName, NetworkPermission permission)
232 {
233     NETNATIVE_LOGI("RemoveInterfaceFromDefaultNetwork, %{public}s;permission:%{public}d;", interfaceName.c_str(),
234                    permission);
235     uint32_t table = FindTableByInterfacename(interfaceName);
236     if (table == RT_TABLE_UNSPEC) {
237         return -1;
238     }
239 
240     Fwmark fwmark;
241     fwmark.netId = NETID_UNSET;
242     fwmark.permission = permission;
243 
244     Fwmark mask;
245     mask.netId = FWMARK_NET_ID_MASK;
246     mask.permission = permission;
247 
248     RuleInfo ruleInfo;
249     ruleInfo.ruleTable = table;
250     ruleInfo.rulePriority = RULE_LEVEL_DEFAULT;
251     ruleInfo.ruleFwmark = fwmark.intValue;
252     ruleInfo.ruleMask = mask.intValue;
253     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
254     ruleInfo.ruleOif = RULEOIF_NULL;
255     return UpdateRuleInfo(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
256 }
257 
AddInterfaceToPhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission)258 int32_t RouteManager::AddInterfaceToPhysicalNetwork(uint16_t netId, const std::string &interfaceName,
259                                                     NetworkPermission permission)
260 {
261     NETNATIVE_LOGI("AddInterfaceToPhysicalNetwork, netId:%{public}d;interfaceName:%{public}s;permission:%{public}d;",
262                    netId, interfaceName.c_str(), permission);
263     return UpdatePhysicalNetwork(netId, interfaceName, permission, ADD_CONTROL);
264 }
265 
RemoveInterfaceFromPhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission)266 int32_t RouteManager::RemoveInterfaceFromPhysicalNetwork(uint16_t netId, const std::string &interfaceName,
267                                                          NetworkPermission permission)
268 {
269     NETNATIVE_LOGI("RemoveInterfacePhysicalNetwork, netId:%{public}d;interfaceName:%{public}s;permission:%{public}d;",
270                    netId, interfaceName.c_str(), permission);
271     if (int32_t ret = UpdatePhysicalNetwork(netId, interfaceName, permission, DEL_CONTROL)) {
272         NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret);
273         return ret;
274     }
275     if (int32_t ret = ClearRoutes(interfaceName, netId)) {
276         NETNATIVE_LOGE("ClearRoutes err, error is %{public}d", ret);
277         return ret;
278     }
279     if (NetManagerStandard::IsInternalNetId(netId)) {
280         NETNATIVE_LOGI("InternalNetId skip");
281         return 0;
282     }
283     if (int32_t ret = ClearSharingRules(interfaceName)) {
284         NETNATIVE_LOGE("ClearSharingRules err, error is %{public}d", ret);
285         return ret;
286     }
287 
288     return 0;
289 }
290 
ModifyPhysicalNetworkPermission(uint16_t netId,const std::string & interfaceName,NetworkPermission oldPermission,NetworkPermission newPermission)291 int32_t RouteManager::ModifyPhysicalNetworkPermission(uint16_t netId, const std::string &interfaceName,
292                                                       NetworkPermission oldPermission, NetworkPermission newPermission)
293 {
294     NETNATIVE_LOGI("ModifyPhysicalNetworkPermission, %{public}s", interfaceName.c_str());
295     if (int32_t ret = UpdatePhysicalNetwork(netId, interfaceName, newPermission, ADD_CONTROL)) {
296         NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret);
297         return ret;
298     }
299 
300     return UpdatePhysicalNetwork(netId, interfaceName, newPermission, DEL_CONTROL);
301 }
302 
303 #ifdef SUPPORT_SYSVPN
InitOutcomingPacketMark()304 int32_t RouteManager::InitOutcomingPacketMark()
305 {
306     NETNATIVE_LOGI("InitOutcomingPacketMark");
307     // need to call IptablesWrapper's RunCommand function.
308     std::string commandNew;
309     commandNew.append("-t mangle -N ");
310     commandNew.append(LOCAL_MANGLE_OUTPUT);
311     if (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4, commandNew) == ROUTEMANAGER_ERROR) {
312         NETNATIVE_LOGI("InitOutcomingPacketMark error");
313         return ROUTEMANAGER_ERROR;
314     }
315 
316     std::string commandJump;
317     commandJump.append("-t mangle");
318     commandJump.append(" -A OUTPUT -j ");
319     commandJump.append(LOCAL_MANGLE_OUTPUT);
320     if (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4, commandJump) == ROUTEMANAGER_ERROR) {
321         NETNATIVE_LOGE("InitOutcomingPacketMark error");
322         return ROUTEMANAGER_ERROR;
323     }
324     return ROUTEMANAGER_SUCCESS;
325 }
326 
UpdateVpnRules(uint16_t netId,const std::string & interface,const std::vector<std::string> & extMessages,bool add)327 int32_t RouteManager::UpdateVpnRules(uint16_t netId, const std::string &interface,
328     const std::vector<std::string> &extMessages, bool add)
329 {
330     int32_t ret = ROUTEMANAGER_SUCCESS;
331     if (interface.empty()) {
332         NETNATIVE_LOGE("UpdateVpnRules err, vpn name is empty");
333         return ROUTEMANAGER_ERROR;
334     }
335     NETNATIVE_LOG_D("update vpn rules on interface, %{public}s.", interface.c_str());
336     bool isSysVpn = CheckSysVpnCall();
337     bool isTunVpn = CheckTunVpnCall(interface);
338 
339     for (const auto& msg : extMessages) {
340         if (!CommonUtils::IsValidIPV4(msg)) {
341             NETNATIVE_LOGE("failed to add update vpn rules on interface of netId, %{public}u.", netId);
342             return ROUTEMANAGER_ERROR;
343         }
344         if (isTunVpn) {
345             NETNATIVE_LOGI("TUN mode, skipping update for interface: %{public}s", interface.c_str());
346             continue;
347         }
348         if (isSysVpn) {
349             ret = UpdateVpnOutPutPenetrationRule(netId, defauleNetWorkName_, msg, add);
350         } else {
351             ret = UpdateOutcomingIpMark(netId, msg, add);
352         }
353     }
354     return ret;
355 }
356 
UpdateOutcomingIpMark(uint16_t netId,const std::string & addr,bool add)357 int32_t RouteManager::UpdateOutcomingIpMark(uint16_t netId, const std::string &addr, bool add)
358 {
359     NETNATIVE_LOGI("UpdateOutcomingIpMark,add===%{public}d", add);
360     Fwmark fwmark;
361     fwmark.netId = netId;
362     NetworkPermission permission = NetworkPermission::PERMISSION_SYSTEM;
363     fwmark.permission = permission;
364     std::string action = "";
365     if (add) {
366         action = "-A ";
367     } else {
368         action = "-D ";
369     }
370     std::stringstream ss;
371     ss << "-t mangle " << action << LOCAL_MANGLE_OUTPUT << " -s " << addr
372     << " -j MARK --set-mark 0x" << std::nouppercase
373     << std::hex << fwmark.intValue;
374     // need to call IptablesWrapper's RunCommand function.
375     if (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4, ss.str()) == ROUTEMANAGER_ERROR) {
376         NETNATIVE_LOGE("UpdateOutcomingIpMark error");
377         return ROUTEMANAGER_ERROR;
378     }
379     return ROUTEMANAGER_SUCCESS;
380 }
381 
UpdateOutcomingUidMark(uint16_t netId,uid_t startUid,uid_t endUid,bool add)382 int32_t RouteManager::UpdateOutcomingUidMark(uint16_t netId, uid_t startUid, uid_t endUid, bool add)
383 {
384     NETNATIVE_LOGI("UpdateOutcomingUidMark,add===%{public}d", add);
385     Fwmark fwmark;
386     fwmark.netId = netId;
387     NetworkPermission permission = NetworkPermission::PERMISSION_SYSTEM;
388     fwmark.permission = permission;
389     std::string action = "";
390     if (add) {
391         action = "-A ";
392     } else {
393         action = "-D ";
394     }
395     std::stringstream ss;
396     ss << "-t mangle " << action << LOCAL_MANGLE_OUTPUT << " -m owner --uid-owner " << startUid << "-" << endUid
397        << " -j MARK --set-mark 0x" << std::nouppercase
398        << std::hex << fwmark.intValue;
399     // need to call IptablesWrapper's RunCommand function.
400     if (IptablesWrapper::GetInstance()->RunCommand(IPTYPE_IPV4, ss.str()) == ROUTEMANAGER_ERROR) {
401         NETNATIVE_LOGE("UpdateOutcomingUidMark error");
402         return ROUTEMANAGER_ERROR;
403     }
404     return ROUTEMANAGER_SUCCESS;
405 }
406 
SetVpnCallMode(const std::string & message)407 int32_t RouteManager::SetVpnCallMode(const std::string &message)
408 {
409     std::lock_guard lock(interfaceToTableLock_);
410     if (message.find("0") == std::string::npos) {
411         vpnSysCall_ = true;
412     } else {
413         vpnSysCall_ = false;
414     }
415     NETNATIVE_LOG_D("vpnSysCall_ %{public}d", vpnSysCall_);
416     return ROUTEMANAGER_SUCCESS;
417 }
418 
CheckTunVpnCall(const std::string & vpnName)419 bool RouteManager::CheckTunVpnCall(const std::string &vpnName)
420 {
421     if (vpnName.empty()) {
422         NETNATIVE_LOGE("CheckTunVpnCall err, vpn name is empty");
423         return false;
424     }
425     NETNATIVE_LOG_D("vpnName %{public}s, vpnSysCall_ %{public}d", vpnName.c_str(), vpnSysCall_);
426     if (vpnName.find(TUN_CARD_NAME) != std::string::npos) {
427         return true;
428     }
429     return false;
430 }
431 
CheckSysVpnCall()432 bool RouteManager::CheckSysVpnCall()
433 {
434     return vpnSysCall_;
435 }
436 
CheckMultiVpnCall(const std::string & vpnName)437 bool RouteManager::CheckMultiVpnCall(const std::string &vpnName)
438 {
439     if (vpnName.empty()) {
440         NETNATIVE_LOGE("CheckTunVpnCall err, vpn name is empty");
441         return false;
442     }
443     if (CheckTunVpnCall(vpnName)) {
444         return false;
445     } else {
446         return !CheckSysVpnCall();
447     }
448     return false;
449 }
450 
GetVpnInterffaceToId(const std::string & ifName)451 uint32_t RouteManager::GetVpnInterffaceToId(const std::string &ifName)
452 {
453     if (ifName.find(XFRM_CARD_NAME) != std::string::npos) {
454         return CommonUtils::StrToUint(ifName.substr(strlen(XFRM_CARD_NAME)));
455     } else if (ifName.find(PPP_CARD_NAME) != std::string::npos) {
456         return CommonUtils::StrToUint(ifName.substr(strlen(PPP_CARD_NAME)));
457     } else if (ifName.find(MULTI_TUN_CARD_NAME) != std::string::npos) {
458         return CommonUtils::StrToUint(ifName.substr(strlen(MULTI_TUN_CARD_NAME)));
459     }
460     return 0;
461 }
462 
FindVpnIdByInterfacename(VpnRuleIdType type,const std::string & interfaceName)463 uint32_t RouteManager::FindVpnIdByInterfacename(VpnRuleIdType type, const std::string &interfaceName)
464 {
465     std::lock_guard lock(interfaceToTableLock_);
466     NETNATIVE_LOG_D("type %{public}d, interface %{public}s", type, interfaceName.c_str());
467     uint32_t id = GetVpnInterffaceToId(interfaceName.c_str());
468     switch (type) {
469         case VpnRuleIdType::VPN_OUTPUT_TO_LOCAL:
470             id = RULE_LEVEL_VPN_OUTPUT_TO_LOCAL - id;
471             break;
472         case VpnRuleIdType::VPN_SECURE:
473             id = RULE_LEVEL_SECURE_VPN - id;
474             break;
475         case VpnRuleIdType::VPN_EXPLICIT_NETWORK:
476             id = RULE_LEVEL_EXPLICIT_NETWORK - id;
477             break;
478         case VpnRuleIdType::VPN_OUTPUT_IFACE:
479             id = RULE_LEVEL_OUTPUT_IFACE_VPN - id;
480             break;
481         case VpnRuleIdType::VPN_NETWORK_TABLE:
482             id = DEFAULT_ROUTE_VPN_NETWORK_BASE_TABLE + id;
483             break;
484         default :
485             NETNATIVE_LOGI("unkonw type %{public}d, interface %{public}s", type, interfaceName.c_str());
486             break;
487     }
488     return id;
489 }
490 #endif // SUPPORT_SYSVPN
491 
AddInterfaceToVirtualNetwork(int32_t netId,const std::string & interfaceName)492 int32_t RouteManager::AddInterfaceToVirtualNetwork(int32_t netId, const std::string &interfaceName)
493 {
494     return ModifyVirtualNetBasedRules(netId, interfaceName, true);
495 }
496 
RemoveInterfaceFromVirtualNetwork(int32_t netId,const std::string & interfaceName)497 int32_t RouteManager::RemoveInterfaceFromVirtualNetwork(int32_t netId, const std::string &interfaceName)
498 {
499     if (ModifyVirtualNetBasedRules(netId, interfaceName, false) != ROUTEMANAGER_SUCCESS) {
500         return ROUTEMANAGER_ERROR;
501     }
502 #ifdef SUPPORT_SYSVPN
503     if (CheckMultiVpnCall(interfaceName)) {
504         uint32_t tableId = FindVpnIdByInterfacename(VpnRuleIdType::VPN_NETWORK_TABLE, interfaceName);
505         NETNATIVE_LOG_D("RemoveInterfaceFromVirtualNetwork, clear table %{public}d", tableId);
506         return ClearRouteInfo(RTM_GETROUTE, tableId);
507     } else {
508         return ClearRouteInfo(RTM_GETROUTE, ROUTE_VPN_NETWORK_TABLE);
509     }
510 #else
511     return ClearRouteInfo(RTM_GETROUTE, ROUTE_VPN_NETWORK_TABLE);
512 #endif // SUPPORT_SYSVPN
513 }
514 
ModifyVirtualNetBasedRules(int32_t netId,const std::string & ifaceName,bool add)515 int32_t RouteManager::ModifyVirtualNetBasedRules(int32_t netId, const std::string &ifaceName, bool add)
516 {
517     NETNATIVE_LOGI("ModifyVirtualNetBasedRules,add===%{public}d", add);
518     uint32_t table = GetRouteTableFromType(RouteManager::VPN_NETWORK, ifaceName);
519     if (table == RT_TABLE_UNSPEC) {
520         NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
521         return ROUTEMANAGER_ERROR;
522     }
523 
524     // If the rule fails to be added, continue to execute the next rule
525     int32_t ret = UpdateVpnOutputToLocalRule(ifaceName, add);
526 #ifdef SUPPORT_SYSVPN
527     ret += UpdateVpnSystemPermissionRule(netId, table, add, ifaceName);
528     ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add, ifaceName);
529 #else
530     ret += UpdateVpnSystemPermissionRule(netId, table, add);
531     ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add);
532 #endif // SUPPORT_SYSVPN
533     return ret;
534 }
535 
536 #ifdef SUPPORT_SYSVPN
UpdateVpnOutPutPenetrationRule(int32_t netId,const std::string & interfaceName,const std::string & ruleDstIp,bool add)537 int32_t RouteManager::UpdateVpnOutPutPenetrationRule(int32_t netId, const std::string &interfaceName,
538                                                      const std::string &ruleDstIp, bool add)
539 {
540     RuleInfo ruleInfo;
541     ruleInfo.ruleTable = FindTableByInterfacename(interfaceName);
542     ruleInfo.rulePriority = RULE_LEVEL_VPN_OUTPUT_TO_LOCAL;
543     ruleInfo.ruleFwmark = MARK_UNSET;
544     ruleInfo.ruleMask = MARK_UNSET;
545     ruleInfo.ruleOif = RULEOIF_NULL;
546     ruleInfo.ruleDstIp = ruleDstIp;
547 
548     NETNATIVE_LOG_D("rule ruleDstIp %{public}s", ToAnonymousIp(ruleDstIp).c_str());
549     return UpdateDistributedRule(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
550 }
551 #endif // SUPPORT_SYSVPN
552 
UpdateVpnOutputToLocalRule(const std::string & interfaceName,bool add)553 int32_t RouteManager::UpdateVpnOutputToLocalRule(const std::string &interfaceName, bool add)
554 {
555     RuleInfo ruleInfo;
556     ruleInfo.ruleTable = ROUTE_LOCAL_NETWORK_TABLE;
557 #ifdef SUPPORT_SYSVPN
558     if (CheckMultiVpnCall(interfaceName)) {
559         ruleInfo.rulePriority = FindVpnIdByInterfacename(VpnRuleIdType::VPN_OUTPUT_TO_LOCAL, interfaceName);
560     } else {
561         ruleInfo.rulePriority = RULE_LEVEL_VPN_OUTPUT_TO_LOCAL;
562     }
563     NETNATIVE_LOG_D("rule priority %{public}d", ruleInfo.rulePriority);
564 #else
565     ruleInfo.rulePriority = RULE_LEVEL_VPN_OUTPUT_TO_LOCAL;
566 #endif // SUPPORT_SYSVPN
567 
568     ruleInfo.ruleFwmark = MARK_UNSET;
569     ruleInfo.ruleMask = MARK_UNSET;
570     if (interfaceName.find("vpn") == std::string::npos) {
571         ruleInfo.ruleIif = interfaceName;
572     }
573     ruleInfo.ruleOif = RULEOIF_NULL;
574 
575     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
576 }
577 
UpdateVpnSystemPermissionRule(int32_t netId,uint32_t table,bool add,const std::string & interfaceName)578 int32_t RouteManager::UpdateVpnSystemPermissionRule(int32_t netId, uint32_t table, bool add,
579     const std::string &interfaceName)
580 {
581     Fwmark fwmark;
582     fwmark.netId = netId;
583     NetworkPermission permission = NetworkPermission::PERMISSION_SYSTEM;
584     fwmark.permission = permission;
585 
586     Fwmark mask;
587     mask.netId = FWMARK_NET_ID_MASK;
588     mask.permission = permission;
589 
590     RuleInfo ruleInfo;
591     ruleInfo.ruleTable = table;
592 #ifdef SUPPORT_SYSVPN
593     if (CheckMultiVpnCall(interfaceName)) {
594         ruleInfo.rulePriority = FindVpnIdByInterfacename(VpnRuleIdType::VPN_SECURE, interfaceName);
595     } else {
596         ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN;
597     }
598     NETNATIVE_LOG_D("rule priority %{public}d", ruleInfo.rulePriority);
599     if (CheckMultiVpnCall(interfaceName) || CheckTunVpnCall(interfaceName)) {
600         NETNATIVE_LOGI("is ext vpn, add fwmark");
601         ruleInfo.ruleFwmark = fwmark.intValue;
602         ruleInfo.ruleMask = mask.intValue;
603     }
604 #else
605     ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN;
606     ruleInfo.ruleFwmark = fwmark.intValue;
607     ruleInfo.ruleMask = mask.intValue;
608 #endif // SUPPORT_SYSVPN
609     ruleInfo.ruleIif = RULEIIF_NULL;
610     ruleInfo.ruleOif = RULEOIF_NULL;
611 
612     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
613 }
614 
AddUsersToVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges)615 int32_t RouteManager::AddUsersToVirtualNetwork(int32_t netId, const std::string &interfaceName,
616                                                const std::vector<NetManagerStandard::UidRange> &uidRanges)
617 {
618     return UpdateVirtualNetwork(netId, interfaceName, uidRanges, true);
619 }
620 
RemoveUsersFromVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges)621 int32_t RouteManager::RemoveUsersFromVirtualNetwork(int32_t netId, const std::string &interfaceName,
622                                                     const std::vector<NetManagerStandard::UidRange> &uidRanges)
623 {
624     return UpdateVirtualNetwork(netId, interfaceName, uidRanges, false);
625 }
626 
UpdateVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges,bool add)627 int32_t RouteManager::UpdateVirtualNetwork(int32_t netId, const std::string &interfaceName,
628                                            const std::vector<NetManagerStandard::UidRange> &uidRanges, bool add)
629 {
630     NETNATIVE_LOGI("UpdateVirtualNetwork, add == %{public}d", add);
631     uint32_t table = GetRouteTableFromType(RouteManager::VPN_NETWORK, interfaceName);
632     if (table == RT_TABLE_UNSPEC) {
633         NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
634         return ROUTEMANAGER_ERROR;
635     }
636     int32_t ret = ROUTEMANAGER_SUCCESS;
637     for (auto range : uidRanges) {
638         // If the rule fails to be added, continue to execute the next rule
639 #ifdef SUPPORT_SYSVPN
640         ret += UpdateVpnUidRangeRule(table, range.begin_, range.end_, add, interfaceName);
641         ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, range.begin_, range.end_, add,
642                                                 interfaceName);
643         ret += UpdateOutputInterfaceRulesWithUid(interfaceName, table, PERMISSION_NONE, range.begin_, range.end_, add);
644 
645         if (CheckMultiVpnCall(interfaceName)) {
646             NETNATIVE_LOGI("is ext vpn, add uid mark");
647             ret += UpdateOutcomingUidMark(netId, range.begin_, range.end_, add);
648             if (ret != ROUTEMANAGER_SUCCESS) {
649                 NETNATIVE_LOGE("add uid mark error.");
650             }
651         }
652 #else
653         ret += UpdateVpnUidRangeRule(table, range.begin_, range.end_, add);
654         ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, range.begin_, range.end_, add);
655         ret += UpdateOutputInterfaceRulesWithUid(interfaceName, table, PERMISSION_NONE, range.begin_, range.end_, add);
656 #endif // SUPPORT_SYSVPN
657     }
658     return ret;
659 }
660 
UpdateVnicUidRangesRule(const std::vector<NetManagerStandard::UidRange> & uidRanges,bool add)661 int32_t RouteManager::UpdateVnicUidRangesRule(const std::vector<NetManagerStandard::UidRange> &uidRanges, bool add)
662 {
663     int32_t ret = ROUTEMANAGER_SUCCESS;
664     for (const auto &range : uidRanges) {
665         Fwmark fwmark;
666         Fwmark mask;
667         fwmark.protectedFromVpn = false;
668         mask.protectedFromVpn = false;
669 
670         RuleInfo ruleInfo;
671         ruleInfo.ruleTable = ROUTE_VNIC_TABLE;
672         ruleInfo.rulePriority = RULE_LEVEL_VNIC_NETWORK;
673         ruleInfo.ruleFwmark = fwmark.intValue;
674         ruleInfo.ruleMask = mask.intValue;
675         ruleInfo.ruleIif = RULEIIF_LOOPBACK;
676         ruleInfo.ruleOif = RULEOIF_NULL;
677         ret += UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, range.begin_, range.end_);
678     }
679     return ret;
680 }
681 
EnableDistributedClientNet(const std::string & virNicAddr,const std::string & iif)682 int32_t RouteManager::EnableDistributedClientNet(const std::string &virNicAddr, const std::string &iif)
683 {
684     NETNATIVE_LOGI("EnableDistributedClientNet virNicAddr:%{public}s,iif:%{public}s",
685                    ToAnonymousIp(virNicAddr).c_str(), iif.c_str());
686     int32_t ret = DistributedManager::GetInstance().ConfigVirnicAndVeth(virNicAddr, DISTRIBUTED_TUN_CARD_NAME,
687         DISTRIBUTED_TUN_CARD_NAME_VETH);
688     if (ret != ROUTEMANAGER_SUCCESS) {
689         NETNATIVE_LOGE("ConfigVirnicAndVeth err, error is %{public}d", ret);
690         return ret;
691     }
692     NETNATIVE_LOGI("EnableDistributedClientNet ConfigVirnicAndVeth success.");
693     RuleInfo ruleInfo;
694     ruleInfo.ruleTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
695     ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
696     ruleInfo.ruleIif = iif;
697     ruleInfo.ruleFwmark = MARK_UNSET;
698     ruleInfo.ruleMask = MARK_UNSET;
699     ret = UpdateDistributedRule(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
700     if (ret != ROUTEMANAGER_SUCCESS) {
701         NETNATIVE_LOGE("EnableDistributedClientNet UpdateDistributedRule err, error is %{public}d", ret);
702         return ret;
703     }
704     std::string maskAddr = CommonUtils::GetMaskByLength(DEFAULT_GATEWAY_MASK_MAX_LENGTH);
705     std::string virNicVethAddr = CommonUtils::GetGatewayAddr(virNicAddr, maskAddr);
706     if (virNicVethAddr.empty()) {
707         NETNATIVE_LOGE("get gateway addr is empty");
708         return ROUTEMANAGER_ERROR;
709     }
710     uint32_t table = if_nametoindex(DISTRIBUTED_TUN_CARD_NAME);
711     if (table == 0) {
712         NETNATIVE_LOGE("create Virnic Route, if_nametoindex error %{public}d", errno);
713         return -errno;
714     }
715     table += THOUSAND_LEN;
716 
717     std::string out;
718     std::string createVirnicRoute = std::string(IP_CMD_PATH) + " route add default via " + virNicVethAddr +
719         " dev " + DISTRIBUTED_TUN_CARD_NAME + " table " + std::to_string(table) + " proto static";
720     NETNATIVE_LOGI("create Virnic Route: %{public}s", CommonUtils::AnonymousIpInStr(createVirnicRoute).c_str());
721     if (CommonUtils::ForkExec(createVirnicRoute.c_str(), &out) != ROUTEMANAGER_SUCCESS) {
722         NETNATIVE_LOGE("create Virnic Route failed, output %{public}s", out.c_str());
723         return ROUTEMANAGER_ERROR;
724     }
725     NETNATIVE_LOGI("EnableDistributedClientNet add route success.");
726     return ROUTEMANAGER_SUCCESS;
727 }
728 
AddServerUplinkRoute(const std::string & UplinkIif,const std::string & devIface)729 int32_t RouteManager::AddServerUplinkRoute(const std::string &UplinkIif, const std::string &devIface)
730 {
731     RuleInfo ruleInfo;
732     ruleInfo.ruleTable = ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE;
733     ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
734     ruleInfo.ruleIif = UplinkIif;
735     ruleInfo.ruleFwmark = MARK_UNSET;
736     ruleInfo.ruleMask = MARK_UNSET;
737     int32_t ret = UpdateDistributedRule(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
738     if (ret != ROUTEMANAGER_SUCCESS) {
739         NETNATIVE_LOGE("EnableDistributedServerNet Update Uplink RuleInfo err, error is %{public}d", ret);
740         return ret;
741     }
742 
743     RouteInfo routeInfo;
744     routeInfo.routeTable = ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE;
745     routeInfo.routeInterfaceName = devIface;
746     routeInfo.routeDestinationName = "0.0.0.0/0";
747     routeInfo.routeNextHop = "0.0.0.0";
748     uint16_t flags = (NLM_F_CREATE | NLM_F_EXCL);
749     uint16_t action = RTM_NEWROUTE;
750     ret = UpdateRouteRule(action, flags, routeInfo);
751     if (ret != ROUTEMANAGER_SUCCESS) {
752         NETNATIVE_LOGE("EnableDistributedServerNet Update Uplink RouteRule err, NLM_F_REPLACE");
753         if (UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo)) {
754             UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
755             return ROUTEMANAGER_ERROR;
756         }
757     }
758     NETNATIVE_LOGE("EnableDistributedServerNet AddServerUplinkRoute success");
759 
760     return ROUTEMANAGER_SUCCESS;
761 }
762 
AddServerDownlinkRoute(const std::string & UplinkIif,const std::string & dstAddr)763 int32_t RouteManager::AddServerDownlinkRoute(const std::string &UplinkIif, const std::string &dstAddr)
764 {
765     RuleInfo ruleInfo;
766     ruleInfo.ruleTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
767     ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
768     ruleInfo.ruleDstIp = dstAddr;
769     ruleInfo.ruleFwmark = MARK_UNSET;
770     ruleInfo.ruleMask = MARK_UNSET;
771     int32_t ret = UpdateDistributedRule(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
772     if (ret != ROUTEMANAGER_SUCCESS) {
773         NETNATIVE_LOGE("EnableDistributedServerNet Update Downlink RuleInfo err, error is %{public}d", ret);
774         return ret;
775     }
776 
777     RouteInfo routeInfo;
778     routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
779     routeInfo.routeInterfaceName = UplinkIif;
780     routeInfo.routeDestinationName = "0.0.0.0/0";
781     routeInfo.routeNextHop = "0.0.0.0";
782     uint16_t flags = (NLM_F_CREATE | NLM_F_EXCL);
783     uint16_t action = RTM_NEWROUTE;
784     ret = UpdateRouteRule(action, flags, routeInfo);
785     if (ret != ROUTEMANAGER_SUCCESS) {
786         NETNATIVE_LOGE("EnableDistributedServerNet Update Downlink RouteRule err, NLM_F_REPLACE");
787         if (UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo)) {
788             UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
789             return ROUTEMANAGER_ERROR;
790         }
791     }
792     NETNATIVE_LOGE("EnableDistributedServerNet AddServerDownlinkRoute success");
793 
794     return ROUTEMANAGER_SUCCESS;
795 }
796 
EnableDistributedServerNet(const std::string & iif,const std::string & devIface,const std::string & dstAddr)797 int32_t RouteManager::EnableDistributedServerNet(const std::string &iif, const std::string &devIface,
798                                                  const std::string &dstAddr)
799 {
800     NETNATIVE_LOGI("EnableDistributedServerNet iif:%{public}s,devIface:%{public}s,dstAddr:%{public}s",
801                    iif.c_str(), devIface.c_str(), ToAnonymousIp(dstAddr).c_str());
802 
803     int32_t ret = ROUTEMANAGER_SUCCESS;
804     DistributedManager::GetInstance().SetServerNicInfo(iif, devIface);
805     ret += AddServerUplinkRoute(iif, devIface);
806     ret += AddServerDownlinkRoute(iif, dstAddr);
807 
808     return ret;
809 }
810 
DisableDistributedNet(bool isServer)811 int32_t RouteManager::DisableDistributedNet(bool isServer)
812 {
813     NETNATIVE_LOGI("DisableDistributedNet Enter, isServer:%{public}d", isServer);
814     RuleInfo ruleInfo;
815     ruleInfo.ruleFwmark = MARK_UNSET;
816     ruleInfo.ruleMask = MARK_UNSET;
817     ruleInfo.ruleIif = RULEIIF_NULL;
818     ruleInfo.ruleOif = RULEOIF_NULL;
819     ruleInfo.ruleTable = RT_TABLE_UNSPEC;
820     ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
821     RouteInfo routeInfo;
822     routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
823     routeInfo.routeInterfaceName = DISTRIBUTED_TUN_CARD_NAME;
824     routeInfo.routeDestinationName = "0.0.0.0/0";
825     routeInfo.routeNextHop = "0.0.0.0";
826     int32_t ret = ROUTEMANAGER_SUCCESS;
827     if (isServer) {
828         ret += UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
829         if (ret != ROUTEMANAGER_SUCCESS) {
830             NETNATIVE_LOGE("del server uplink rule err, rule prio is %{public}d", ruleInfo.rulePriority);
831         }
832         ret += UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
833         if (ret != ROUTEMANAGER_SUCCESS) {
834             NETNATIVE_LOGE("del server downlink rule err, rule prio is %{public}d", ruleInfo.rulePriority);
835         }
836         routeInfo.routeTable = ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE;
837         routeInfo.routeInterfaceName = DistributedManager::GetInstance().GetServerDevIfaceNic();
838         ret += UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
839         if (ret != ROUTEMANAGER_SUCCESS) {
840             NETNATIVE_LOGE("del server uplink route err, route table is %{public}d", routeInfo.routeTable);
841         }
842         routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
843         routeInfo.routeInterfaceName = DistributedManager::GetInstance().GetServerIifNic();
844         ret += UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
845         if (ret != ROUTEMANAGER_SUCCESS) {
846             NETNATIVE_LOGE("del server downlink route err, route table is %{public}d", routeInfo.routeTable);
847         }
848     } else {
849         ret += UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
850         if (ret != ROUTEMANAGER_SUCCESS) {
851             NETNATIVE_LOGE("del client rule err, rule prio is %{public}d", ruleInfo.rulePriority);
852         }
853         DistributedManager::GetInstance().DisableVirnic(DISTRIBUTED_TUN_CARD_NAME);
854     }
855     return ret;
856 }
857 
UpdateVpnUidRangeRule(uint32_t table,uid_t uidStart,uid_t uidEnd,bool add,const std::string & interfaceName)858 int32_t RouteManager::UpdateVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd, bool add,
859     const std::string &interfaceName)
860 {
861     Fwmark fwmark;
862     Fwmark mask;
863     fwmark.protectedFromVpn = false;
864     mask.protectedFromVpn = true;
865 
866     RuleInfo ruleInfo;
867     ruleInfo.ruleTable = table;
868 #ifdef SUPPORT_SYSVPN
869     if (CheckMultiVpnCall(interfaceName)) {
870         ruleInfo.rulePriority = FindVpnIdByInterfacename(VpnRuleIdType::VPN_SECURE, interfaceName);
871     } else {
872         ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN;
873     }
874     NETNATIVE_LOG_D("rule priority %{public}d", ruleInfo.rulePriority);
875 #else
876     ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN;
877 #endif // SUPPORT_SYSVPN
878 
879     ruleInfo.ruleFwmark = fwmark.intValue;
880     ruleInfo.ruleMask = mask.intValue;
881     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
882     ruleInfo.ruleOif = RULEOIF_NULL;
883     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd);
884 }
885 
UpdateExplicitNetworkRuleWithUid(int32_t netId,uint32_t table,NetworkPermission permission,uid_t uidStart,uid_t uidEnd,bool add,const std::string & interfaceName)886 int32_t RouteManager::UpdateExplicitNetworkRuleWithUid(int32_t netId, uint32_t table, NetworkPermission permission,
887                                                        uid_t uidStart, uid_t uidEnd, bool add,
888                                                        const std::string &interfaceName)
889 {
890     NETNATIVE_LOGI("UpdateExplicitNetworkRuleWithUid");
891     Fwmark fwmark;
892     fwmark.netId = netId;
893     fwmark.explicitlySelected = true;
894     fwmark.permission = permission;
895 
896     Fwmark mask;
897     mask.netId = FWMARK_NET_ID_MASK;
898     mask.explicitlySelected = true;
899     mask.permission = permission;
900 
901     RuleInfo ruleInfo;
902     ruleInfo.ruleTable = table;
903 #ifdef SUPPORT_SYSVPN
904     if (CheckMultiVpnCall(interfaceName)) {
905         ruleInfo.rulePriority = FindVpnIdByInterfacename(VpnRuleIdType::VPN_EXPLICIT_NETWORK, interfaceName);
906     } else {
907         ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK;
908     }
909     NETNATIVE_LOG_D("rule priority %{public}d", ruleInfo.rulePriority);
910 #else
911     ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK;
912 #endif // SUPPORT_SYSVPN
913     ruleInfo.ruleFwmark = fwmark.intValue;
914     ruleInfo.ruleMask = mask.intValue;
915     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
916     ruleInfo.ruleOif = RULEOIF_NULL;
917 
918     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd);
919 }
920 
UpdateOutputInterfaceRulesWithUid(const std::string & interface,uint32_t table,NetworkPermission permission,uid_t uidStart,uid_t uidEnd,bool add)921 int32_t RouteManager::UpdateOutputInterfaceRulesWithUid(const std::string &interface, uint32_t table,
922                                                         NetworkPermission permission, uid_t uidStart, uid_t uidEnd,
923                                                         bool add)
924 {
925     NETNATIVE_LOGI("UpdateOutputInterfaceRulesWithUid interface:%{public}s", interface.c_str());
926     Fwmark fwmark;
927     fwmark.permission = permission;
928 
929     Fwmark mask;
930     mask.permission = permission;
931 
932     RuleInfo ruleInfo;
933     ruleInfo.ruleTable = table;
934 #ifdef SUPPORT_SYSVPN
935     if (CheckMultiVpnCall(interface)) {
936         ruleInfo.rulePriority = FindVpnIdByInterfacename(VpnRuleIdType::VPN_OUTPUT_IFACE, interface);
937     } else {
938         ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_IFACE_VPN;
939     }
940     NETNATIVE_LOG_D("UpdateOutputInterfaceRulesWithUid rule priority %{public}d", ruleInfo.rulePriority);
941 #else
942     ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_IFACE_VPN;
943 #endif // SUPPORT_SYSVPN
944     ruleInfo.ruleFwmark = fwmark.intValue;
945     ruleInfo.ruleMask = mask.intValue;
946     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
947     ruleInfo.ruleOif = interface;
948 
949     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd);
950 }
951 
AddInterfaceToLocalNetwork(uint16_t netId,const std::string & interfaceName)952 int32_t RouteManager::AddInterfaceToLocalNetwork(uint16_t netId, const std::string &interfaceName)
953 {
954     NETNATIVE_LOGI("AddInterfaceToLocalNetwork, %{public}s", interfaceName.c_str());
955     if (int32_t ret = UpdateLocalNetwork(netId, interfaceName, ADD_CONTROL)) {
956         NETNATIVE_LOGE("UpdateLocalNetwork err, error is %{public}d", ret);
957         return ret;
958     }
959     std::lock_guard lock(interfaceToTableLock_);
960     interfaceToTable_[interfaceName] = ROUTE_LOCAL_NETWORK_TABLE;
961 
962     return 0;
963 }
964 
RemoveInterfaceFromLocalNetwork(uint16_t netId,const std::string & interfaceName)965 int32_t RouteManager::RemoveInterfaceFromLocalNetwork(uint16_t netId, const std::string &interfaceName)
966 {
967     NETNATIVE_LOGI("RemoveInterfaceFromLocalNetwork");
968     if (int32_t ret = UpdateLocalNetwork(netId, interfaceName, DEL_CONTROL)) {
969         NETNATIVE_LOGE("UpdateLocalNetwork err, error is %{public}d", ret);
970         return ret;
971     }
972     std::lock_guard lock(interfaceToTableLock_);
973     interfaceToTable_.erase(interfaceName);
974 
975     return 0;
976 }
977 
EnableSharing(const std::string & inputInterface,const std::string & outputInterface)978 int32_t RouteManager::EnableSharing(const std::string &inputInterface, const std::string &outputInterface)
979 {
980     return UpdateSharingNetwork(RTM_NEWRULE, inputInterface, outputInterface);
981 }
982 
DisableSharing(const std::string & inputInterface,const std::string & outputInterface)983 int32_t RouteManager::DisableSharing(const std::string &inputInterface, const std::string &outputInterface)
984 {
985     return UpdateSharingNetwork(RTM_DELRULE, inputInterface, outputInterface);
986 }
987 
ReadAddrGw(const std::string & addr,InetAddr * res)988 int32_t RouteManager::ReadAddrGw(const std::string &addr, InetAddr *res)
989 {
990     if (res == nullptr) {
991         return -1;
992     }
993 
994     std::string addressString(addr.c_str());
995     if (strchr(addr.c_str(), ':')) {
996         res->family = AF_INET6;
997         res->bitlen = OUTPUT_MAX;
998     } else {
999         res->family = AF_INET;
1000         res->bitlen = BIT_32_LEN;
1001     }
1002 
1003     return inet_pton(res->family, addressString.c_str(), res->data);
1004 }
1005 
ReadAddr(const std::string & addr,InetAddr * res)1006 int32_t RouteManager::ReadAddr(const std::string &addr, InetAddr *res)
1007 {
1008     if (res == nullptr) {
1009         return -EINVAL;
1010     }
1011 
1012     const char *slashStr = strchr(addr.c_str(), '/');
1013     if (slashStr == nullptr) {
1014         return -EINVAL;
1015     }
1016 
1017     const char *maskLenStr = slashStr + 1;
1018     if (*maskLenStr == 0) {
1019         return -EINVAL;
1020     }
1021 
1022     char *endptr = nullptr;
1023     unsigned templen = strtoul(maskLenStr, &endptr, DECIMAL_DIGITAL);
1024     if ((endptr == nullptr) || (templen > BIT_MAX_LEN)) {
1025         return -EINVAL;
1026     }
1027     res->prefixlen = templen;
1028 
1029     std::string addressString(addr.c_str(), slashStr - addr.c_str());
1030     if (strchr(addr.c_str(), ':')) {
1031         res->family = AF_INET6;
1032         res->bitlen = OUTPUT_MAX;
1033     } else {
1034         res->family = AF_INET;
1035         res->bitlen = BIT_32_LEN;
1036     }
1037 
1038     return inet_pton(res->family, addressString.c_str(), res->data);
1039 }
1040 
AddClatTunInterface(const std::string & interfaceName,const std::string & dstAddr,const std::string & nxtHop)1041 int32_t RouteManager::AddClatTunInterface(const std::string &interfaceName, const std::string &dstAddr,
1042                                           const std::string &nxtHop)
1043 {
1044     NETNATIVE_LOGI("AddClatTunInterface, interfaceName:%{public}s; dstAddr:%{public}s; nxtHop:%{public}s;",
1045                    interfaceName.c_str(), dstAddr.c_str(), nxtHop.c_str());
1046     bool routeRepeat = false;
1047     NetworkRouteInfo networkRouteInfo;
1048     networkRouteInfo.ifName = interfaceName;
1049     networkRouteInfo.destination = dstAddr;
1050     networkRouteInfo.nextHop = nxtHop;
1051     networkRouteInfo.isExcludedRoute = false;
1052     if (int32_t ret = AddRoute(RouteManager::INTERFACE, networkRouteInfo, routeRepeat)) {
1053         NETNATIVE_LOGE("AddRoute err, error is %{public}d", ret);
1054         return ret;
1055     }
1056     return UpdateClatTunInterface(interfaceName, PERMISSION_NONE, ADD_CONTROL);
1057 }
1058 
RemoveClatTunInterface(const std::string & interfaceName)1059 int32_t RouteManager::RemoveClatTunInterface(const std::string &interfaceName)
1060 {
1061     NETNATIVE_LOGI("RemoveClatTunInterface, interfaceName:%{public}s", interfaceName.c_str());
1062     if (int32_t ret = UpdateClatTunInterface(interfaceName, PERMISSION_NONE, DEL_CONTROL)) {
1063         NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret);
1064         return ret;
1065     }
1066     if (int32_t ret = ClearRoutes(interfaceName)) {
1067         NETNATIVE_LOGE("ClearRoutes err, error is %{public}d", ret);
1068         return ret;
1069     }
1070     if (int32_t ret = ClearSharingRules(interfaceName)) {
1071         NETNATIVE_LOGE("ClearSharingRules err, error is %{public}d", ret);
1072         return ret;
1073     }
1074 
1075     return 0;
1076 }
1077 
UpdateClatTunInterface(const std::string & interfaceName,NetworkPermission permission,bool add)1078 int32_t RouteManager::UpdateClatTunInterface(const std::string &interfaceName, NetworkPermission permission, bool add)
1079 {
1080     NETNATIVE_LOGI("UpdateClatTunInterface, interfaceName: %{public}s, permission: %{public}d, add: %{public}d",
1081                    interfaceName.c_str(), static_cast<int32_t>(permission), add);
1082     uint32_t table = FindTableByInterfacename(interfaceName);
1083     if (table == RT_TABLE_UNSPEC) {
1084         NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
1085         return -1;
1086     }
1087 
1088     Fwmark fwmark;
1089     fwmark.permission = permission;
1090 
1091     Fwmark mask;
1092     mask.permission = permission;
1093 
1094     RuleInfo ruleInfo;
1095     ruleInfo.ruleTable = table;
1096     ruleInfo.rulePriority = RULE_LEVEL_CLAT_TUN;
1097     ruleInfo.ruleFwmark = fwmark.intValue;
1098     ruleInfo.ruleMask = mask.intValue;
1099     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
1100     ruleInfo.ruleOif = RULEOIF_NULL;
1101 
1102     if (int32_t ret = UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo)) {
1103         NETNATIVE_LOGE("UpdateRuleInfo failed, err is %{public}d", ret);
1104         return ret;
1105     }
1106 
1107     return 0;
1108 }
1109 
Init()1110 int32_t RouteManager::Init()
1111 {
1112     NETNATIVE_LOGI("Init");
1113     // need to call IptablesWrapper's RunCommand function.
1114     std::string commandNew;
1115     commandNew.append(" -t mangle -N ");
1116     commandNew.append(LOCAL_MANGLE_INPUT);
1117 
1118     std::string commandJump;
1119     commandJump.append(" -A INPUT -j ");
1120     commandJump.append(LOCAL_MANGLE_INPUT);
1121 
1122     if (int32_t ret = ClearRules()) {
1123         NETNATIVE_LOGE("ClearRules failed, err is %{public}d", ret);
1124         return ret;
1125     }
1126 
1127     if (access(NETSYS_ROUTE_INIT_DIR_PATH, F_OK) == 0) {
1128         if (int32_t ret = AddLocalNetworkRules()) {
1129             NETNATIVE_LOGE("AddLocalNetworkRules failed, err is %{public}d", ret);
1130             return ret;
1131         }
1132     } else {
1133         NETNATIVE_LOGI("AddLocalNetworkRules init ok, do not need repeat");
1134     }
1135 
1136     return 0;
1137 }
1138 
ClearRules()1139 int32_t RouteManager::ClearRules()
1140 {
1141     return ClearRouteInfo(RTM_GETRULE, 0) >= 0 ? 0 : -1;
1142 }
1143 
ClearRoutes(const std::string & interfaceName,int32_t netId)1144 int32_t RouteManager::ClearRoutes(const std::string &interfaceName, int32_t netId)
1145 {
1146     uint32_t table = FindTableByInterfacename(interfaceName, netId);
1147     NETNATIVE_LOGI("ClearRoutes--table==:%{public}d", table);
1148     if (table == RT_TABLE_UNSPEC) {
1149         return -1;
1150     }
1151     int32_t ret = ClearRouteInfo(RTM_GETROUTE, table);
1152     if (ret == 0 && table > ROUTE_INTERNAL_DEFAULT_TABLE) {
1153         interfaceToTable_.erase(interfaceName);
1154     }
1155 
1156     return 0;
1157 }
1158 
AddLocalNetworkRules()1159 int32_t RouteManager::AddLocalNetworkRules()
1160 {
1161     NETNATIVE_LOGI("AddLocalNetworkRules");
1162     if (int32_t ret =
1163             UpdateExplicitNetworkRule(LOCAL_NET_ID, ROUTE_LOCAL_NETWORK_TABLE, PERMISSION_NONE, ADD_CONTROL)) {
1164         NETNATIVE_LOGE("UpdateExplicitNetworkRule failed, err is %{public}d", ret);
1165         return ret;
1166     }
1167     Fwmark fwmark;
1168     fwmark.explicitlySelected = false;
1169 
1170     Fwmark mask;
1171     mask.explicitlySelected = true;
1172 
1173     RuleInfo ruleInfo;
1174     ruleInfo.ruleTable = ROUTE_LOCAL_NETWORK_TABLE;
1175     ruleInfo.rulePriority = RULE_LEVEL_LOCAL_NETWORK;
1176     ruleInfo.ruleFwmark = fwmark.intValue;
1177     ruleInfo.ruleMask = mask.intValue;
1178     ruleInfo.ruleIif = RULEIIF_NULL;
1179     ruleInfo.ruleOif = RULEOIF_NULL;
1180 
1181     return UpdateRuleInfo(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo);
1182 }
1183 
UpdatePhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission,bool add)1184 int32_t RouteManager::UpdatePhysicalNetwork(uint16_t netId, const std::string &interfaceName,
1185                                             NetworkPermission permission, bool add)
1186 {
1187     NETNATIVE_LOGI("UpdatePhysicalNetwork,add===%{public}d", add);
1188     uint32_t table = FindTableByInterfacename(interfaceName, netId);
1189     if (table == RT_TABLE_UNSPEC) {
1190         NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
1191         return -1;
1192     }
1193 
1194     if (int32_t ret = UpdateExplicitNetworkRule(netId, table, permission, add)) {
1195         NETNATIVE_LOGE("UpdateExplicitNetworkRule failed, err is %{public}d", ret);
1196         return ret;
1197     }
1198 
1199     if (int32_t ret = UpdateOutputInterfaceRules(interfaceName, table, permission, add)) {
1200         NETNATIVE_LOGE("UpdateOutputInterfaceRules failed, err is %{public}d", ret);
1201         return ret;
1202     }
1203 
1204     return 0;
1205 }
1206 
UpdateLocalNetwork(uint16_t netId,const std::string & interfaceName,bool add)1207 int32_t RouteManager::UpdateLocalNetwork(uint16_t netId, const std::string &interfaceName, bool add)
1208 {
1209     NETNATIVE_LOGI("UpdateLocalNetwork");
1210     return UpdateOutputInterfaceRules(interfaceName, ROUTE_LOCAL_NETWORK_TABLE, PERMISSION_NONE, add);
1211 }
1212 
UpdateIncomingPacketMark(uint16_t netId,const std::string & interfaceName,NetworkPermission permission,bool add)1213 int32_t RouteManager::UpdateIncomingPacketMark(uint16_t netId, const std::string &interfaceName,
1214                                                NetworkPermission permission, bool add)
1215 {
1216     NETNATIVE_LOGI("UpdateIncomingPacketMark");
1217     Fwmark fwmark;
1218     fwmark.netId = netId;
1219     fwmark.explicitlySelected = true;
1220     fwmark.protectedFromVpn = true;
1221     fwmark.permission = permission;
1222     const uint32_t mask = ~Fwmark::GetUidBillingMask();
1223     std::string action = "";
1224     if (add) {
1225         action = " -A ";
1226     } else {
1227         action = " -D ";
1228     }
1229     std::stringstream ss;
1230     ss << action << LOCAL_MANGLE_INPUT << " -i " << interfaceName << " -j MARK --set-mark 0x" << std::nouppercase
1231        << std::hex << fwmark.intValue << "/0x" << std::nouppercase << std::hex << mask;
1232     // need to call IptablesWrapper's RunCommand function.
1233 
1234     return 0;
1235 }
1236 
UpdateExplicitNetworkRule(uint16_t netId,uint32_t table,NetworkPermission permission,bool add)1237 int32_t RouteManager::UpdateExplicitNetworkRule(uint16_t netId, uint32_t table, NetworkPermission permission, bool add)
1238 {
1239     NETNATIVE_LOGI("UpdateExplicitNetworkRule");
1240     Fwmark fwmark;
1241     fwmark.netId = netId;
1242     fwmark.explicitlySelected = true;
1243     fwmark.permission = permission;
1244 
1245     Fwmark mask;
1246     mask.netId = FWMARK_NET_ID_MASK;
1247     mask.explicitlySelected = true;
1248     mask.permission = permission;
1249 
1250     RuleInfo ruleInfo;
1251     ruleInfo.ruleTable = table;
1252     ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK;
1253     ruleInfo.ruleFwmark = fwmark.intValue;
1254     ruleInfo.ruleMask = mask.intValue;
1255     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
1256     ruleInfo.ruleOif = RULEOIF_NULL;
1257 
1258     if (NetManagerStandard::IsInternalNetId(netId)) {
1259         return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, UID_ALLOW_INTERNAL.first,
1260                               UID_ALLOW_INTERNAL.second);
1261     }
1262     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
1263 }
1264 
UpdateOutputInterfaceRules(const std::string & interfaceName,uint32_t table,NetworkPermission permission,bool add)1265 int32_t RouteManager::UpdateOutputInterfaceRules(const std::string &interfaceName, uint32_t table,
1266                                                  NetworkPermission permission, bool add)
1267 {
1268     NETNATIVE_LOGI("UpdateOutputInterfaceRules");
1269     Fwmark fwmark;
1270     fwmark.permission = permission;
1271 
1272     Fwmark mask;
1273     mask.permission = permission;
1274 
1275     RuleInfo ruleInfo;
1276     ruleInfo.ruleTable = table;
1277     ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_INTERFACE;
1278     ruleInfo.ruleFwmark = fwmark.intValue;
1279     ruleInfo.ruleMask = mask.intValue;
1280     ruleInfo.ruleIif = RULEIIF_LOOPBACK;
1281     ruleInfo.ruleOif = interfaceName;
1282 
1283     return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
1284 }
1285 
UpdateSharingNetwork(uint16_t action,const std::string & inputInterface,const std::string & outputInterface)1286 int32_t RouteManager::UpdateSharingNetwork(uint16_t action, const std::string &inputInterface,
1287                                            const std::string &outputInterface)
1288 {
1289     NETNATIVE_LOGI("UpdateSharingNetwork");
1290     uint32_t table = FindTableByInterfacename(outputInterface);
1291     if (table == RT_TABLE_UNSPEC) {
1292         return -1;
1293     }
1294 
1295     RuleInfo ruleInfo;
1296     ruleInfo.ruleTable = table;
1297     ruleInfo.rulePriority = RULE_LEVEL_SHARING;
1298     ruleInfo.ruleFwmark = MARK_UNSET;
1299     ruleInfo.ruleMask = MARK_UNSET;
1300     ruleInfo.ruleIif = inputInterface;
1301     ruleInfo.ruleOif = RULEOIF_NULL;
1302 
1303     return UpdateRuleInfo(action, FR_ACT_TO_TBL, ruleInfo);
1304 }
1305 
ClearSharingRules(const std::string & inputInterface)1306 int32_t RouteManager::ClearSharingRules(const std::string &inputInterface)
1307 {
1308     NETNATIVE_LOGI("ClearSharingRules");
1309 
1310     RuleInfo ruleInfo;
1311     ruleInfo.ruleTable = 0;
1312     ruleInfo.rulePriority = RULE_LEVEL_SHARING;
1313     ruleInfo.ruleFwmark = MARK_UNSET;
1314     ruleInfo.ruleMask = MARK_UNSET;
1315     ruleInfo.ruleIif = inputInterface;
1316     ruleInfo.ruleOif = RULEOIF_NULL;
1317 
1318     return UpdateRuleInfo(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
1319 }
1320 
UpdateRuleInfo(uint32_t action,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1321 int32_t RouteManager::UpdateRuleInfo(uint32_t action, uint8_t ruleType, RuleInfo ruleInfo, uid_t uidStart, uid_t uidEnd)
1322 {
1323     NETNATIVE_LOGI("UpdateRuleInfo");
1324     if (ruleInfo.rulePriority < 0) {
1325         NETNATIVE_LOGE("invalid IP-rule priority %{public}d", ruleInfo.rulePriority);
1326         return ROUTEMANAGER_ERROR;
1327     }
1328 
1329     if (ruleInfo.ruleFwmark & ~ruleInfo.ruleMask) {
1330         NETNATIVE_LOGE("mask 0x%{public}x does not select all the bits set in fwmark 0x%{public}x", ruleInfo.ruleMask,
1331                        ruleInfo.ruleFwmark);
1332         return ROUTEMANAGER_ERROR;
1333     }
1334 
1335     if (ruleInfo.ruleTable == RT_TABLE_UNSPEC && ruleType == FR_ACT_TO_TBL && action != RTM_DELRULE) {
1336         NETNATIVE_LOGE("RT_TABLE_UNSPEC only allowed when deleting rules");
1337         return -ENOTUNIQ;
1338     }
1339 
1340     // The main work is to assemble the structure required for rule.
1341     for (const uint8_t family : {AF_INET, AF_INET6}) {
1342         if (SendRuleToKernel(action, family, ruleType, ruleInfo, uidStart, uidEnd) < 0) {
1343             NETNATIVE_LOGE("Update %{public}s rule info failed, action = %{public}d",
1344                            (family == AF_INET) ? "IPv4" : "IPv6", action);
1345             return NETMANAGER_ERR_INTERNAL;
1346         }
1347     }
1348     return NETMANAGER_SUCCESS;
1349 }
1350 
UpdateDistributedRule(uint32_t action,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1351 int32_t RouteManager::UpdateDistributedRule(uint32_t action, uint8_t ruleType, RuleInfo ruleInfo, uid_t uidStart,
1352                                             uid_t uidEnd)
1353 {
1354     NETNATIVE_LOGI("UpdateDistributedRule");
1355     if (ruleInfo.rulePriority < 0) {
1356         NETNATIVE_LOGE("invalid IP-rule priority %{public}d", ruleInfo.rulePriority);
1357         return ROUTEMANAGER_ERROR;
1358     }
1359 
1360     if (ruleInfo.ruleTable == RT_TABLE_UNSPEC && ruleType == FR_ACT_TO_TBL && action != RTM_DELRULE) {
1361         NETNATIVE_LOGE("RT_TABLE_UNSPEC only allowed when deleting rules");
1362         return -ENOTUNIQ;
1363     }
1364 
1365     int32_t family;
1366     if (!ruleInfo.ruleDstIp.empty() && strchr(ruleInfo.ruleDstIp.c_str(), ':')) {
1367         family = AF_INET6;
1368     } else {
1369         family = AF_INET;
1370     }
1371 
1372     if (SendRuleToKernelEx(action, family, ruleType, ruleInfo, uidStart, uidEnd) < 0) {
1373         NETNATIVE_LOGE("Update %{public}s rule info failed, action = %{public}d",
1374                        (family == AF_INET) ? "IPv4" : "IPv6", action);
1375         return NETMANAGER_ERR_INTERNAL;
1376     }
1377 
1378     return NETMANAGER_SUCCESS;
1379 }
1380 
GetRuleFlag(uint32_t action)1381 uint16_t RouteManager::GetRuleFlag(uint32_t action)
1382 {
1383 #ifdef SUPPORT_SYSVPN
1384     return (action == RTM_NEWRULE) ? NLM_F_CREATE : 0;
1385 #else
1386     return (action == RTM_NEWRULE) ? NLM_F_CREATE : NLM_F_EXCL;
1387 #endif // SUPPORT_SYSVPN
1388 }
1389 
SendRuleToKernel(uint32_t action,uint8_t family,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1390 int32_t RouteManager::SendRuleToKernel(uint32_t action, uint8_t family, uint8_t ruleType, RuleInfo ruleInfo,
1391                                        uid_t uidStart, uid_t uidEnd)
1392 {
1393     struct fib_rule_hdr msg = {0};
1394     msg.action = ruleType;
1395     msg.family = family;
1396     uint16_t ruleFlag = GetRuleFlag(action);
1397     NetlinkMsg nlmsg(ruleFlag, NETLINK_MAX_LEN, getpid());
1398     nlmsg.AddRule(action, msg);
1399     if (int32_t ret = nlmsg.AddAttr32(FRA_PRIORITY, ruleInfo.rulePriority)) {
1400         return ret;
1401     }
1402     if (ruleInfo.ruleTable != RT_TABLE_UNSPEC) {
1403         if (int32_t ret = nlmsg.AddAttr32(FRA_TABLE, ruleInfo.ruleTable)) {
1404             return ret;
1405         }
1406     }
1407     if (ruleInfo.ruleMask != 0) {
1408         if (int32_t ret = nlmsg.AddAttr32(FRA_FWMARK, ruleInfo.ruleFwmark)) {
1409             return ret;
1410         }
1411         if (int32_t ret = nlmsg.AddAttr32(FRA_FWMASK, ruleInfo.ruleMask)) {
1412             return ret;
1413         }
1414     }
1415     if ((uidStart != INVALID_UID) && (uidEnd != INVALID_UID)) {
1416         FibRuleUidRange uidRange = {uidStart, uidEnd};
1417         if (int32_t ret = nlmsg.AddAttr(FRA_UID_RANGE, &uidRange, sizeof(uidRange))) {
1418             NETNATIVE_LOGE("SendRuleToKernel FRA_UID_RANGE is error.");
1419             return ret;
1420         }
1421     }
1422     if (ruleInfo.ruleIif != RULEIIF_NULL) {
1423         char ruleIifName[IFNAMSIZ] = {0};
1424         size_t ruleIifLength = strlcpy(ruleIifName, ruleInfo.ruleIif.c_str(), IFNAMSIZ) + 1;
1425         if (int32_t ret = nlmsg.AddAttr(FRA_IIFNAME, ruleIifName, ruleIifLength)) {
1426             return ret;
1427         }
1428     }
1429     if (ruleInfo.ruleOif != RULEOIF_NULL) {
1430         char ruleOifName[IFNAMSIZ] = {0};
1431         size_t ruleOifLength = strlcpy(ruleOifName, ruleInfo.ruleOif.c_str(), IFNAMSIZ) + 1;
1432         if (int32_t ret = nlmsg.AddAttr(FRA_OIFNAME, ruleOifName, ruleOifLength)) {
1433             return ret;
1434         }
1435     }
1436 
1437     return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
1438 }
1439 
SendRuleToKernelEx(uint32_t action,uint8_t family,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1440 int32_t RouteManager::SendRuleToKernelEx(uint32_t action, uint8_t family, uint8_t ruleType, RuleInfo ruleInfo,
1441                                          uid_t uidStart, uid_t uidEnd)
1442 {
1443     struct fib_rule_hdr msg = {0};
1444     msg.action = ruleType;
1445     msg.family = family;
1446     if (ruleInfo.ruleDstIp != RULEIP_NULL && family == AF_INET) {
1447         msg.dst_len = BIT_32_LEN;
1448     }
1449     uint16_t ruleFlag = GetRuleFlag(action);
1450     NetlinkMsg nlmsg(ruleFlag, NETLINK_MAX_LEN, getpid());
1451     nlmsg.AddRule(action, msg);
1452     if (int32_t ret = nlmsg.AddAttr32(FRA_PRIORITY, ruleInfo.rulePriority)) {
1453         return ret;
1454     }
1455     if (ruleInfo.ruleTable != RT_TABLE_UNSPEC) {
1456         if (int32_t ret = nlmsg.AddAttr32(FRA_TABLE, ruleInfo.ruleTable)) {
1457             return ret;
1458         }
1459     }
1460     if (ruleInfo.ruleMask != 0) {
1461         if (int32_t ret = nlmsg.AddAttr32(FRA_FWMARK, ruleInfo.ruleFwmark)) {
1462             return ret;
1463         }
1464         if (int32_t ret = nlmsg.AddAttr32(FRA_FWMASK, ruleInfo.ruleMask)) {
1465             return ret;
1466         }
1467     }
1468     if (ruleInfo.ruleIif != RULEIIF_NULL) {
1469         char ruleIifName[IFNAMSIZ] = {0};
1470         size_t ruleIifLength = strlcpy(ruleIifName, ruleInfo.ruleIif.c_str(), IFNAMSIZ) + 1;
1471         if (int32_t ret = nlmsg.AddAttr(FRA_IIFNAME, ruleIifName, ruleIifLength)) {
1472             return ret;
1473         }
1474     }
1475     if (ruleInfo.ruleDstIp != RULEIP_NULL) {
1476         InetAddr dst = {0};
1477         if (ReadAddrGw(ruleInfo.ruleDstIp, &dst) <= 0) {
1478             NETNATIVE_LOGE("dest addr parse failed.");
1479             return NETMANAGER_ERR_OPERATION_FAILED;
1480         }
1481         if (int32_t ret = nlmsg.AddAttr(FRA_DST, dst.data, dst.bitlen / BYTE_ALIGNMENT)) {
1482             return ret;
1483         }
1484     }
1485     return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
1486 }
1487 
UpdateRouteRule(uint16_t action,uint16_t flags,RouteInfo routeInfo)1488 int32_t RouteManager::UpdateRouteRule(uint16_t action, uint16_t flags, RouteInfo routeInfo)
1489 {
1490     NETNATIVE_LOG_D("UpdateRouteRule");
1491     RouteInfo routeInfoModify = routeInfo;
1492     // The main work is to assemble the structure required for route.
1493     struct rtmsg msg;
1494     (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
1495     msg.rtm_family = AF_INET;
1496     msg.rtm_dst_len = BIT_32_LEN;
1497     msg.rtm_protocol = RTPROT_STATIC;
1498     msg.rtm_scope = RT_SCOPE_UNIVERSE;
1499     msg.rtm_type = RTN_UNICAST;
1500     msg.rtm_table = RT_TABLE_UNSPEC;
1501 
1502     uint32_t index = 0;
1503     if (!routeInfo.routeNextHop.empty() && !strcmp(routeInfo.routeNextHop.c_str(), "unreachable")) {
1504         msg.rtm_type = RTN_UNREACHABLE;
1505         routeInfoModify.routeInterfaceName = "";
1506         routeInfoModify.routeNextHop = "";
1507     } else if ((!routeInfo.routeNextHop.empty() && !strcmp(routeInfo.routeNextHop.c_str(), "throw")) ||
1508         routeInfo.isExcludedRoute == true) {
1509         msg.rtm_type = RTN_THROW;
1510         routeInfoModify.routeInterfaceName = "";
1511         routeInfoModify.routeNextHop = "";
1512     } else {
1513         index = if_nametoindex(routeInfo.routeInterfaceName.c_str());
1514     }
1515 
1516     int32_t ret = SendRouteToKernel(action, flags, msg, routeInfoModify, index);
1517     if (ret < 0) {
1518         NETNATIVE_LOGE("SendNetlinkMsgToKernel Error ret = %{public}d", ret);
1519         return ret;
1520     }
1521 
1522     return 0;
1523 }
1524 
SendRouteToKernel(uint16_t action,uint16_t routeFlag,rtmsg msg,RouteInfo routeInfo,uint32_t index)1525 int32_t RouteManager::SendRouteToKernel(uint16_t action, uint16_t routeFlag, rtmsg msg, RouteInfo routeInfo,
1526                                         uint32_t index)
1527 {
1528     InetAddr dst;
1529     int32_t readAddrResult = ReadAddr(routeInfo.routeDestinationName, &dst);
1530     if (readAddrResult != 1) {
1531         NETNATIVE_LOGE("dest parse failed:%{public}d", readAddrResult);
1532         return -1;
1533     }
1534     msg.rtm_family = static_cast<uint8_t>(dst.family);
1535     msg.rtm_dst_len = static_cast<uint8_t>(dst.prefixlen);
1536     if (dst.family == AF_INET) {
1537         msg.rtm_scope = RT_SCOPE_LINK;
1538     } else if (dst.family == AF_INET6) {
1539         msg.rtm_scope = RT_SCOPE_UNIVERSE;
1540     }
1541 
1542     InetAddr gw = {0};
1543     if (!routeInfo.routeNextHop.empty() && ReadAddrGw(routeInfo.routeNextHop, &gw) <= 0) {
1544         NETNATIVE_LOGE("gw parse failed:%{public}d", readAddrResult);
1545         return -1;
1546     }
1547     if (gw.bitlen != 0) {
1548         msg.rtm_scope = RT_SCOPE_UNIVERSE;
1549         msg.rtm_family = static_cast<uint8_t>(gw.family);
1550     }
1551     NetlinkMsg nlmsg(routeFlag, NETLINK_MAX_LEN, getpid());
1552     nlmsg.AddRoute(action, msg);
1553     if (int32_t ret = nlmsg.AddAttr32(RTA_TABLE, routeInfo.routeTable)) {
1554         return ret;
1555     }
1556     if (int32_t ret = nlmsg.AddAttr(RTA_DST, dst.data, dst.bitlen / BYTE_ALIGNMENT)) {
1557         return ret;
1558     }
1559     if (!routeInfo.routeNextHop.empty()) {
1560         if (int32_t ret = nlmsg.AddAttr(RTA_GATEWAY, gw.data, gw.bitlen / BYTE_ALIGNMENT)) {
1561             return ret;
1562         }
1563     }
1564     if (!routeInfo.routeInterfaceName.empty()) {
1565         NETNATIVE_LOGI("index is :%{public}d", index);
1566         if (int32_t ret = nlmsg.AddAttr32(RTA_OIF, index)) {
1567             return ret;
1568         }
1569     }
1570 
1571     return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
1572 }
1573 
FindTableByInterfacename(const std::string & interfaceName,int32_t netId)1574 uint32_t RouteManager::FindTableByInterfacename(const std::string &interfaceName, int32_t netId)
1575 {
1576     NETNATIVE_LOG_D("FindTableByInterfacename netId %{public}d", netId);
1577     auto iter = interfaceToTable_.find(interfaceName);
1578     if (iter != interfaceToTable_.end()) {
1579         return ConvertTableByNetId(netId, iter->second);
1580     }
1581 
1582     uint32_t table = if_nametoindex(interfaceName.c_str());
1583     if (table == 0) {
1584         NETNATIVE_LOGE("RouteManager cannot find interface %{public}s", interfaceName.c_str());
1585         return RT_TABLE_UNSPEC;
1586     }
1587     table += THOUSAND_LEN;
1588     std::lock_guard lock(RouteManager::interfaceToTableLock_);
1589     interfaceToTable_[interfaceName] = table;
1590     return ConvertTableByNetId(netId, table);
1591 }
1592 
GetRouteTableFromType(TableType tableType,const std::string & interfaceName)1593 uint32_t RouteManager::GetRouteTableFromType(TableType tableType, const std::string &interfaceName)
1594 {
1595     switch (tableType) {
1596         case RouteManager::INTERFACE:
1597             return FindTableByInterfacename(interfaceName);
1598         case RouteManager::LOCAL_NETWORK:
1599             return ROUTE_LOCAL_NETWORK_TABLE;
1600         case RouteManager::VPN_NETWORK:
1601 #ifdef SUPPORT_SYSVPN
1602             if (CheckMultiVpnCall(interfaceName)) {
1603                 return FindVpnIdByInterfacename(VpnRuleIdType::VPN_NETWORK_TABLE, interfaceName);
1604             } else {
1605                 return ROUTE_VPN_NETWORK_TABLE;
1606             }
1607 #else
1608             return ROUTE_VPN_NETWORK_TABLE;
1609 #endif // SUPPORT_SYSVPN
1610         case RouteManager::INTERNAL_DEFAULT:
1611             return FindTableByInterfacename(interfaceName) % ROUTE_INTERNAL_DEFAULT_TABLE + 1;
1612         default:
1613             NETNATIVE_LOGE("tableType [%{tableType}d] is error", tableType);
1614             return RT_TABLE_UNSPEC;
1615     }
1616 }
1617 
SetRouteInfo(TableType tableType,NetworkRouteInfo networkRouteInfo,RouteInfo & routeInfo)1618 int32_t RouteManager::SetRouteInfo(TableType tableType, NetworkRouteInfo networkRouteInfo, RouteInfo &routeInfo)
1619 {
1620     uint32_t table = GetRouteTableFromType(tableType, networkRouteInfo.ifName);
1621     if (table == RT_TABLE_UNSPEC) {
1622         return -1;
1623     }
1624 
1625     routeInfo.routeTable = table;
1626     routeInfo.routeInterfaceName = networkRouteInfo.ifName;
1627     routeInfo.routeDestinationName = networkRouteInfo.destination;
1628     routeInfo.routeNextHop = networkRouteInfo.nextHop;
1629     routeInfo.isExcludedRoute = networkRouteInfo.isExcludedRoute;
1630     return 0;
1631 }
1632 
1633 #ifdef FEATURE_ENTERPRISE_ROUTE_CUSTOM
1634 /* route target uid to enterprise inner net */
UpdateEnterpriseRoute(const std::string & interfaceName,uint32_t uid,bool add)1635 int32_t RouteManager::UpdateEnterpriseRoute(const std::string &interfaceName, uint32_t uid, bool add)
1636 {
1637     NETNATIVE_LOGI("UpdateEnterpriseRoute,interfaceName:%{public}s, uid:%{public}u, add:%{public}d ",
1638         interfaceName.c_str(), uid, add);
1639     uint32_t table = FindTableByInterfacename(interfaceName);
1640     if (table == RT_TABLE_UNSPEC) {
1641         NETNATIVE_LOGE("find table by name fail");
1642         return NETMANAGER_ERR_PARAMETER_ERROR;
1643     }
1644 
1645     RuleInfo ruleInfo;
1646     ruleInfo.ruleTable = table;
1647     ruleInfo.rulePriority = RULE_LEVEL_ENTERPRISE;
1648     uint16_t action = add ? RTM_NEWRULE : RTM_DELRULE;
1649 
1650     if (uid != 0) {
1651         return UpdateRuleInfo(action, FR_ACT_TO_TBL, ruleInfo, uid, uid);
1652     }
1653 
1654     return UpdateRuleInfo(action, FR_ACT_TO_TBL, ruleInfo);
1655 }
1656 #endif
1657 } // namespace nmd
1658 } // namespace OHOS
1659