1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <arpa/inet.h>
17 #include <cstdint>
18 #include <cstring>
19 #include <iostream>
20 #include <linux/fib_rules.h>
21 #include <linux/netlink.h>
22 #include <linux/rtnetlink.h>
23 #include <map>
24 #include <mutex>
25 #include <net/if.h>
26 #include <netlink_socket.h>
27 #include <sstream>
28 #include <sys/ioctl.h>
29 #include <sys/socket.h>
30 #include <sys/uio.h>
31 #include <unistd.h>
32
33 #include "fwmark.h"
34 #include "net_manager_constants.h"
35 #include "netlink_manager.h"
36 #include "netlink_msg.h"
37 #include "netmanager_base_common_utils.h"
38 #include "netnative_log_wrapper.h"
39 #include "securec.h"
40 #include "distributed_manager.h"
41
42 #include "route_manager.h"
43
44 using namespace OHOS::NetManagerStandard;
45 using namespace OHOS::NetManagerStandard::CommonUtils;
46 namespace OHOS {
47 namespace nmd {
48 namespace {
49 constexpr int32_t RULE_LEVEL_CLAT_TUN = 8000;
50 constexpr int32_t RULE_LEVEL_VPN_OUTPUT_TO_LOCAL = 9000;
51 constexpr int32_t RULE_LEVEL_SECURE_VPN = 10000;
52 constexpr int32_t RULE_LEVEL_VNIC_NETWORK = 10500;
53 constexpr int32_t RULE_LEVEL_EXPLICIT_NETWORK = 11000;
54 constexpr int32_t RULE_LEVEL_OUTPUT_IFACE_VPN = 11500;
55 constexpr int32_t RULE_LEVEL_OUTPUT_INTERFACE = 12000;
56 constexpr int32_t RULE_LEVEL_LOCAL_NETWORK = 13000;
57 constexpr int32_t RULE_LEVEL_SHARING = 14000;
58 constexpr int32_t RULE_LEVEL_DEFAULT = 16000;
59 constexpr int32_t RULE_LEVEL_DISTRIBUTE_COMMUNICATION = 16500;
60 constexpr uint32_t ROUTE_DISTRIBUTE_TO_CLIENT_TABLE = 90;
61 constexpr uint32_t ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE = 91;
62 constexpr uint32_t ROUTE_VNIC_TABLE = 97;
63 constexpr uint32_t ROUTE_VPN_NETWORK_TABLE = 98;
64 constexpr uint32_t ROUTE_LOCAL_NETWORK_TABLE = 99;
65 constexpr uint32_t OUTPUT_MAX = 128;
66 constexpr uint32_t BIT_32_LEN = 32;
67 constexpr uint32_t BIT_MAX_LEN = 255;
68 constexpr uint32_t DECIMAL_DIGITAL = 10;
69 constexpr uint32_t BYTE_ALIGNMENT = 8;
70 constexpr uint32_t THOUSAND_LEN = 100;
71 constexpr uint16_t LOCAL_NET_ID = 99;
72 constexpr uint16_t NETID_UNSET = 0;
73 constexpr uint32_t MARK_UNSET = 0;
74 constexpr uid_t UID_ROOT = 0;
75 constexpr std::pair<uid_t, uid_t> UID_ALLOW_INTERNAL = {7023, 7023};
76 constexpr uint32_t ROUTEMANAGER_SUCCESS = 0;
77 constexpr uint32_t ROUTEMANAGER_ERROR = -1;
78 constexpr bool ADD_CONTROL = true;
79 constexpr bool DEL_CONTROL = false;
80 const std::string RULEIIF_LOOPBACK = "lo";
81 const std::string RULEIIF_NULL = "";
82 const std::string RULEOIF_NULL = "";
83 const std::string RULEIP_NULL = "";
84 const std::string LOCAL_MANGLE_INPUT = "routectrl_mangle_INPUT";
85 constexpr const char *DISTRIBUTED_TUN_CARD_NAME = "virnic";
86 constexpr const char *NETSYS_ROUTE_INIT_DIR_PATH = "/data/service/el1/public/netmanager/route";
87
88 struct FibRuleUidRange {
89 __u32 start;
90 __u32 end;
91 };
92 } // namespace
93
94 std::mutex RouteManager::interfaceToTableLock_;
95 std::map<std::string, uint32_t> RouteManager::interfaceToTable_;
96
RouteManager()97 RouteManager::RouteManager()
98 {
99 Init();
100 }
101
UpdateVnicRoute(const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop,bool add)102 int32_t RouteManager::UpdateVnicRoute(const std::string &interfaceName, const std::string &destinationName,
103 const std::string &nextHop, bool add)
104 {
105 NETNATIVE_LOGI(
106 "VnicChangeRoute,interfaceName:%{public}s,destination:%{public}s, nextHop:%{public}s, add:%{public}d ",
107 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str(), add);
108
109 RouteInfo routeInfo;
110 routeInfo.routeTable = ROUTE_VNIC_TABLE;
111 routeInfo.routeInterfaceName = interfaceName;
112 routeInfo.routeDestinationName = destinationName;
113 routeInfo.routeNextHop = nextHop;
114 uint16_t flags = add ? (NLM_F_CREATE | NLM_F_EXCL) : NLM_F_EXCL;
115 uint16_t action = add ? RTM_NEWROUTE : RTM_DELROUTE;
116
117 return UpdateRouteRule(action, flags, routeInfo);
118 }
119
AddRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop,bool & routeRepeat)120 int32_t RouteManager::AddRoute(TableType tableType, const std::string &interfaceName,
121 const std::string &destinationName, const std::string &nextHop, bool& routeRepeat)
122 {
123 NETNATIVE_LOGI("AddRoute,interfaceName:%{public}s,destination:%{public}s, nextHop:%{public}s",
124 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str());
125
126 // This is a user-defined structure used to integrate the information required for setting up routes.
127 RouteInfo routeInfo;
128 if (SetRouteInfo(tableType, interfaceName, destinationName, nextHop, routeInfo) != 0) {
129 return -1;
130 }
131
132 int32_t ret = UpdateRouteRule(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, routeInfo);
133 if (ret == EEXIST) {
134 routeRepeat = true;
135 } else {
136 routeRepeat = false;
137 }
138 return ret;
139 }
140
RemoveRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)141 int32_t RouteManager::RemoveRoute(TableType tableType, const std::string &interfaceName,
142 const std::string &destinationName, const std::string &nextHop)
143 {
144 NETNATIVE_LOGI("RemoveRoute,interfaceName:%{public}s,destination:%{public}s,nextHop:%{public}s",
145 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str());
146
147 RouteInfo routeInfo;
148 if (SetRouteInfo(tableType, interfaceName, destinationName, nextHop, routeInfo) != 0) {
149 return -1;
150 }
151 return UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
152 }
153
UpdateRoute(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop)154 int32_t RouteManager::UpdateRoute(TableType tableType, const std::string &interfaceName,
155 const std::string &destinationName, const std::string &nextHop)
156 {
157 NETNATIVE_LOGI("UpdateRoute,interfaceName:%{public}s,destination:%{public}s,nextHop:%{public}s",
158 interfaceName.c_str(), ToAnonymousIp(destinationName).c_str(), ToAnonymousIp(nextHop).c_str());
159
160 RouteInfo routeInfo;
161 if (SetRouteInfo(tableType, interfaceName, destinationName, nextHop, routeInfo) != 0) {
162 return -1;
163 }
164 return UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo);
165 }
166
AddInterfaceToDefaultNetwork(const std::string & interfaceName,NetworkPermission permission)167 int32_t RouteManager::AddInterfaceToDefaultNetwork(const std::string &interfaceName, NetworkPermission permission)
168 {
169 NETNATIVE_LOGI("AddInterfaceToDefaultNetwork, %{public}s;permission:%{public}d;", interfaceName.c_str(),
170 permission);
171 uint32_t table = FindTableByInterfacename(interfaceName);
172 if (table == RT_TABLE_UNSPEC) {
173 return -1;
174 }
175 Fwmark fwmark;
176 fwmark.netId = NETID_UNSET;
177 fwmark.permission = permission;
178
179 Fwmark mask;
180 mask.netId = FWMARK_NET_ID_MASK;
181 mask.permission = permission;
182
183 // This is a user-defined structure used to integrate the information required for setting up rules.
184 RuleInfo ruleInfo;
185 ruleInfo.ruleTable = table;
186 ruleInfo.rulePriority = RULE_LEVEL_DEFAULT;
187 ruleInfo.ruleFwmark = fwmark.intValue;
188 ruleInfo.ruleMask = mask.intValue;
189 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
190 ruleInfo.ruleOif = RULEOIF_NULL;
191 return UpdateRuleInfo(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo);
192 }
193
RemoveInterfaceFromDefaultNetwork(const std::string & interfaceName,NetworkPermission permission)194 int32_t RouteManager::RemoveInterfaceFromDefaultNetwork(const std::string &interfaceName, NetworkPermission permission)
195 {
196 NETNATIVE_LOGI("RemoveInterfaceFromDefaultNetwork, %{public}s;permission:%{public}d;", interfaceName.c_str(),
197 permission);
198 uint32_t table = FindTableByInterfacename(interfaceName);
199 if (table == RT_TABLE_UNSPEC) {
200 return -1;
201 }
202
203 Fwmark fwmark;
204 fwmark.netId = NETID_UNSET;
205 fwmark.permission = permission;
206
207 Fwmark mask;
208 mask.netId = FWMARK_NET_ID_MASK;
209 mask.permission = permission;
210
211 RuleInfo ruleInfo;
212 ruleInfo.ruleTable = table;
213 ruleInfo.rulePriority = RULE_LEVEL_DEFAULT;
214 ruleInfo.ruleFwmark = fwmark.intValue;
215 ruleInfo.ruleMask = mask.intValue;
216 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
217 ruleInfo.ruleOif = RULEOIF_NULL;
218 return UpdateRuleInfo(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
219 }
220
AddInterfaceToPhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission)221 int32_t RouteManager::AddInterfaceToPhysicalNetwork(uint16_t netId, const std::string &interfaceName,
222 NetworkPermission permission)
223 {
224 NETNATIVE_LOGI("AddInterfaceToPhysicalNetwork, netId:%{public}d;interfaceName:%{public}s;permission:%{public}d;",
225 netId, interfaceName.c_str(), permission);
226 return UpdatePhysicalNetwork(netId, interfaceName, permission, ADD_CONTROL);
227 }
228
RemoveInterfaceFromPhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission)229 int32_t RouteManager::RemoveInterfaceFromPhysicalNetwork(uint16_t netId, const std::string &interfaceName,
230 NetworkPermission permission)
231 {
232 NETNATIVE_LOGI("RemoveInterfacePhysicalNetwork, netId:%{public}d;interfaceName:%{public}s;permission:%{public}d;",
233 netId, interfaceName.c_str(), permission);
234 if (int32_t ret = UpdatePhysicalNetwork(netId, interfaceName, permission, DEL_CONTROL)) {
235 NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret);
236 return ret;
237 }
238 if (int32_t ret = ClearRoutes(interfaceName, netId)) {
239 NETNATIVE_LOGE("ClearRoutes err, error is %{public}d", ret);
240 return ret;
241 }
242 if (NetManagerStandard::IsInternalNetId(netId)) {
243 NETNATIVE_LOGI("InternalNetId skip");
244 return 0;
245 }
246 if (int32_t ret = ClearSharingRules(interfaceName)) {
247 NETNATIVE_LOGE("ClearSharingRules err, error is %{public}d", ret);
248 return ret;
249 }
250
251 return 0;
252 }
253
ModifyPhysicalNetworkPermission(uint16_t netId,const std::string & interfaceName,NetworkPermission oldPermission,NetworkPermission newPermission)254 int32_t RouteManager::ModifyPhysicalNetworkPermission(uint16_t netId, const std::string &interfaceName,
255 NetworkPermission oldPermission, NetworkPermission newPermission)
256 {
257 NETNATIVE_LOGI("ModifyPhysicalNetworkPermission, %{public}s", interfaceName.c_str());
258 if (int32_t ret = UpdatePhysicalNetwork(netId, interfaceName, newPermission, ADD_CONTROL)) {
259 NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret);
260 return ret;
261 }
262
263 return UpdatePhysicalNetwork(netId, interfaceName, newPermission, DEL_CONTROL);
264 }
265
AddInterfaceToVirtualNetwork(int32_t netId,const std::string & interfaceName)266 int32_t RouteManager::AddInterfaceToVirtualNetwork(int32_t netId, const std::string &interfaceName)
267 {
268 return ModifyVirtualNetBasedRules(netId, interfaceName, true);
269 }
270
RemoveInterfaceFromVirtualNetwork(int32_t netId,const std::string & interfaceName)271 int32_t RouteManager::RemoveInterfaceFromVirtualNetwork(int32_t netId, const std::string &interfaceName)
272 {
273 if (ModifyVirtualNetBasedRules(netId, interfaceName, false) != ROUTEMANAGER_SUCCESS) {
274 return ROUTEMANAGER_ERROR;
275 }
276 return ClearRouteInfo(RTM_GETROUTE, ROUTE_VPN_NETWORK_TABLE);
277 }
278
ModifyVirtualNetBasedRules(int32_t netId,const std::string & ifaceName,bool add)279 int32_t RouteManager::ModifyVirtualNetBasedRules(int32_t netId, const std::string &ifaceName, bool add)
280 {
281 NETNATIVE_LOGI("ModifyVirtualNetBasedRules,add===%{public}d", add);
282 uint32_t table = GetRouteTableFromType(RouteManager::VPN_NETWORK, ifaceName);
283 if (table == RT_TABLE_UNSPEC) {
284 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
285 return ROUTEMANAGER_ERROR;
286 }
287
288 // If the rule fails to be added, continue to execute the next rule
289 int32_t ret = UpdateVpnOutputToLocalRule(ifaceName, add);
290 ret += UpdateVpnSystemPermissionRule(netId, table, add);
291 ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add);
292 return ret;
293 }
294
UpdateVpnOutputToLocalRule(const std::string & interfaceName,bool add)295 int32_t RouteManager::UpdateVpnOutputToLocalRule(const std::string &interfaceName, bool add)
296 {
297 RuleInfo ruleInfo;
298 ruleInfo.ruleTable = ROUTE_LOCAL_NETWORK_TABLE;
299 ruleInfo.rulePriority = RULE_LEVEL_VPN_OUTPUT_TO_LOCAL;
300 ruleInfo.ruleFwmark = MARK_UNSET;
301 ruleInfo.ruleMask = MARK_UNSET;
302 if (interfaceName.find("vpn") == std::string::npos) {
303 ruleInfo.ruleIif = interfaceName;
304 }
305 ruleInfo.ruleOif = RULEOIF_NULL;
306
307 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
308 }
309
UpdateVpnSystemPermissionRule(int32_t netId,uint32_t table,bool add)310 int32_t RouteManager::UpdateVpnSystemPermissionRule(int32_t netId, uint32_t table, bool add)
311 {
312 Fwmark fwmark;
313 fwmark.netId = netId;
314 NetworkPermission permission = NetworkPermission::PERMISSION_SYSTEM;
315 fwmark.permission = permission;
316
317 Fwmark mask;
318 mask.netId = FWMARK_NET_ID_MASK;
319 mask.permission = permission;
320
321 RuleInfo ruleInfo;
322 ruleInfo.ruleTable = table;
323 ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN;
324 ruleInfo.ruleFwmark = fwmark.intValue;
325 ruleInfo.ruleMask = mask.intValue;
326 ruleInfo.ruleIif = RULEIIF_NULL;
327 ruleInfo.ruleOif = RULEOIF_NULL;
328
329 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
330 }
331
AddUsersToVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges)332 int32_t RouteManager::AddUsersToVirtualNetwork(int32_t netId, const std::string &interfaceName,
333 const std::vector<NetManagerStandard::UidRange> &uidRanges)
334 {
335 return UpdateVirtualNetwork(netId, interfaceName, uidRanges, true);
336 }
337
RemoveUsersFromVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges)338 int32_t RouteManager::RemoveUsersFromVirtualNetwork(int32_t netId, const std::string &interfaceName,
339 const std::vector<NetManagerStandard::UidRange> &uidRanges)
340 {
341 return UpdateVirtualNetwork(netId, interfaceName, uidRanges, false);
342 }
343
UpdateVirtualNetwork(int32_t netId,const std::string & interfaceName,const std::vector<NetManagerStandard::UidRange> & uidRanges,bool add)344 int32_t RouteManager::UpdateVirtualNetwork(int32_t netId, const std::string &interfaceName,
345 const std::vector<NetManagerStandard::UidRange> &uidRanges, bool add)
346 {
347 NETNATIVE_LOGI("UpdateVirtualNetwork, add == %{public}d", add);
348 uint32_t table = GetRouteTableFromType(RouteManager::VPN_NETWORK, interfaceName);
349 if (table == RT_TABLE_UNSPEC) {
350 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
351 return ROUTEMANAGER_ERROR;
352 }
353 int32_t ret = ROUTEMANAGER_SUCCESS;
354 for (auto range : uidRanges) {
355 // If the rule fails to be added, continue to execute the next rule
356 ret += UpdateVpnUidRangeRule(table, range.begin_, range.end_, add);
357 ret += UpdateExplicitNetworkRuleWithUid(netId, table, PERMISSION_NONE, range.begin_, range.end_, add);
358 ret += UpdateOutputInterfaceRulesWithUid(interfaceName, table, PERMISSION_NONE, range.begin_, range.end_, add);
359 }
360 return ret;
361 }
362
UpdateVnicUidRangesRule(const std::vector<NetManagerStandard::UidRange> & uidRanges,bool add)363 int32_t RouteManager::UpdateVnicUidRangesRule(const std::vector<NetManagerStandard::UidRange> &uidRanges, bool add)
364 {
365 int32_t ret = ROUTEMANAGER_SUCCESS;
366 for (const auto &range : uidRanges) {
367 Fwmark fwmark;
368 Fwmark mask;
369 fwmark.protectedFromVpn = false;
370 mask.protectedFromVpn = false;
371
372 RuleInfo ruleInfo;
373 ruleInfo.ruleTable = ROUTE_VNIC_TABLE;
374 ruleInfo.rulePriority = RULE_LEVEL_VNIC_NETWORK;
375 ruleInfo.ruleFwmark = fwmark.intValue;
376 ruleInfo.ruleMask = mask.intValue;
377 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
378 ruleInfo.ruleOif = RULEOIF_NULL;
379 ret += UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, range.begin_, range.end_);
380 }
381 return ret;
382 }
383
EnableDistributedClientNet(const std::string & virNicAddr,const std::string & iif)384 int32_t RouteManager::EnableDistributedClientNet(const std::string &virNicAddr, const std::string &iif)
385 {
386 NETNATIVE_LOGI("EnableDistributedClientNet virNicAddr:%{public}s,iif:%{public}s",
387 ToAnonymousIp(virNicAddr).c_str(), iif.c_str());
388 int32_t ret = DistributedManager::GetInstance().CreateDistributedNic(virNicAddr, DISTRIBUTED_TUN_CARD_NAME);
389 if (ret != ROUTEMANAGER_SUCCESS) {
390 NETNATIVE_LOGE("CreateDistributedNic err, error is %{public}d", ret);
391 return ret;
392 }
393 NETNATIVE_LOGI("EnableDistributedClientNet CreateDistributedNic success.");
394 RuleInfo ruleInfo;
395 ruleInfo.ruleTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
396 ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
397 ruleInfo.ruleIif = iif;
398 ruleInfo.ruleFwmark = MARK_UNSET;
399 ruleInfo.ruleMask = MARK_UNSET;
400 ret = UpdateDistributedRule(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
401 if (ret != ROUTEMANAGER_SUCCESS) {
402 NETNATIVE_LOGE("EnableDistributedClientNet UpdateDistributedRule err, error is %{public}d", ret);
403 return ret;
404 }
405 NETNATIVE_LOGI("EnableDistributedClientNet add rule success.");
406 RouteInfo routeInfo;
407 routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
408 routeInfo.routeInterfaceName = DISTRIBUTED_TUN_CARD_NAME;
409 routeInfo.routeDestinationName = "0.0.0.0/0";
410 routeInfo.routeNextHop = "0.0.0.0";
411 uint16_t flags = (NLM_F_CREATE | NLM_F_EXCL);
412 uint16_t action = RTM_NEWROUTE;
413 ret = UpdateRouteRule(action, flags, routeInfo);
414 if (ret != ROUTEMANAGER_SUCCESS) {
415 NETNATIVE_LOGE("EnableDistributedClientNet UpdateRouteRule err, NLM_F_REPLACE");
416 if (UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo)) {
417 UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
418 return ROUTEMANAGER_ERROR;
419 }
420 }
421
422 NETNATIVE_LOGI("EnableDistributedClientNet add route success.");
423 return ROUTEMANAGER_SUCCESS;
424 }
425
AddServerUplinkRoute(const std::string & UplinkIif,const std::string & devIface)426 int32_t RouteManager::AddServerUplinkRoute(const std::string &UplinkIif, const std::string &devIface)
427 {
428 RuleInfo ruleInfo;
429 ruleInfo.ruleTable = ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE;
430 ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
431 ruleInfo.ruleIif = UplinkIif;
432 ruleInfo.ruleFwmark = MARK_UNSET;
433 ruleInfo.ruleMask = MARK_UNSET;
434 int32_t ret = UpdateDistributedRule(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
435 if (ret != ROUTEMANAGER_SUCCESS) {
436 NETNATIVE_LOGE("EnableDistributedServerNet Update Uplink RuleInfo err, error is %{public}d", ret);
437 return ret;
438 }
439
440 RouteInfo routeInfo;
441 routeInfo.routeTable = ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE;
442 routeInfo.routeInterfaceName = devIface;
443 routeInfo.routeDestinationName = "0.0.0.0/0";
444 routeInfo.routeNextHop = "0.0.0.0";
445 uint16_t flags = (NLM_F_CREATE | NLM_F_EXCL);
446 uint16_t action = RTM_NEWROUTE;
447 ret = UpdateRouteRule(action, flags, routeInfo);
448 if (ret != ROUTEMANAGER_SUCCESS) {
449 NETNATIVE_LOGE("EnableDistributedServerNet Update Uplink RouteRule err, NLM_F_REPLACE");
450 if (UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo)) {
451 UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
452 return ROUTEMANAGER_ERROR;
453 }
454 }
455 NETNATIVE_LOGE("EnableDistributedServerNet AddServerUplinkRoute success");
456
457 return ROUTEMANAGER_SUCCESS;
458 }
459
AddServerDownlinkRoute(const std::string & UplinkIif,const std::string & dstAddr)460 int32_t RouteManager::AddServerDownlinkRoute(const std::string &UplinkIif, const std::string &dstAddr)
461 {
462 RuleInfo ruleInfo;
463 ruleInfo.ruleTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
464 ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
465 ruleInfo.ruleDstIp = dstAddr;
466 ruleInfo.ruleFwmark = MARK_UNSET;
467 ruleInfo.ruleMask = MARK_UNSET;
468 int32_t ret = UpdateDistributedRule(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
469 if (ret != ROUTEMANAGER_SUCCESS) {
470 NETNATIVE_LOGE("EnableDistributedServerNet Update Downlink RuleInfo err, error is %{public}d", ret);
471 return ret;
472 }
473
474 RouteInfo routeInfo;
475 routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
476 routeInfo.routeInterfaceName = UplinkIif;
477 routeInfo.routeDestinationName = "0.0.0.0/0";
478 routeInfo.routeNextHop = "0.0.0.0";
479 uint16_t flags = (NLM_F_CREATE | NLM_F_EXCL);
480 uint16_t action = RTM_NEWROUTE;
481 ret = UpdateRouteRule(action, flags, routeInfo);
482 if (ret != ROUTEMANAGER_SUCCESS) {
483 NETNATIVE_LOGE("EnableDistributedServerNet Update Downlink RouteRule err, NLM_F_REPLACE");
484 if (UpdateRouteRule(RTM_NEWROUTE, NLM_F_REPLACE, routeInfo)) {
485 UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
486 return ROUTEMANAGER_ERROR;
487 }
488 }
489 NETNATIVE_LOGE("EnableDistributedServerNet AddServerDownlinkRoute success");
490
491 return ROUTEMANAGER_SUCCESS;
492 }
493
EnableDistributedServerNet(const std::string & iif,const std::string & devIface,const std::string & dstAddr)494 int32_t RouteManager::EnableDistributedServerNet(const std::string &iif, const std::string &devIface,
495 const std::string &dstAddr)
496 {
497 NETNATIVE_LOGI("EnableDistributedServerNet iif:%{public}s,devIface:%{public}s,dstAddr:%{public}s",
498 iif.c_str(), devIface.c_str(), ToAnonymousIp(dstAddr).c_str());
499
500 int32_t ret = ROUTEMANAGER_SUCCESS;
501 DistributedManager::GetInstance().SetServerNicInfo(iif, devIface);
502 ret += AddServerUplinkRoute(iif, devIface);
503 ret += AddServerDownlinkRoute(iif, dstAddr);
504
505 return ret;
506 }
507
DisableDistributedNet(bool isServer)508 int32_t RouteManager::DisableDistributedNet(bool isServer)
509 {
510 NETNATIVE_LOGI("DisableDistributedNet Enter, isServer:%{public}d", isServer);
511 RuleInfo ruleInfo;
512 ruleInfo.ruleFwmark = MARK_UNSET;
513 ruleInfo.ruleMask = MARK_UNSET;
514 ruleInfo.ruleIif = RULEIIF_NULL;
515 ruleInfo.ruleOif = RULEOIF_NULL;
516 ruleInfo.ruleTable = RT_TABLE_UNSPEC;
517 ruleInfo.rulePriority = RULE_LEVEL_DISTRIBUTE_COMMUNICATION;
518 RouteInfo routeInfo;
519 routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
520 routeInfo.routeInterfaceName = DISTRIBUTED_TUN_CARD_NAME;
521 routeInfo.routeDestinationName = "0.0.0.0/0";
522 routeInfo.routeNextHop = "0.0.0.0";
523 int32_t ret = ROUTEMANAGER_SUCCESS;
524 if (isServer) {
525 ret += UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
526 if (ret != ROUTEMANAGER_SUCCESS) {
527 NETNATIVE_LOGE("del server uplink rule err, rule prio is %{public}d", ruleInfo.rulePriority);
528 }
529 ret += UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
530 if (ret != ROUTEMANAGER_SUCCESS) {
531 NETNATIVE_LOGE("del server downlink rule err, rule prio is %{public}d", ruleInfo.rulePriority);
532 }
533 routeInfo.routeTable = ROUTE_DISTRIBUTE_FROM_CLIENT_TABLE;
534 routeInfo.routeInterfaceName = DistributedManager::GetInstance().GetServerDevIfaceNic();
535 ret += UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
536 if (ret != ROUTEMANAGER_SUCCESS) {
537 NETNATIVE_LOGE("del server uplink route err, route table is %{public}d", routeInfo.routeTable);
538 }
539 routeInfo.routeTable = ROUTE_DISTRIBUTE_TO_CLIENT_TABLE;
540 routeInfo.routeInterfaceName = DistributedManager::GetInstance().GetServerIifNic();
541 ret += UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
542 if (ret != ROUTEMANAGER_SUCCESS) {
543 NETNATIVE_LOGE("del server downlink route err, route table is %{public}d", routeInfo.routeTable);
544 }
545 } else {
546 ret += UpdateDistributedRule(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, INVALID_UID, INVALID_UID);
547 if (ret != ROUTEMANAGER_SUCCESS) {
548 NETNATIVE_LOGE("del client rule err, rule prio is %{public}d", ruleInfo.rulePriority);
549 }
550 ret += UpdateRouteRule(RTM_DELROUTE, NLM_F_EXCL, routeInfo);
551 if (ret != ROUTEMANAGER_SUCCESS) {
552 NETNATIVE_LOGE("del client route err, route table is %{public}d", routeInfo.routeTable);
553 }
554 DistributedManager::GetInstance().CloseDistributedTunFd();
555 }
556 return ret;
557 }
558
UpdateVpnUidRangeRule(uint32_t table,uid_t uidStart,uid_t uidEnd,bool add)559 int32_t RouteManager::UpdateVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd, bool add)
560 {
561 Fwmark fwmark;
562 Fwmark mask;
563 fwmark.protectedFromVpn = false;
564 mask.protectedFromVpn = true;
565
566 RuleInfo ruleInfo;
567 ruleInfo.ruleTable = table;
568 ruleInfo.rulePriority = RULE_LEVEL_SECURE_VPN;
569 ruleInfo.ruleFwmark = fwmark.intValue;
570 ruleInfo.ruleMask = mask.intValue;
571 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
572 ruleInfo.ruleOif = RULEOIF_NULL;
573 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd);
574 }
575
UpdateExplicitNetworkRuleWithUid(int32_t netId,uint32_t table,NetworkPermission permission,uid_t uidStart,uid_t uidEnd,bool add)576 int32_t RouteManager::UpdateExplicitNetworkRuleWithUid(int32_t netId, uint32_t table, NetworkPermission permission,
577 uid_t uidStart, uid_t uidEnd, bool add)
578 {
579 NETNATIVE_LOGI("UpdateExplicitNetworkRuleWithUid");
580 Fwmark fwmark;
581 fwmark.netId = netId;
582 fwmark.explicitlySelected = true;
583 fwmark.permission = permission;
584
585 Fwmark mask;
586 mask.netId = FWMARK_NET_ID_MASK;
587 mask.explicitlySelected = true;
588 mask.permission = permission;
589
590 RuleInfo ruleInfo;
591 ruleInfo.ruleTable = table;
592 ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK;
593 ruleInfo.ruleFwmark = fwmark.intValue;
594 ruleInfo.ruleMask = mask.intValue;
595 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
596 ruleInfo.ruleOif = RULEOIF_NULL;
597
598 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd);
599 }
600
UpdateOutputInterfaceRulesWithUid(const std::string & interface,uint32_t table,NetworkPermission permission,uid_t uidStart,uid_t uidEnd,bool add)601 int32_t RouteManager::UpdateOutputInterfaceRulesWithUid(const std::string &interface, uint32_t table,
602 NetworkPermission permission, uid_t uidStart, uid_t uidEnd,
603 bool add)
604 {
605 NETNATIVE_LOGI("UpdateOutputInterfaceRulesWithUid interface:%{public}s", interface.c_str());
606 Fwmark fwmark;
607 fwmark.permission = permission;
608
609 Fwmark mask;
610 mask.permission = permission;
611
612 RuleInfo ruleInfo;
613 ruleInfo.ruleTable = table;
614 ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_IFACE_VPN;
615 ruleInfo.ruleFwmark = fwmark.intValue;
616 ruleInfo.ruleMask = mask.intValue;
617 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
618 ruleInfo.ruleOif = interface;
619
620 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, uidStart, uidEnd);
621 }
622
AddInterfaceToLocalNetwork(uint16_t netId,const std::string & interfaceName)623 int32_t RouteManager::AddInterfaceToLocalNetwork(uint16_t netId, const std::string &interfaceName)
624 {
625 NETNATIVE_LOGI("AddInterfaceToLocalNetwork, %{public}s", interfaceName.c_str());
626 if (int32_t ret = UpdateLocalNetwork(netId, interfaceName, ADD_CONTROL)) {
627 NETNATIVE_LOGE("UpdateLocalNetwork err, error is %{public}d", ret);
628 return ret;
629 }
630 std::lock_guard lock(interfaceToTableLock_);
631 interfaceToTable_[interfaceName] = ROUTE_LOCAL_NETWORK_TABLE;
632
633 return 0;
634 }
635
RemoveInterfaceFromLocalNetwork(uint16_t netId,const std::string & interfaceName)636 int32_t RouteManager::RemoveInterfaceFromLocalNetwork(uint16_t netId, const std::string &interfaceName)
637 {
638 NETNATIVE_LOGI("RemoveInterfaceFromLocalNetwork");
639 if (int32_t ret = UpdateLocalNetwork(netId, interfaceName, DEL_CONTROL)) {
640 NETNATIVE_LOGE("UpdateLocalNetwork err, error is %{public}d", ret);
641 return ret;
642 }
643 std::lock_guard lock(interfaceToTableLock_);
644 interfaceToTable_.erase(interfaceName);
645
646 return 0;
647 }
648
EnableSharing(const std::string & inputInterface,const std::string & outputInterface)649 int32_t RouteManager::EnableSharing(const std::string &inputInterface, const std::string &outputInterface)
650 {
651 return UpdateSharingNetwork(RTM_NEWRULE, inputInterface, outputInterface);
652 }
653
DisableSharing(const std::string & inputInterface,const std::string & outputInterface)654 int32_t RouteManager::DisableSharing(const std::string &inputInterface, const std::string &outputInterface)
655 {
656 return UpdateSharingNetwork(RTM_DELRULE, inputInterface, outputInterface);
657 }
658
ReadAddrGw(const std::string & addr,InetAddr * res)659 int32_t RouteManager::ReadAddrGw(const std::string &addr, InetAddr *res)
660 {
661 if (res == nullptr) {
662 return -1;
663 }
664
665 std::string addressString(addr.c_str());
666 if (strchr(addr.c_str(), ':')) {
667 res->family = AF_INET6;
668 res->bitlen = OUTPUT_MAX;
669 } else {
670 res->family = AF_INET;
671 res->bitlen = BIT_32_LEN;
672 }
673
674 return inet_pton(res->family, addressString.c_str(), res->data);
675 }
676
ReadAddr(const std::string & addr,InetAddr * res)677 int32_t RouteManager::ReadAddr(const std::string &addr, InetAddr *res)
678 {
679 if (res == nullptr) {
680 return -EINVAL;
681 }
682
683 const char *slashStr = strchr(addr.c_str(), '/');
684 if (slashStr == nullptr) {
685 return -EINVAL;
686 }
687
688 const char *maskLenStr = slashStr + 1;
689 if (*maskLenStr == 0) {
690 return -EINVAL;
691 }
692
693 char *endptr = nullptr;
694 unsigned templen = strtoul(maskLenStr, &endptr, DECIMAL_DIGITAL);
695 if ((endptr == nullptr) || (templen > BIT_MAX_LEN)) {
696 return -EINVAL;
697 }
698 res->prefixlen = templen;
699
700 std::string addressString(addr.c_str(), slashStr - addr.c_str());
701 if (strchr(addr.c_str(), ':')) {
702 res->family = AF_INET6;
703 res->bitlen = OUTPUT_MAX;
704 } else {
705 res->family = AF_INET;
706 res->bitlen = BIT_32_LEN;
707 }
708
709 return inet_pton(res->family, addressString.c_str(), res->data);
710 }
711
AddClatTunInterface(const std::string & interfaceName,const std::string & dstAddr,const std::string & nxtHop)712 int32_t RouteManager::AddClatTunInterface(const std::string &interfaceName, const std::string &dstAddr,
713 const std::string &nxtHop)
714 {
715 NETNATIVE_LOGI("AddClatTunInterface, interfaceName:%{public}s; dstAddr:%{public}s; nxtHop:%{public}s;",
716 interfaceName.c_str(), dstAddr.c_str(), nxtHop.c_str());
717 bool routeRepeat = false;
718 if (int32_t ret = AddRoute(RouteManager::INTERFACE, interfaceName, dstAddr, nxtHop, routeRepeat)) {
719 NETNATIVE_LOGE("AddRoute err, error is %{public}d", ret);
720 return ret;
721 }
722 return UpdateClatTunInterface(interfaceName, PERMISSION_NONE, ADD_CONTROL);
723 }
724
RemoveClatTunInterface(const std::string & interfaceName)725 int32_t RouteManager::RemoveClatTunInterface(const std::string &interfaceName)
726 {
727 NETNATIVE_LOGI("RemoveClatTunInterface, interfaceName:%{public}s", interfaceName.c_str());
728 if (int32_t ret = UpdateClatTunInterface(interfaceName, PERMISSION_NONE, DEL_CONTROL)) {
729 NETNATIVE_LOGE("UpdatePhysicalNetwork err, error is %{public}d", ret);
730 return ret;
731 }
732 if (int32_t ret = ClearRoutes(interfaceName)) {
733 NETNATIVE_LOGE("ClearRoutes err, error is %{public}d", ret);
734 return ret;
735 }
736 if (int32_t ret = ClearSharingRules(interfaceName)) {
737 NETNATIVE_LOGE("ClearSharingRules err, error is %{public}d", ret);
738 return ret;
739 }
740
741 return 0;
742 }
743
UpdateClatTunInterface(const std::string & interfaceName,NetworkPermission permission,bool add)744 int32_t RouteManager::UpdateClatTunInterface(const std::string &interfaceName, NetworkPermission permission, bool add)
745 {
746 NETNATIVE_LOGI("UpdateClatTunInterface, interfaceName: %{public}s, permission: %{public}d, add: %{public}d",
747 interfaceName.c_str(), static_cast<int32_t>(permission), add);
748 uint32_t table = FindTableByInterfacename(interfaceName);
749 if (table == RT_TABLE_UNSPEC) {
750 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
751 return -1;
752 }
753
754 Fwmark fwmark;
755 fwmark.permission = permission;
756
757 Fwmark mask;
758 mask.permission = permission;
759
760 RuleInfo ruleInfo;
761 ruleInfo.ruleTable = table;
762 ruleInfo.rulePriority = RULE_LEVEL_CLAT_TUN;
763 ruleInfo.ruleFwmark = fwmark.intValue;
764 ruleInfo.ruleMask = mask.intValue;
765 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
766 ruleInfo.ruleOif = RULEOIF_NULL;
767
768 if (int32_t ret = UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo)) {
769 NETNATIVE_LOGE("UpdateRuleInfo failed, err is %{public}d", ret);
770 return ret;
771 }
772
773 return 0;
774 }
775
Init()776 int32_t RouteManager::Init()
777 {
778 NETNATIVE_LOGI("Init");
779 // need to call IptablesWrapper's RunCommand function.
780 std::string commandNew;
781 commandNew.append(" -t mangle -N ");
782 commandNew.append(LOCAL_MANGLE_INPUT);
783
784 std::string commandJump;
785 commandJump.append(" -A INPUT -j ");
786 commandJump.append(LOCAL_MANGLE_INPUT);
787
788 if (int32_t ret = ClearRules()) {
789 NETNATIVE_LOGE("ClearRules failed, err is %{public}d", ret);
790 return ret;
791 }
792
793 if (access(NETSYS_ROUTE_INIT_DIR_PATH, F_OK) == 0) {
794 if (int32_t ret = AddLocalNetworkRules()) {
795 NETNATIVE_LOGE("AddLocalNetworkRules failed, err is %{public}d", ret);
796 return ret;
797 }
798 } else {
799 NETNATIVE_LOGI("AddLocalNetworkRules init ok, do not need repeat");
800 }
801
802 return 0;
803 }
804
ClearRules()805 int32_t RouteManager::ClearRules()
806 {
807 return ClearRouteInfo(RTM_GETRULE, 0) >= 0 ? 0 : -1;
808 }
809
ClearRoutes(const std::string & interfaceName,int32_t netId)810 int32_t RouteManager::ClearRoutes(const std::string &interfaceName, int32_t netId)
811 {
812 uint32_t table = FindTableByInterfacename(interfaceName, netId);
813 NETNATIVE_LOGI("ClearRoutes--table==:%{public}d", table);
814 if (table == RT_TABLE_UNSPEC) {
815 return -1;
816 }
817 int32_t ret = ClearRouteInfo(RTM_GETROUTE, table);
818 if (ret == 0 && table > ROUTE_INTERNAL_DEFAULT_TABLE) {
819 interfaceToTable_.erase(interfaceName);
820 }
821
822 return 0;
823 }
824
AddLocalNetworkRules()825 int32_t RouteManager::AddLocalNetworkRules()
826 {
827 NETNATIVE_LOGI("AddLocalNetworkRules");
828 if (int32_t ret =
829 UpdateExplicitNetworkRule(LOCAL_NET_ID, ROUTE_LOCAL_NETWORK_TABLE, PERMISSION_NONE, ADD_CONTROL)) {
830 NETNATIVE_LOGE("UpdateExplicitNetworkRule failed, err is %{public}d", ret);
831 return ret;
832 }
833 Fwmark fwmark;
834 fwmark.explicitlySelected = false;
835
836 Fwmark mask;
837 mask.explicitlySelected = true;
838
839 RuleInfo ruleInfo;
840 ruleInfo.ruleTable = ROUTE_LOCAL_NETWORK_TABLE;
841 ruleInfo.rulePriority = RULE_LEVEL_LOCAL_NETWORK;
842 ruleInfo.ruleFwmark = fwmark.intValue;
843 ruleInfo.ruleMask = mask.intValue;
844 ruleInfo.ruleIif = RULEIIF_NULL;
845 ruleInfo.ruleOif = RULEOIF_NULL;
846
847 return UpdateRuleInfo(RTM_NEWRULE, FR_ACT_TO_TBL, ruleInfo);
848 }
849
UpdatePhysicalNetwork(uint16_t netId,const std::string & interfaceName,NetworkPermission permission,bool add)850 int32_t RouteManager::UpdatePhysicalNetwork(uint16_t netId, const std::string &interfaceName,
851 NetworkPermission permission, bool add)
852 {
853 NETNATIVE_LOGI("UpdatePhysicalNetwork,add===%{public}d", add);
854 uint32_t table = FindTableByInterfacename(interfaceName, netId);
855 if (table == RT_TABLE_UNSPEC) {
856 NETNATIVE_LOGE("table == RT_TABLE_UNSPEC, this is error");
857 return -1;
858 }
859
860 if (int32_t ret = UpdateExplicitNetworkRule(netId, table, permission, add)) {
861 NETNATIVE_LOGE("UpdateExplicitNetworkRule failed, err is %{public}d", ret);
862 return ret;
863 }
864
865 if (int32_t ret = UpdateOutputInterfaceRules(interfaceName, table, permission, add)) {
866 NETNATIVE_LOGE("UpdateOutputInterfaceRules failed, err is %{public}d", ret);
867 return ret;
868 }
869
870 return 0;
871 }
872
UpdateLocalNetwork(uint16_t netId,const std::string & interfaceName,bool add)873 int32_t RouteManager::UpdateLocalNetwork(uint16_t netId, const std::string &interfaceName, bool add)
874 {
875 NETNATIVE_LOGI("UpdateLocalNetwork");
876 return UpdateOutputInterfaceRules(interfaceName, ROUTE_LOCAL_NETWORK_TABLE, PERMISSION_NONE, add);
877 }
878
UpdateIncomingPacketMark(uint16_t netId,const std::string & interfaceName,NetworkPermission permission,bool add)879 int32_t RouteManager::UpdateIncomingPacketMark(uint16_t netId, const std::string &interfaceName,
880 NetworkPermission permission, bool add)
881 {
882 NETNATIVE_LOGI("UpdateIncomingPacketMark");
883 Fwmark fwmark;
884 fwmark.netId = netId;
885 fwmark.explicitlySelected = true;
886 fwmark.protectedFromVpn = true;
887 fwmark.permission = permission;
888 const uint32_t mask = ~Fwmark::GetUidBillingMask();
889 std::string action = "";
890 if (add) {
891 action = " -A ";
892 } else {
893 action = " -D ";
894 }
895 std::stringstream ss;
896 ss << action << LOCAL_MANGLE_INPUT << " -i " << interfaceName << " -j MARK --set-mark 0x" << std::nouppercase
897 << std::hex << fwmark.intValue << "/0x" << std::nouppercase << std::hex << mask;
898 // need to call IptablesWrapper's RunCommand function.
899
900 return 0;
901 }
902
UpdateExplicitNetworkRule(uint16_t netId,uint32_t table,NetworkPermission permission,bool add)903 int32_t RouteManager::UpdateExplicitNetworkRule(uint16_t netId, uint32_t table, NetworkPermission permission, bool add)
904 {
905 NETNATIVE_LOGI("UpdateExplicitNetworkRule");
906 Fwmark fwmark;
907 fwmark.netId = netId;
908 fwmark.explicitlySelected = true;
909 fwmark.permission = permission;
910
911 Fwmark mask;
912 mask.netId = FWMARK_NET_ID_MASK;
913 mask.explicitlySelected = true;
914 mask.permission = permission;
915
916 RuleInfo ruleInfo;
917 ruleInfo.ruleTable = table;
918 ruleInfo.rulePriority = RULE_LEVEL_EXPLICIT_NETWORK;
919 ruleInfo.ruleFwmark = fwmark.intValue;
920 ruleInfo.ruleMask = mask.intValue;
921 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
922 ruleInfo.ruleOif = RULEOIF_NULL;
923
924 if (NetManagerStandard::IsInternalNetId(netId)) {
925 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo, UID_ALLOW_INTERNAL.first,
926 UID_ALLOW_INTERNAL.second);
927 }
928 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
929 }
930
UpdateOutputInterfaceRules(const std::string & interfaceName,uint32_t table,NetworkPermission permission,bool add)931 int32_t RouteManager::UpdateOutputInterfaceRules(const std::string &interfaceName, uint32_t table,
932 NetworkPermission permission, bool add)
933 {
934 NETNATIVE_LOGI("UpdateOutputInterfaceRules");
935 Fwmark fwmark;
936 fwmark.permission = permission;
937
938 Fwmark mask;
939 mask.permission = permission;
940
941 RuleInfo ruleInfo;
942 ruleInfo.ruleTable = table;
943 ruleInfo.rulePriority = RULE_LEVEL_OUTPUT_INTERFACE;
944 ruleInfo.ruleFwmark = fwmark.intValue;
945 ruleInfo.ruleMask = mask.intValue;
946 ruleInfo.ruleIif = RULEIIF_LOOPBACK;
947 ruleInfo.ruleOif = interfaceName;
948
949 return UpdateRuleInfo(add ? RTM_NEWRULE : RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
950 }
951
UpdateSharingNetwork(uint16_t action,const std::string & inputInterface,const std::string & outputInterface)952 int32_t RouteManager::UpdateSharingNetwork(uint16_t action, const std::string &inputInterface,
953 const std::string &outputInterface)
954 {
955 NETNATIVE_LOGI("UpdateSharingNetwork");
956 uint32_t table = FindTableByInterfacename(outputInterface);
957 if (table == RT_TABLE_UNSPEC) {
958 return -1;
959 }
960
961 RuleInfo ruleInfo;
962 ruleInfo.ruleTable = table;
963 ruleInfo.rulePriority = RULE_LEVEL_SHARING;
964 ruleInfo.ruleFwmark = MARK_UNSET;
965 ruleInfo.ruleMask = MARK_UNSET;
966 ruleInfo.ruleIif = inputInterface;
967 ruleInfo.ruleOif = RULEOIF_NULL;
968
969 return UpdateRuleInfo(action, FR_ACT_TO_TBL, ruleInfo);
970 }
971
ClearSharingRules(const std::string & inputInterface)972 int32_t RouteManager::ClearSharingRules(const std::string &inputInterface)
973 {
974 NETNATIVE_LOGI("ClearSharingRules");
975
976 RuleInfo ruleInfo;
977 ruleInfo.ruleTable = 0;
978 ruleInfo.rulePriority = RULE_LEVEL_SHARING;
979 ruleInfo.ruleFwmark = MARK_UNSET;
980 ruleInfo.ruleMask = MARK_UNSET;
981 ruleInfo.ruleIif = inputInterface;
982 ruleInfo.ruleOif = RULEOIF_NULL;
983
984 return UpdateRuleInfo(RTM_DELRULE, FR_ACT_TO_TBL, ruleInfo);
985 }
986
UpdateRuleInfo(uint32_t action,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)987 int32_t RouteManager::UpdateRuleInfo(uint32_t action, uint8_t ruleType, RuleInfo ruleInfo, uid_t uidStart, uid_t uidEnd)
988 {
989 NETNATIVE_LOGI("UpdateRuleInfo");
990 if (ruleInfo.rulePriority < 0) {
991 NETNATIVE_LOGE("invalid IP-rule priority %{public}d", ruleInfo.rulePriority);
992 return ROUTEMANAGER_ERROR;
993 }
994
995 if (ruleInfo.ruleFwmark & ~ruleInfo.ruleMask) {
996 NETNATIVE_LOGE("mask 0x%{public}x does not select all the bits set in fwmark 0x%{public}x", ruleInfo.ruleMask,
997 ruleInfo.ruleFwmark);
998 return ROUTEMANAGER_ERROR;
999 }
1000
1001 if (ruleInfo.ruleTable == RT_TABLE_UNSPEC && ruleType == FR_ACT_TO_TBL && action != RTM_DELRULE) {
1002 NETNATIVE_LOGE("RT_TABLE_UNSPEC only allowed when deleting rules");
1003 return -ENOTUNIQ;
1004 }
1005
1006 // The main work is to assemble the structure required for rule.
1007 for (const uint8_t family : {AF_INET, AF_INET6}) {
1008 if (SendRuleToKernel(action, family, ruleType, ruleInfo, uidStart, uidEnd) < 0) {
1009 NETNATIVE_LOGE("Update %{public}s rule info failed, action = %{public}d",
1010 (family == AF_INET) ? "IPv4" : "IPv6", action);
1011 return NETMANAGER_ERR_INTERNAL;
1012 }
1013 }
1014 return NETMANAGER_SUCCESS;
1015 }
1016
UpdateDistributedRule(uint32_t action,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1017 int32_t RouteManager::UpdateDistributedRule(uint32_t action, uint8_t ruleType, RuleInfo ruleInfo, uid_t uidStart,
1018 uid_t uidEnd)
1019 {
1020 NETNATIVE_LOGI("UpdateDistributedRule");
1021 if (ruleInfo.rulePriority < 0) {
1022 NETNATIVE_LOGE("invalid IP-rule priority %{public}d", ruleInfo.rulePriority);
1023 return ROUTEMANAGER_ERROR;
1024 }
1025
1026 if (ruleInfo.ruleTable == RT_TABLE_UNSPEC && ruleType == FR_ACT_TO_TBL && action != RTM_DELRULE) {
1027 NETNATIVE_LOGE("RT_TABLE_UNSPEC only allowed when deleting rules");
1028 return -ENOTUNIQ;
1029 }
1030
1031 int32_t family;
1032 if (!ruleInfo.ruleDstIp.empty() && strchr(ruleInfo.ruleDstIp.c_str(), ':')) {
1033 family = AF_INET6;
1034 } else {
1035 family = AF_INET;
1036 }
1037
1038 if (SendRuleToKernelEx(action, family, ruleType, ruleInfo, uidStart, uidEnd) < 0) {
1039 NETNATIVE_LOGE("Update %{public}s rule info failed, action = %{public}d",
1040 (family == AF_INET) ? "IPv4" : "IPv6", action);
1041 return NETMANAGER_ERR_INTERNAL;
1042 }
1043
1044 return NETMANAGER_SUCCESS;
1045 }
1046
SendRuleToKernel(uint32_t action,uint8_t family,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1047 int32_t RouteManager::SendRuleToKernel(uint32_t action, uint8_t family, uint8_t ruleType, RuleInfo ruleInfo,
1048 uid_t uidStart, uid_t uidEnd)
1049 {
1050 struct fib_rule_hdr msg = {0};
1051 msg.action = ruleType;
1052 msg.family = family;
1053 uint16_t ruleFlag = (action == RTM_NEWRULE) ? NLM_F_CREATE : NLM_F_EXCL;
1054 NetlinkMsg nlmsg(ruleFlag, NETLINK_MAX_LEN, getpid());
1055 nlmsg.AddRule(action, msg);
1056 if (int32_t ret = nlmsg.AddAttr32(FRA_PRIORITY, ruleInfo.rulePriority)) {
1057 return ret;
1058 }
1059 if (ruleInfo.ruleTable != RT_TABLE_UNSPEC) {
1060 if (int32_t ret = nlmsg.AddAttr32(FRA_TABLE, ruleInfo.ruleTable)) {
1061 return ret;
1062 }
1063 }
1064 if (ruleInfo.ruleMask != 0) {
1065 if (int32_t ret = nlmsg.AddAttr32(FRA_FWMARK, ruleInfo.ruleFwmark)) {
1066 return ret;
1067 }
1068 if (int32_t ret = nlmsg.AddAttr32(FRA_FWMASK, ruleInfo.ruleMask)) {
1069 return ret;
1070 }
1071 }
1072 if ((uidStart != INVALID_UID) && (uidEnd != INVALID_UID)) {
1073 FibRuleUidRange uidRange = {uidStart, uidEnd};
1074 if (int32_t ret = nlmsg.AddAttr(FRA_UID_RANGE, &uidRange, sizeof(uidRange))) {
1075 NETNATIVE_LOGE("SendRuleToKernel FRA_UID_RANGE is error.");
1076 return ret;
1077 }
1078 }
1079 if (ruleInfo.ruleIif != RULEIIF_NULL) {
1080 char ruleIifName[IFNAMSIZ] = {0};
1081 size_t ruleIifLength = strlcpy(ruleIifName, ruleInfo.ruleIif.c_str(), IFNAMSIZ) + 1;
1082 if (int32_t ret = nlmsg.AddAttr(FRA_IIFNAME, ruleIifName, ruleIifLength)) {
1083 return ret;
1084 }
1085 }
1086 if (ruleInfo.ruleOif != RULEOIF_NULL) {
1087 char ruleOifName[IFNAMSIZ] = {0};
1088 size_t ruleOifLength = strlcpy(ruleOifName, ruleInfo.ruleOif.c_str(), IFNAMSIZ) + 1;
1089 if (int32_t ret = nlmsg.AddAttr(FRA_OIFNAME, ruleOifName, ruleOifLength)) {
1090 return ret;
1091 }
1092 }
1093
1094 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
1095 }
1096
SendRuleToKernelEx(uint32_t action,uint8_t family,uint8_t ruleType,RuleInfo ruleInfo,uid_t uidStart,uid_t uidEnd)1097 int32_t RouteManager::SendRuleToKernelEx(uint32_t action, uint8_t family, uint8_t ruleType, RuleInfo ruleInfo,
1098 uid_t uidStart, uid_t uidEnd)
1099 {
1100 struct fib_rule_hdr msg = {0};
1101 msg.action = ruleType;
1102 msg.family = family;
1103 if (ruleInfo.ruleDstIp != RULEIP_NULL && family == AF_INET) {
1104 msg.dst_len = BIT_32_LEN;
1105 }
1106 uint16_t ruleFlag = (action == RTM_NEWRULE) ? NLM_F_CREATE : NLM_F_EXCL;
1107 NetlinkMsg nlmsg(ruleFlag, NETLINK_MAX_LEN, getpid());
1108 nlmsg.AddRule(action, msg);
1109 if (int32_t ret = nlmsg.AddAttr32(FRA_PRIORITY, ruleInfo.rulePriority)) {
1110 return ret;
1111 }
1112 if (ruleInfo.ruleTable != RT_TABLE_UNSPEC) {
1113 if (int32_t ret = nlmsg.AddAttr32(FRA_TABLE, ruleInfo.ruleTable)) {
1114 return ret;
1115 }
1116 }
1117 if (ruleInfo.ruleMask != 0) {
1118 if (int32_t ret = nlmsg.AddAttr32(FRA_FWMARK, ruleInfo.ruleFwmark)) {
1119 return ret;
1120 }
1121 if (int32_t ret = nlmsg.AddAttr32(FRA_FWMASK, ruleInfo.ruleMask)) {
1122 return ret;
1123 }
1124 }
1125 if (ruleInfo.ruleIif != RULEIIF_NULL) {
1126 char ruleIifName[IFNAMSIZ] = {0};
1127 size_t ruleIifLength = strlcpy(ruleIifName, ruleInfo.ruleIif.c_str(), IFNAMSIZ) + 1;
1128 if (int32_t ret = nlmsg.AddAttr(FRA_IIFNAME, ruleIifName, ruleIifLength)) {
1129 return ret;
1130 }
1131 }
1132 if (ruleInfo.ruleDstIp != RULEIP_NULL) {
1133 InetAddr dst = {0};
1134 if (ReadAddrGw(ruleInfo.ruleDstIp, &dst) <= 0) {
1135 NETNATIVE_LOGE("dest addr parse failed.");
1136 return NETMANAGER_ERR_OPERATION_FAILED;
1137 }
1138 if (int32_t ret = nlmsg.AddAttr(FRA_DST, dst.data, dst.bitlen / BYTE_ALIGNMENT)) {
1139 return ret;
1140 }
1141 }
1142 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
1143 }
1144
UpdateRouteRule(uint16_t action,uint16_t flags,RouteInfo routeInfo)1145 int32_t RouteManager::UpdateRouteRule(uint16_t action, uint16_t flags, RouteInfo routeInfo)
1146 {
1147 NETNATIVE_LOG_D("UpdateRouteRule");
1148 RouteInfo routeInfoModify = routeInfo;
1149 // The main work is to assemble the structure required for route.
1150 struct rtmsg msg;
1151 (void)memset_s(&msg, sizeof(msg), 0, sizeof(msg));
1152 msg.rtm_family = AF_INET;
1153 msg.rtm_dst_len = BIT_32_LEN;
1154 msg.rtm_protocol = RTPROT_STATIC;
1155 msg.rtm_scope = RT_SCOPE_UNIVERSE;
1156 msg.rtm_type = RTN_UNICAST;
1157 msg.rtm_table = RT_TABLE_UNSPEC;
1158
1159 uint32_t index = 0;
1160 if (!routeInfo.routeNextHop.empty() && !strcmp(routeInfo.routeNextHop.c_str(), "unreachable")) {
1161 msg.rtm_type = RTN_UNREACHABLE;
1162 routeInfoModify.routeInterfaceName = "";
1163 routeInfoModify.routeNextHop = "";
1164 } else if (!routeInfo.routeNextHop.empty() && !strcmp(routeInfo.routeNextHop.c_str(), "throw")) {
1165 msg.rtm_type = RTN_THROW;
1166 routeInfoModify.routeInterfaceName = "";
1167 routeInfoModify.routeNextHop = "";
1168 } else {
1169 index = if_nametoindex(routeInfo.routeInterfaceName.c_str());
1170 }
1171
1172 int32_t ret = SendRouteToKernel(action, flags, msg, routeInfoModify, index);
1173 if (ret < 0) {
1174 NETNATIVE_LOGE("SendNetlinkMsgToKernel Error ret = %{public}d", ret);
1175 return ret;
1176 }
1177
1178 return 0;
1179 }
1180
SendRouteToKernel(uint16_t action,uint16_t routeFlag,rtmsg msg,RouteInfo routeInfo,uint32_t index)1181 int32_t RouteManager::SendRouteToKernel(uint16_t action, uint16_t routeFlag, rtmsg msg, RouteInfo routeInfo,
1182 uint32_t index)
1183 {
1184 InetAddr dst;
1185 int32_t readAddrResult = ReadAddr(routeInfo.routeDestinationName, &dst);
1186 if (readAddrResult != 1) {
1187 NETNATIVE_LOGE("dest parse failed:%{public}d", readAddrResult);
1188 return -1;
1189 }
1190 msg.rtm_family = static_cast<uint8_t>(dst.family);
1191 msg.rtm_dst_len = static_cast<uint8_t>(dst.prefixlen);
1192 if (dst.family == AF_INET) {
1193 msg.rtm_scope = RT_SCOPE_LINK;
1194 } else if (dst.family == AF_INET6) {
1195 msg.rtm_scope = RT_SCOPE_UNIVERSE;
1196 }
1197
1198 InetAddr gw = {0};
1199 if (!routeInfo.routeNextHop.empty() && ReadAddrGw(routeInfo.routeNextHop, &gw) <= 0) {
1200 NETNATIVE_LOGE("gw parse failed:%{public}d", readAddrResult);
1201 return -1;
1202 }
1203 if (gw.bitlen != 0) {
1204 msg.rtm_scope = RT_SCOPE_UNIVERSE;
1205 msg.rtm_family = static_cast<uint8_t>(gw.family);
1206 }
1207 NetlinkMsg nlmsg(routeFlag, NETLINK_MAX_LEN, getpid());
1208 nlmsg.AddRoute(action, msg);
1209 if (int32_t ret = nlmsg.AddAttr32(RTA_TABLE, routeInfo.routeTable)) {
1210 return ret;
1211 }
1212 if (int32_t ret = nlmsg.AddAttr(RTA_DST, dst.data, dst.bitlen / BYTE_ALIGNMENT)) {
1213 return ret;
1214 }
1215 if (!routeInfo.routeNextHop.empty()) {
1216 if (int32_t ret = nlmsg.AddAttr(RTA_GATEWAY, gw.data, gw.bitlen / BYTE_ALIGNMENT)) {
1217 return ret;
1218 }
1219 }
1220 if (!routeInfo.routeInterfaceName.empty()) {
1221 NETNATIVE_LOGI("index is :%{public}d", index);
1222 if (int32_t ret = nlmsg.AddAttr32(RTA_OIF, index)) {
1223 return ret;
1224 }
1225 }
1226
1227 return SendNetlinkMsgToKernel(nlmsg.GetNetLinkMessage());
1228 }
1229
FindTableByInterfacename(const std::string & interfaceName,int32_t netId)1230 uint32_t RouteManager::FindTableByInterfacename(const std::string &interfaceName, int32_t netId)
1231 {
1232 NETNATIVE_LOGI("FindTableByInterfacename netId %{public}d", netId);
1233 auto iter = interfaceToTable_.find(interfaceName);
1234 if (iter != interfaceToTable_.end()) {
1235 return ConvertTableByNetId(netId, iter->second);
1236 }
1237
1238 uint32_t table = if_nametoindex(interfaceName.c_str());
1239 if (table == 0) {
1240 NETNATIVE_LOGE("RouteManager cannot find interface %{public}s", interfaceName.c_str());
1241 return RT_TABLE_UNSPEC;
1242 }
1243 table += THOUSAND_LEN;
1244 std::lock_guard lock(RouteManager::interfaceToTableLock_);
1245 interfaceToTable_[interfaceName] = table;
1246 return ConvertTableByNetId(netId, table);
1247 }
1248
GetRouteTableFromType(TableType tableType,const std::string & interfaceName)1249 uint32_t RouteManager::GetRouteTableFromType(TableType tableType, const std::string &interfaceName)
1250 {
1251 switch (tableType) {
1252 case RouteManager::INTERFACE:
1253 return FindTableByInterfacename(interfaceName);
1254 case RouteManager::LOCAL_NETWORK:
1255 return ROUTE_LOCAL_NETWORK_TABLE;
1256 case RouteManager::VPN_NETWORK:
1257 return ROUTE_VPN_NETWORK_TABLE;
1258 case RouteManager::INTERNAL_DEFAULT:
1259 return FindTableByInterfacename(interfaceName) % ROUTE_INTERNAL_DEFAULT_TABLE + 1;
1260 default:
1261 NETNATIVE_LOGE("tableType [%{tableType}d] is error", tableType);
1262 return RT_TABLE_UNSPEC;
1263 }
1264 }
1265
SetRouteInfo(TableType tableType,const std::string & interfaceName,const std::string & destinationName,const std::string & nextHop,RouteInfo & routeInfo)1266 int32_t RouteManager::SetRouteInfo(TableType tableType, const std::string &interfaceName,
1267 const std::string &destinationName, const std::string &nextHop, RouteInfo &routeInfo)
1268 {
1269 uint32_t table = GetRouteTableFromType(tableType, interfaceName);
1270 if (table == RT_TABLE_UNSPEC) {
1271 return -1;
1272 }
1273
1274 routeInfo.routeTable = table;
1275 routeInfo.routeInterfaceName = interfaceName;
1276 routeInfo.routeDestinationName = destinationName;
1277 routeInfo.routeNextHop = nextHop;
1278 return 0;
1279 }
1280 } // namespace nmd
1281 } // namespace OHOS
1282