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