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