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