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