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