blob: a56d4e05d99f9f23c4e771d2a5b6ebe30a12095f [file] [log] [blame]
Sreeram Ramachandrand736d4b2014-03-26 18:33:47 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Bernie Innocenti762dcf42019-06-14 19:52:49 +090017#pragma once
Sreeram Ramachandrand736d4b2014-03-26 18:33:47 -070018
Chiachang Wang5320c1a2022-03-07 19:19:33 +080019#include "InterfaceController.h" // getParameter
20#include "NetdConstants.h" // IptablesTarget
21#include "Network.h" // UidRangeMap
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070022#include "Permission.h"
23
Luke Huang534980c2018-07-06 17:50:11 +080024#include <android-base/thread_annotations.h>
25
Lorenzo Colitti60367db2017-02-13 16:31:45 +090026#include <linux/netlink.h>
Luke Huangd1ee4622018-06-29 13:49:58 +080027#include <sys/types.h>
28#include <map>
Luke Huang534980c2018-07-06 17:50:11 +080029#include <mutex>
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070030
Bernie Innocenti762dcf42019-06-14 19:52:49 +090031namespace android::net {
Lorenzo Colitti7035f222017-02-13 18:29:00 +090032
Ken Chen69839af2021-01-05 22:48:32 +080033// clang-format off
Chiachang Wang2e9443f2022-01-14 22:55:36 +080034constexpr int32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000;
35constexpr int32_t RULE_PRIORITY_VPN_OVERRIDE_OIF = 11000;
36constexpr int32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 12000;
37constexpr int32_t RULE_PRIORITY_SECURE_VPN = 13000;
38constexpr int32_t RULE_PRIORITY_PROHIBIT_NON_VPN = 14000;
Ken Chen8738e1c2020-11-24 11:38:54 +080039// Rules used when applications explicitly select a network that they have permission to use only
40// because they are in the list of UID ranges for that network.
41//
42// Sockets from these UIDs will not match RULE_PRIORITY_EXPLICIT_NETWORK rules because they will
43// not have the necessary permission bits in the fwmark. We cannot just give any socket on any of
44// these networks the permission bits, because if the UID that created the socket loses access to
45// the network, then the socket must not match any rule that selects that network.
Chiachang Wang2e9443f2022-01-14 22:55:36 +080046constexpr int32_t RULE_PRIORITY_UID_EXPLICIT_NETWORK = 15000;
47constexpr int32_t RULE_PRIORITY_EXPLICIT_NETWORK = 16000;
48constexpr int32_t RULE_PRIORITY_OUTPUT_INTERFACE = 17000;
49constexpr int32_t RULE_PRIORITY_LEGACY_SYSTEM = 18000;
50constexpr int32_t RULE_PRIORITY_LEGACY_NETWORK = 19000;
51constexpr int32_t RULE_PRIORITY_LOCAL_NETWORK = 20000;
52constexpr int32_t RULE_PRIORITY_TETHERING = 21000;
Ken Chen8738e1c2020-11-24 11:38:54 +080053// Implicit rules for sockets that connected on a given network because the network was the default
54// network for the UID.
Chiachang Wang2e9443f2022-01-14 22:55:36 +080055constexpr int32_t RULE_PRIORITY_UID_IMPLICIT_NETWORK = 22000;
56constexpr int32_t RULE_PRIORITY_IMPLICIT_NETWORK = 23000;
57constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION = 24000;
chiachangwang0d5ae982022-05-17 05:16:16 +000058// Sets of rules used for excluding local routes from the VPN. Look up tables
59// that contain directly-connected local routes taken from the default network.
60// The first set is used for apps that have a per-UID default network. The rule
61// UID ranges match those of the per-UID default network rule for that network.
62// The second set has no UID ranges and is used for apps whose default network
63// is the system default network network.
64constexpr int32_t RULE_PRIORITY_UID_LOCAL_ROUTES = 25000;
65constexpr int32_t RULE_PRIORITY_LOCAL_ROUTES = 26000;
66constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION = 27000;
67constexpr int32_t RULE_PRIORITY_VPN_FALLTHROUGH = 28000;
68constexpr int32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 29000;
Ken Chen4e8ef9b2021-03-17 01:57:19 +080069// Rule used when framework wants to disable default network from specified applications. There will
70// be a small interval the same uid range exists in both UID_DEFAULT_UNREACHABLE and
71// UID_DEFAULT_NETWORK when framework is switching user preferences.
72//
73// framework --> netd
74// step 1: set uid to unreachable network
75// step 2: remove uid from OEM-paid network list
Ken Chen55db3802021-03-30 13:47:49 +080076// or
77// step 1: add uid to OEM-paid network list
78// step 2: remove uid from unreachable network
Ken Chen4e8ef9b2021-03-17 01:57:19 +080079//
Ken Chen55db3802021-03-30 13:47:49 +080080// The priority is lower than UID_DEFAULT_NETWORK. Otherwise, the app will be told by
81// ConnectivityService that it has a network in step 1 of the second case. But if it tries to use
82// the network, it will not work. That will potentially cause a user-visible error.
chiachangwang0d5ae982022-05-17 05:16:16 +000083constexpr int32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE = 30000;
84constexpr int32_t RULE_PRIORITY_DEFAULT_NETWORK = 31000;
Chiachang Wang2e9443f2022-01-14 22:55:36 +080085constexpr int32_t RULE_PRIORITY_UNREACHABLE = 32000;
Ken Chen69839af2021-01-05 22:48:32 +080086// clang-format on
87
Sreeram Ramachandranb1425cc2014-06-23 18:54:27 -070088class UidRanges;
89
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070090class RouteController {
91public:
Sreeram Ramachandran38b7af12014-05-22 14:21:49 -070092 // How the routing table number is determined for route modification requests.
93 enum TableType {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070094 INTERFACE, // Compute the table number based on the interface index.
Sreeram Ramachandran87475a12014-07-15 16:20:28 -070095 LOCAL_NETWORK, // A fixed table used for routes to directly-connected clients/peers.
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070096 LEGACY_NETWORK, // Use a fixed table that's used to override the default network.
97 LEGACY_SYSTEM, // A fixed table, only modifiable by system apps; overrides VPNs too.
Sreeram Ramachandran38b7af12014-05-22 14:21:49 -070098 };
99
Sreeram Ramachandrana4811802014-04-10 12:10:24 -0700100 static const int ROUTE_TABLE_OFFSET_FROM_INDEX = 1000;
Chiachang Wangf79e3562022-01-15 13:31:04 +0800101 // Offset for the table of virtual local network created from the physical interface.
102 static const int ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL = 1000000000;
Sreeram Ramachandrana4811802014-04-10 12:10:24 -0700103
Chiachang Wangf79e3562022-01-15 13:31:04 +0800104 static constexpr const char* INTERFACE_LOCAL_SUFFIX = "_local";
105 static constexpr const char* RT_TABLES_PATH = "/data/misc/net/rt_tables";
Lorenzo Colittid78843e2017-03-27 05:52:31 +0900106 static const char* const LOCAL_MANGLE_INPUT;
107
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900108 [[nodiscard]] static int Init(unsigned localNetId);
Sreeram Ramachandran8fe9c8e2014-04-16 12:08:05 -0700109
Rubin Xu6c00b612018-04-27 14:27:59 +0100110 // Returns an ifindex given the interface name, by looking up in sInterfaceToTable.
111 // This is currently only used by NetworkController::addInterfaceToNetwork
112 // and should probabaly be changed to passing the ifindex into RouteController instead.
113 // We do this instead of calling if_nametoindex because the same interface name can
114 // correspond to different interface indices over time. This way, even if the interface
115 // index has changed, we can still free any map entries indexed by the ifindex that was
116 // used to add them.
Luke Huang534980c2018-07-06 17:50:11 +0800117 static uint32_t getIfIndex(const char* interface) EXCLUDES(sInterfaceToTableLock);
Rubin Xu6c00b612018-04-27 14:27:59 +0100118
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900119 [[nodiscard]] static int addInterfaceToLocalNetwork(unsigned netId, const char* interface);
120 [[nodiscard]] static int removeInterfaceFromLocalNetwork(unsigned netId, const char* interface);
Sreeram Ramachandran6a773532014-07-11 09:10:20 -0700121
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900122 [[nodiscard]] static int addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
Ken Chen8738e1c2020-11-24 11:38:54 +0800123 Permission permission,
Chalard Jeane479f312022-12-12 18:27:49 +0900124 const UidRangeMap& uidRangeMap,
125 bool local);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900126 [[nodiscard]] static int removeInterfaceFromPhysicalNetwork(unsigned netId,
127 const char* interface,
Ken Chen8738e1c2020-11-24 11:38:54 +0800128 Permission permission,
Chalard Jeane479f312022-12-12 18:27:49 +0900129 const UidRangeMap& uidRangeMap,
130 bool local);
Sreeram Ramachandran9c0d3132014-04-10 20:35:04 -0700131
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900132 [[nodiscard]] static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
Ken Chen4ea88462021-05-23 14:56:43 +0800133 bool secure,
Chiachang Wang2e9443f2022-01-14 22:55:36 +0800134 const UidRangeMap& uidRangeMap,
135 bool excludeLocalRoutes);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900136 [[nodiscard]] static int removeInterfaceFromVirtualNetwork(unsigned netId,
137 const char* interface, bool secure,
Chiachang Wang2e9443f2022-01-14 22:55:36 +0800138 const UidRangeMap& uidRangeMap,
139 bool excludeLocalRoutes);
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700140
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900141 [[nodiscard]] static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
142 Permission oldPermission,
Chalard Jeane479f312022-12-12 18:27:49 +0900143 Permission newPermission, bool local);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700144
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900145 [[nodiscard]] static int addUsersToVirtualNetwork(unsigned netId, const char* interface,
Chiachang Wang2e9443f2022-01-14 22:55:36 +0800146 bool secure, const UidRangeMap& uidRangeMap,
147 bool excludeLocalRoutes);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900148 [[nodiscard]] static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
Ken Chen4ea88462021-05-23 14:56:43 +0800149 bool secure,
Chiachang Wang2e9443f2022-01-14 22:55:36 +0800150 const UidRangeMap& uidRangeMap,
151 bool excludeLocalRoutes);
Sreeram Ramachandran7619e1b2014-04-15 14:23:08 -0700152
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900153 [[nodiscard]] static int addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges);
154 [[nodiscard]] static int removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges);
Robin Leeb8087362016-03-30 18:43:08 +0100155
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900156 [[nodiscard]] static int addInterfaceToDefaultNetwork(const char* interface,
157 Permission permission);
158 [[nodiscard]] static int removeInterfaceFromDefaultNetwork(const char* interface,
159 Permission permission);
Sreeram Ramachandranb1425cc2014-06-23 18:54:27 -0700160
Sreeram Ramachandrande5d5df2014-07-26 18:43:25 -0700161 // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
Lorenzo Colitti4c95a122014-09-18 16:01:50 +0900162 // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900163 [[nodiscard]] static int addRoute(const char* interface, const char* destination,
Taras Antoshchuk0cceda22021-09-24 18:40:03 +0200164 const char* nexthop, TableType tableType, int mtu,
165 int priority);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900166 [[nodiscard]] static int removeRoute(const char* interface, const char* destination,
Taras Antoshchuk0cceda22021-09-24 18:40:03 +0200167 const char* nexthop, TableType tableType, int priority);
Tyler Wearfa94a272019-12-05 15:01:48 -0800168 [[nodiscard]] static int updateRoute(const char* interface, const char* destination,
169 const char* nexthop, TableType tableType, int mtu);
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700170
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900171 [[nodiscard]] static int enableTethering(const char* inputInterface,
172 const char* outputInterface);
173 [[nodiscard]] static int disableTethering(const char* inputInterface,
174 const char* outputInterface);
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700175
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900176 [[nodiscard]] static int addVirtualNetworkFallthrough(unsigned vpnNetId,
177 const char* physicalInterface,
178 Permission permission);
179 [[nodiscard]] static int removeVirtualNetworkFallthrough(unsigned vpnNetId,
180 const char* physicalInterface,
181 Permission permission);
Lorenzo Colittic1306ea2017-03-27 05:52:31 +0900182
Ken Chen8738e1c2020-11-24 11:38:54 +0800183 [[nodiscard]] static int addUsersToPhysicalNetwork(unsigned netId, const char* interface,
Chalard Jeane479f312022-12-12 18:27:49 +0900184 const UidRangeMap& uidRangeMap, bool local);
Ken Chen8738e1c2020-11-24 11:38:54 +0800185
186 [[nodiscard]] static int removeUsersFromPhysicalNetwork(unsigned netId, const char* interface,
Chalard Jeane479f312022-12-12 18:27:49 +0900187 const UidRangeMap& uidRangeMap,
188 bool local);
Ken Chen8738e1c2020-11-24 11:38:54 +0800189
Ken Chen4e8ef9b2021-03-17 01:57:19 +0800190 [[nodiscard]] static int addUsersToUnreachableNetwork(unsigned netId,
Ken Chen4ea88462021-05-23 14:56:43 +0800191 const UidRangeMap& uidRangeMap);
Ken Chen4e8ef9b2021-03-17 01:57:19 +0800192
193 [[nodiscard]] static int removeUsersFromUnreachableNetwork(unsigned netId,
Ken Chen4ea88462021-05-23 14:56:43 +0800194 const UidRangeMap& uidRangeMap);
Ken Chen4e8ef9b2021-03-17 01:57:19 +0800195
Lorenzo Colittic1306ea2017-03-27 05:52:31 +0900196 // For testing.
197 static int (*iptablesRestoreCommandFunction)(IptablesTarget, const std::string&,
198 const std::string&, std::string *);
Chiachang Wangf79e3562022-01-15 13:31:04 +0800199 static uint32_t (*ifNameToIndexFunction)(const char*);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900200
Chiachang Wangf79e3562022-01-15 13:31:04 +0800201 private:
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900202 friend class RouteControllerTest;
Luke Huang534980c2018-07-06 17:50:11 +0800203
chiachangwangd3f3d062022-10-31 10:50:18 +0000204 // An expandable array for fixed local prefix though it's only one element now.
205 static constexpr const char* V4_FIXED_LOCAL_PREFIXES[] = {
206 // The multicast range is 224.0.0.0/4 but only limit it to 224.0.0.0/24 since the IPv4
207 // definitions are not as precise as for IPv6, it is the only range that the standards
208 // (RFC 2365 and RFC 5771) specify is link-local and must not be forwarded.
209 "224.0.0.0/24" // Link-local multicast; non-internet routable
210 };
211
Luke Huang534980c2018-07-06 17:50:11 +0800212 static std::mutex sInterfaceToTableLock;
213 static std::map<std::string, uint32_t> sInterfaceToTable GUARDED_BY(sInterfaceToTableLock);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900214
215 static int configureDummyNetwork();
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900216 [[nodiscard]] static int flushRoutes(const char* interface) EXCLUDES(sInterfaceToTableLock);
Chiachang Wangf79e3562022-01-15 13:31:04 +0800217 [[nodiscard]] static int flushRoutes(const char* interface, bool local)
218 EXCLUDES(sInterfaceToTableLock);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900219 [[nodiscard]] static int flushRoutes(uint32_t table);
Chiachang Wangf79e3562022-01-15 13:31:04 +0800220 static uint32_t getRouteTableForInterfaceLocked(const char* interface, bool local)
Luke Huang534980c2018-07-06 17:50:11 +0800221 REQUIRES(sInterfaceToTableLock);
Chiachang Wangf79e3562022-01-15 13:31:04 +0800222 static uint32_t getRouteTableForInterface(const char* interface, bool local)
223 EXCLUDES(sInterfaceToTableLock);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900224 static int modifyDefaultNetwork(uint16_t action, const char* interface, Permission permission);
Ken Chen8738e1c2020-11-24 11:38:54 +0800225 static int modifyPhysicalNetwork(unsigned netId, const char* interface,
Ken Chen4ea88462021-05-23 14:56:43 +0800226 const UidRangeMap& uidRangeMap, Permission permission,
Chalard Jeane479f312022-12-12 18:27:49 +0900227 bool add, bool modifyNonUidBasedRules, bool local);
Ken Chen4ea88462021-05-23 14:56:43 +0800228 static int modifyUnreachableNetwork(unsigned netId, const UidRangeMap& uidRangeMap, bool add);
Tyler Wearfa94a272019-12-05 15:01:48 -0800229 static int modifyRoute(uint16_t action, uint16_t flags, const char* interface,
230 const char* destination, const char* nexthop, TableType tableType,
Chiachangf9e81ac2022-05-12 05:21:20 +0000231 int mtu, int priority, bool isLocal);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900232 static int modifyTetheredNetwork(uint16_t action, const char* inputInterface,
233 const char* outputInterface);
234 static int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
235 const char* physicalInterface, Permission permission);
236 static int modifyVirtualNetwork(unsigned netId, const char* interface,
Ken Chen4ea88462021-05-23 14:56:43 +0800237 const UidRangeMap& uidRangeMap, bool secure, bool add,
Chiachang Wang2e9443f2022-01-14 22:55:36 +0800238 bool modifyNonUidBasedRules, bool excludeLocalRoutes);
Luke Huang534980c2018-07-06 17:50:11 +0800239 static void updateTableNamesFile() EXCLUDES(sInterfaceToTableLock);
Chiachang Wang8b9cdd22022-01-27 10:43:28 +0800240 static int modifyVpnLocalExclusionRule(bool add, const char* physicalInterface);
Chiachangf9e81ac2022-05-12 05:21:20 +0000241
chiachangwang0d5ae982022-05-17 05:16:16 +0000242 static int modifyUidLocalNetworkRule(const char* interface, uid_t uidStart, uid_t uidEnd,
243 bool add);
chiachangwang2efd0ce2022-06-15 02:42:44 +0000244 static bool isLocalRoute(TableType tableType, const char* destination, const char* nexthop);
245 static bool isWithinIpv4LocalPrefix(const char* addrstr);
chiachangwang5308c042022-08-25 06:55:19 +0000246 static int addFixedLocalRoutes(const char* interface);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700247};
248
Lorenzo Colitti60367db2017-02-13 16:31:45 +0900249// Public because they are called by by RouteControllerTest.cpp.
250// TODO: come up with a scheme of unit testing this code that does not rely on making all its
251// functions public.
Tyler Wearfa94a272019-12-05 15:01:48 -0800252[[nodiscard]] int modifyIpRoute(uint16_t action, uint16_t flags, uint32_t table,
253 const char* interface, const char* destination, const char* nexthop,
Taras Antoshchuk0cceda22021-09-24 18:40:03 +0200254 uint32_t mtu, uint32_t priority);
Lorenzo Colitti60367db2017-02-13 16:31:45 +0900255uint32_t getRulePriority(const nlmsghdr *nlh);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900256[[nodiscard]] int modifyIncomingPacketMark(unsigned netId, const char* interface,
257 Permission permission, bool add);
Lorenzo Colitti60367db2017-02-13 16:31:45 +0900258
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900259} // namespace android::net