blob: 38d2d6210a85a32d4810944e1f3e82ffcb06bdfc [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
Bernie Innocenti762dcf42019-06-14 19:52:49 +090019#include "NetdConstants.h" // IptablesTarget
Ken Chend9aa98a2021-05-23 14:56:43 +080020#include "Network.h" // UidRangeMap
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070021#include "Permission.h"
22
Luke Huang534980c2018-07-06 17:50:11 +080023#include <android-base/thread_annotations.h>
24
Lorenzo Colitti60367db2017-02-13 16:31:45 +090025#include <linux/netlink.h>
Luke Huangd1ee4622018-06-29 13:49:58 +080026#include <sys/types.h>
27#include <map>
Luke Huang534980c2018-07-06 17:50:11 +080028#include <mutex>
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -070029
Bernie Innocenti762dcf42019-06-14 19:52:49 +090030namespace android::net {
Lorenzo Colitti7035f222017-02-13 18:29:00 +090031
Ken Chen69839af2021-01-05 22:48:32 +080032// clang-format off
Ken Chen4e8ef9b2021-03-17 01:57:19 +080033const uint32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000;
34const uint32_t RULE_PRIORITY_VPN_OVERRIDE_OIF = 11000;
35const uint32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 12000;
36const uint32_t RULE_PRIORITY_SECURE_VPN = 13000;
37const uint32_t RULE_PRIORITY_PROHIBIT_NON_VPN = 14000;
Ken Chen8738e1c2020-11-24 11:38:54 +080038// Rules used when applications explicitly select a network that they have permission to use only
39// because they are in the list of UID ranges for that network.
40//
41// Sockets from these UIDs will not match RULE_PRIORITY_EXPLICIT_NETWORK rules because they will
42// not have the necessary permission bits in the fwmark. We cannot just give any socket on any of
43// these networks the permission bits, because if the UID that created the socket loses access to
44// the network, then the socket must not match any rule that selects that network.
Ken Chen4e8ef9b2021-03-17 01:57:19 +080045const uint32_t RULE_PRIORITY_UID_EXPLICIT_NETWORK = 15000;
46const uint32_t RULE_PRIORITY_EXPLICIT_NETWORK = 16000;
47const uint32_t RULE_PRIORITY_OUTPUT_INTERFACE = 17000;
48const uint32_t RULE_PRIORITY_LEGACY_SYSTEM = 18000;
49const uint32_t RULE_PRIORITY_LEGACY_NETWORK = 19000;
50const uint32_t RULE_PRIORITY_LOCAL_NETWORK = 20000;
51const uint32_t RULE_PRIORITY_TETHERING = 21000;
Ken Chen8738e1c2020-11-24 11:38:54 +080052// Implicit rules for sockets that connected on a given network because the network was the default
53// network for the UID.
Ken Chen4e8ef9b2021-03-17 01:57:19 +080054const uint32_t RULE_PRIORITY_UID_IMPLICIT_NETWORK = 22000;
55const uint32_t RULE_PRIORITY_IMPLICIT_NETWORK = 23000;
56const uint32_t RULE_PRIORITY_BYPASSABLE_VPN = 24000;
57// reserved for RULE_PRIORITY_UID_VPN_FALLTHROUGH = 25000;
58const uint32_t RULE_PRIORITY_VPN_FALLTHROUGH = 26000;
Ken Chen55db3802021-03-30 13:47:49 +080059const uint32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 27000;
Ken Chen4e8ef9b2021-03-17 01:57:19 +080060// Rule used when framework wants to disable default network from specified applications. There will
61// be a small interval the same uid range exists in both UID_DEFAULT_UNREACHABLE and
62// UID_DEFAULT_NETWORK when framework is switching user preferences.
63//
64// framework --> netd
65// step 1: set uid to unreachable network
66// step 2: remove uid from OEM-paid network list
Ken Chen55db3802021-03-30 13:47:49 +080067// or
68// step 1: add uid to OEM-paid network list
69// step 2: remove uid from unreachable network
Ken Chen4e8ef9b2021-03-17 01:57:19 +080070//
Ken Chen55db3802021-03-30 13:47:49 +080071// The priority is lower than UID_DEFAULT_NETWORK. Otherwise, the app will be told by
72// ConnectivityService that it has a network in step 1 of the second case. But if it tries to use
73// the network, it will not work. That will potentially cause a user-visible error.
74const uint32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE = 28000;
Ken Chen4e8ef9b2021-03-17 01:57:19 +080075const uint32_t RULE_PRIORITY_DEFAULT_NETWORK = 29000;
76const uint32_t RULE_PRIORITY_UNREACHABLE = 32000;
Ken Chen69839af2021-01-05 22:48:32 +080077// clang-format on
78
Sreeram Ramachandranb1425cc2014-06-23 18:54:27 -070079class UidRanges;
80
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -070081class RouteController {
82public:
Sreeram Ramachandran38b7af12014-05-22 14:21:49 -070083 // How the routing table number is determined for route modification requests.
84 enum TableType {
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070085 INTERFACE, // Compute the table number based on the interface index.
Sreeram Ramachandran87475a12014-07-15 16:20:28 -070086 LOCAL_NETWORK, // A fixed table used for routes to directly-connected clients/peers.
Sreeram Ramachandran5009d5e2014-07-03 12:20:48 -070087 LEGACY_NETWORK, // Use a fixed table that's used to override the default network.
88 LEGACY_SYSTEM, // A fixed table, only modifiable by system apps; overrides VPNs too.
Sreeram Ramachandran38b7af12014-05-22 14:21:49 -070089 };
90
Sreeram Ramachandrana4811802014-04-10 12:10:24 -070091 static const int ROUTE_TABLE_OFFSET_FROM_INDEX = 1000;
92
Lorenzo Colittid78843e2017-03-27 05:52:31 +090093 static const char* const LOCAL_MANGLE_INPUT;
94
Bernie Innocenti762dcf42019-06-14 19:52:49 +090095 [[nodiscard]] static int Init(unsigned localNetId);
Sreeram Ramachandran8fe9c8e2014-04-16 12:08:05 -070096
Rubin Xu6c00b612018-04-27 14:27:59 +010097 // Returns an ifindex given the interface name, by looking up in sInterfaceToTable.
98 // This is currently only used by NetworkController::addInterfaceToNetwork
99 // and should probabaly be changed to passing the ifindex into RouteController instead.
100 // We do this instead of calling if_nametoindex because the same interface name can
101 // correspond to different interface indices over time. This way, even if the interface
102 // index has changed, we can still free any map entries indexed by the ifindex that was
103 // used to add them.
Luke Huang534980c2018-07-06 17:50:11 +0800104 static uint32_t getIfIndex(const char* interface) EXCLUDES(sInterfaceToTableLock);
Rubin Xu6c00b612018-04-27 14:27:59 +0100105
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900106 [[nodiscard]] static int addInterfaceToLocalNetwork(unsigned netId, const char* interface);
107 [[nodiscard]] static int removeInterfaceFromLocalNetwork(unsigned netId, const char* interface);
Sreeram Ramachandran6a773532014-07-11 09:10:20 -0700108
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900109 [[nodiscard]] static int addInterfaceToPhysicalNetwork(unsigned netId, const char* interface,
Ken Chen8738e1c2020-11-24 11:38:54 +0800110 Permission permission,
Ken Chend9aa98a2021-05-23 14:56:43 +0800111 const UidRangeMap& uidRangeMap);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900112 [[nodiscard]] static int removeInterfaceFromPhysicalNetwork(unsigned netId,
113 const char* interface,
Ken Chen8738e1c2020-11-24 11:38:54 +0800114 Permission permission,
Ken Chend9aa98a2021-05-23 14:56:43 +0800115 const UidRangeMap& uidRangeMap);
Sreeram Ramachandran9c0d3132014-04-10 20:35:04 -0700116
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900117 [[nodiscard]] static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800118 bool secure,
119 const UidRangeMap& uidRangeMap);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900120 [[nodiscard]] static int removeInterfaceFromVirtualNetwork(unsigned netId,
121 const char* interface, bool secure,
Ken Chend9aa98a2021-05-23 14:56:43 +0800122 const UidRangeMap& uidRangeMap);
Sreeram Ramachandran4043f012014-06-23 12:41:37 -0700123
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900124 [[nodiscard]] static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
125 Permission oldPermission,
126 Permission newPermission);
Sreeram Ramachandranf4f6c8d2014-06-23 09:54:06 -0700127
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900128 [[nodiscard]] static int addUsersToVirtualNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800129 bool secure, const UidRangeMap& uidRangeMap);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900130 [[nodiscard]] static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800131 bool secure,
132 const UidRangeMap& uidRangeMap);
Sreeram Ramachandran7619e1b2014-04-15 14:23:08 -0700133
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900134 [[nodiscard]] static int addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges);
135 [[nodiscard]] static int removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges);
Robin Leeb8087362016-03-30 18:43:08 +0100136
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900137 [[nodiscard]] static int addInterfaceToDefaultNetwork(const char* interface,
138 Permission permission);
139 [[nodiscard]] static int removeInterfaceFromDefaultNetwork(const char* interface,
140 Permission permission);
Sreeram Ramachandranb1425cc2014-06-23 18:54:27 -0700141
Sreeram Ramachandrande5d5df2014-07-26 18:43:25 -0700142 // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
Lorenzo Colitti4c95a122014-09-18 16:01:50 +0900143 // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900144 [[nodiscard]] static int addRoute(const char* interface, const char* destination,
Tyler Wearfa94a272019-12-05 15:01:48 -0800145 const char* nexthop, TableType tableType, int mtu);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900146 [[nodiscard]] static int removeRoute(const char* interface, const char* destination,
147 const char* nexthop, TableType tableType);
Tyler Wearfa94a272019-12-05 15:01:48 -0800148 [[nodiscard]] static int updateRoute(const char* interface, const char* destination,
149 const char* nexthop, TableType tableType, int mtu);
Sreeram Ramachandran87475a12014-07-15 16:20:28 -0700150
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900151 [[nodiscard]] static int enableTethering(const char* inputInterface,
152 const char* outputInterface);
153 [[nodiscard]] static int disableTethering(const char* inputInterface,
154 const char* outputInterface);
Sreeram Ramachandran48e19b02014-07-22 22:23:20 -0700155
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900156 [[nodiscard]] static int addVirtualNetworkFallthrough(unsigned vpnNetId,
157 const char* physicalInterface,
158 Permission permission);
159 [[nodiscard]] static int removeVirtualNetworkFallthrough(unsigned vpnNetId,
160 const char* physicalInterface,
161 Permission permission);
Lorenzo Colittic1306ea2017-03-27 05:52:31 +0900162
Ken Chen8738e1c2020-11-24 11:38:54 +0800163 [[nodiscard]] static int addUsersToPhysicalNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800164 const UidRangeMap& uidRangeMap);
Ken Chen8738e1c2020-11-24 11:38:54 +0800165
166 [[nodiscard]] static int removeUsersFromPhysicalNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800167 const UidRangeMap& uidRangeMap);
Ken Chen8738e1c2020-11-24 11:38:54 +0800168
Ken Chen4e8ef9b2021-03-17 01:57:19 +0800169 [[nodiscard]] static int addUsersToUnreachableNetwork(unsigned netId,
Ken Chend9aa98a2021-05-23 14:56:43 +0800170 const UidRangeMap& uidRangeMap);
Ken Chen4e8ef9b2021-03-17 01:57:19 +0800171
172 [[nodiscard]] static int removeUsersFromUnreachableNetwork(unsigned netId,
Ken Chend9aa98a2021-05-23 14:56:43 +0800173 const UidRangeMap& uidRangeMap);
Ken Chen4e8ef9b2021-03-17 01:57:19 +0800174
Lorenzo Colittic1306ea2017-03-27 05:52:31 +0900175 // For testing.
176 static int (*iptablesRestoreCommandFunction)(IptablesTarget, const std::string&,
177 const std::string&, std::string *);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900178
179private:
180 friend class RouteControllerTest;
Luke Huang534980c2018-07-06 17:50:11 +0800181
182 static std::mutex sInterfaceToTableLock;
183 static std::map<std::string, uint32_t> sInterfaceToTable GUARDED_BY(sInterfaceToTableLock);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900184
185 static int configureDummyNetwork();
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900186 [[nodiscard]] static int flushRoutes(const char* interface) EXCLUDES(sInterfaceToTableLock);
187 [[nodiscard]] static int flushRoutes(uint32_t table);
188 static uint32_t getRouteTableForInterfaceLocked(const char* interface)
Luke Huang534980c2018-07-06 17:50:11 +0800189 REQUIRES(sInterfaceToTableLock);
190 static uint32_t getRouteTableForInterface(const char *interface) EXCLUDES(sInterfaceToTableLock);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900191 static int modifyDefaultNetwork(uint16_t action, const char* interface, Permission permission);
Ken Chen8738e1c2020-11-24 11:38:54 +0800192 static int modifyPhysicalNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800193 const UidRangeMap& uidRangeMap, Permission permission,
194 bool add, bool modifyNonUidBasedRules);
195 static int modifyUnreachableNetwork(unsigned netId, const UidRangeMap& uidRangeMap, bool add);
Tyler Wearfa94a272019-12-05 15:01:48 -0800196 static int modifyRoute(uint16_t action, uint16_t flags, const char* interface,
197 const char* destination, const char* nexthop, TableType tableType,
198 int mtu);
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900199 static int modifyTetheredNetwork(uint16_t action, const char* inputInterface,
200 const char* outputInterface);
201 static int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
202 const char* physicalInterface, Permission permission);
203 static int modifyVirtualNetwork(unsigned netId, const char* interface,
Ken Chend9aa98a2021-05-23 14:56:43 +0800204 const UidRangeMap& uidRangeMap, bool secure, bool add,
Lorenzo Colitti02cb80a2017-10-30 19:21:06 +0900205 bool modifyNonUidBasedRules);
Luke Huang534980c2018-07-06 17:50:11 +0800206 static void updateTableNamesFile() EXCLUDES(sInterfaceToTableLock);
Sreeram Ramachandran5c181bf2014-04-07 14:10:04 -0700207};
208
Lorenzo Colitti60367db2017-02-13 16:31:45 +0900209// Public because they are called by by RouteControllerTest.cpp.
210// TODO: come up with a scheme of unit testing this code that does not rely on making all its
211// functions public.
Tyler Wearfa94a272019-12-05 15:01:48 -0800212[[nodiscard]] int modifyIpRoute(uint16_t action, uint16_t flags, uint32_t table,
213 const char* interface, const char* destination, const char* nexthop,
214 uint32_t mtu);
Lorenzo Colitti60367db2017-02-13 16:31:45 +0900215uint32_t getRulePriority(const nlmsghdr *nlh);
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900216[[nodiscard]] int modifyIncomingPacketMark(unsigned netId, const char* interface,
217 Permission permission, bool add);
Lorenzo Colitti60367db2017-02-13 16:31:45 +0900218
Bernie Innocenti762dcf42019-06-14 19:52:49 +0900219} // namespace android::net