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