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