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