xref: /aosp_15_r20/system/netd/server/NetworkController.h (revision 8542734a0dd1db395a4d42aae09c37f3c3c3e7a1)
1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker  *
4*8542734aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker  *
8*8542734aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker  *
10*8542734aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker  * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker  */
16*8542734aSAndroid Build Coastguard Worker 
17*8542734aSAndroid Build Coastguard Worker #pragma once
18*8542734aSAndroid Build Coastguard Worker 
19*8542734aSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h>
20*8542734aSAndroid Build Coastguard Worker #include <android/multinetwork.h>
21*8542734aSAndroid Build Coastguard Worker 
22*8542734aSAndroid Build Coastguard Worker #include "NetdConstants.h"
23*8542734aSAndroid Build Coastguard Worker #include "Permission.h"
24*8542734aSAndroid Build Coastguard Worker #include "PhysicalNetwork.h"
25*8542734aSAndroid Build Coastguard Worker #include "UnreachableNetwork.h"
26*8542734aSAndroid Build Coastguard Worker #include "android/net/INetd.h"
27*8542734aSAndroid Build Coastguard Worker #include "netdutils/DumpWriter.h"
28*8542734aSAndroid Build Coastguard Worker 
29*8542734aSAndroid Build Coastguard Worker #include <sys/types.h>
30*8542734aSAndroid Build Coastguard Worker #include <list>
31*8542734aSAndroid Build Coastguard Worker #include <map>
32*8542734aSAndroid Build Coastguard Worker #include <set>
33*8542734aSAndroid Build Coastguard Worker #include <shared_mutex>
34*8542734aSAndroid Build Coastguard Worker #include <unordered_map>
35*8542734aSAndroid Build Coastguard Worker #include <unordered_set>
36*8542734aSAndroid Build Coastguard Worker #include <vector>
37*8542734aSAndroid Build Coastguard Worker 
38*8542734aSAndroid Build Coastguard Worker struct android_net_context;
39*8542734aSAndroid Build Coastguard Worker 
40*8542734aSAndroid Build Coastguard Worker namespace android::net {
41*8542734aSAndroid Build Coastguard Worker 
42*8542734aSAndroid Build Coastguard Worker typedef std::shared_lock<std::shared_mutex> ScopedRLock;
43*8542734aSAndroid Build Coastguard Worker typedef std::lock_guard<std::shared_mutex> ScopedWLock;
44*8542734aSAndroid Build Coastguard Worker 
45*8542734aSAndroid Build Coastguard Worker constexpr uint32_t kHandleMagic = 0xcafed00d;
46*8542734aSAndroid Build Coastguard Worker 
47*8542734aSAndroid Build Coastguard Worker // Utility to convert from netId to net_handle_t. Doing this here as opposed to exporting
48*8542734aSAndroid Build Coastguard Worker // from net.c as it may have NDK implications. Besides no conversion available in net.c for
49*8542734aSAndroid Build Coastguard Worker // obtaining handle given netId.
50*8542734aSAndroid Build Coastguard Worker // TODO: Use getnetidfromhandle() in net.c.
netHandleToNetId(net_handle_t fromNetHandle)51*8542734aSAndroid Build Coastguard Worker static inline unsigned netHandleToNetId(net_handle_t fromNetHandle) {
52*8542734aSAndroid Build Coastguard Worker     const uint32_t k32BitMask = 0xffffffff;
53*8542734aSAndroid Build Coastguard Worker     // This value MUST be kept in sync with the corresponding value in
54*8542734aSAndroid Build Coastguard Worker     // the android.net.Network#getNetworkHandle() implementation.
55*8542734aSAndroid Build Coastguard Worker 
56*8542734aSAndroid Build Coastguard Worker     // Check for minimum acceptable version of the API in the low bits.
57*8542734aSAndroid Build Coastguard Worker     if (fromNetHandle != NETWORK_UNSPECIFIED &&
58*8542734aSAndroid Build Coastguard Worker         (fromNetHandle & k32BitMask) != kHandleMagic) {
59*8542734aSAndroid Build Coastguard Worker         return 0;
60*8542734aSAndroid Build Coastguard Worker     }
61*8542734aSAndroid Build Coastguard Worker 
62*8542734aSAndroid Build Coastguard Worker     return ((fromNetHandle >> (CHAR_BIT * sizeof(k32BitMask))) & k32BitMask);
63*8542734aSAndroid Build Coastguard Worker }
64*8542734aSAndroid Build Coastguard Worker 
65*8542734aSAndroid Build Coastguard Worker // Utility to convert from nethandle to netid, keep in sync with getNetworkHandle
66*8542734aSAndroid Build Coastguard Worker // in Network.java.
netIdToNetHandle(unsigned fromNetId)67*8542734aSAndroid Build Coastguard Worker static inline net_handle_t netIdToNetHandle(unsigned fromNetId) {
68*8542734aSAndroid Build Coastguard Worker     if (!fromNetId) {
69*8542734aSAndroid Build Coastguard Worker         return NETWORK_UNSPECIFIED;
70*8542734aSAndroid Build Coastguard Worker     }
71*8542734aSAndroid Build Coastguard Worker     return (((net_handle_t)fromNetId << 32) | kHandleMagic);
72*8542734aSAndroid Build Coastguard Worker }
73*8542734aSAndroid Build Coastguard Worker 
74*8542734aSAndroid Build Coastguard Worker class Network;
75*8542734aSAndroid Build Coastguard Worker class UidRanges;
76*8542734aSAndroid Build Coastguard Worker class VirtualNetwork;
77*8542734aSAndroid Build Coastguard Worker 
78*8542734aSAndroid Build Coastguard Worker /*
79*8542734aSAndroid Build Coastguard Worker  * Keeps track of default, per-pid, and per-uid-range network selection, as
80*8542734aSAndroid Build Coastguard Worker  * well as the mark associated with each network. Networks are identified
81*8542734aSAndroid Build Coastguard Worker  * by netid. In all set* commands netid == 0 means "unspecified" and is
82*8542734aSAndroid Build Coastguard Worker  * equivalent to clearing the mapping.
83*8542734aSAndroid Build Coastguard Worker  */
84*8542734aSAndroid Build Coastguard Worker class NetworkController {
85*8542734aSAndroid Build Coastguard Worker public:
86*8542734aSAndroid Build Coastguard Worker     // NetIds 53..98 are reserved for future use.
87*8542734aSAndroid Build Coastguard Worker     static constexpr int MIN_OEM_ID = 1;
88*8542734aSAndroid Build Coastguard Worker     static constexpr int MAX_OEM_ID = 50;
89*8542734aSAndroid Build Coastguard Worker     static constexpr int LOCAL_NET_ID = INetd::LOCAL_NET_ID;
90*8542734aSAndroid Build Coastguard Worker     static constexpr int DUMMY_NET_ID = INetd::DUMMY_NET_ID;
91*8542734aSAndroid Build Coastguard Worker     static constexpr int UNREACHABLE_NET_ID = INetd::UNREACHABLE_NET_ID;
92*8542734aSAndroid Build Coastguard Worker 
93*8542734aSAndroid Build Coastguard Worker     // Route mode for modify route
94*8542734aSAndroid Build Coastguard Worker     enum RouteOperation { ROUTE_ADD, ROUTE_UPDATE, ROUTE_REMOVE };
95*8542734aSAndroid Build Coastguard Worker 
96*8542734aSAndroid Build Coastguard Worker     NetworkController();
97*8542734aSAndroid Build Coastguard Worker 
98*8542734aSAndroid Build Coastguard Worker     unsigned getDefaultNetwork() const;
99*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int setDefaultNetwork(unsigned netId);
100*8542734aSAndroid Build Coastguard Worker 
101*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForUser(uid_t uid) const;
102*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForConnect(uid_t uid) const;
103*8542734aSAndroid Build Coastguard Worker     void getNetworkContext(unsigned netId, uid_t uid, struct android_net_context* netcontext) const;
104*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForInterface(const char* interface) const;
105*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForInterface(const int ifIndex) const;
106*8542734aSAndroid Build Coastguard Worker     bool isVirtualNetwork(unsigned netId) const;
107*8542734aSAndroid Build Coastguard Worker 
108*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int createPhysicalNetwork(unsigned netId, Permission permission, bool local);
109*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int createPhysicalOemNetwork(Permission permission, unsigned* netId);
110*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int createVirtualNetwork(unsigned netId, bool secure, NativeVpnType vpnType,
111*8542734aSAndroid Build Coastguard Worker                                            bool excludeLocalRoutes);
112*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int destroyNetwork(unsigned netId);
113*8542734aSAndroid Build Coastguard Worker 
114*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int addInterfaceToNetwork(unsigned netId, const char* interface);
115*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int removeInterfaceFromNetwork(unsigned netId, const char* interface);
116*8542734aSAndroid Build Coastguard Worker 
117*8542734aSAndroid Build Coastguard Worker     Permission getPermissionForUser(uid_t uid) const;
118*8542734aSAndroid Build Coastguard Worker     void setPermissionForUsers(Permission permission, const std::vector<uid_t>& uids);
119*8542734aSAndroid Build Coastguard Worker     int checkUserNetworkAccess(uid_t uid, unsigned netId) const;
120*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int setPermissionForNetworks(Permission permission,
121*8542734aSAndroid Build Coastguard Worker                                                const std::vector<unsigned>& netIds);
122*8542734aSAndroid Build Coastguard Worker 
123*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges,
124*8542734aSAndroid Build Coastguard Worker                                         int32_t subPriority);
125*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges,
126*8542734aSAndroid Build Coastguard Worker                                              int32_t subPriority);
127*8542734aSAndroid Build Coastguard Worker 
128*8542734aSAndroid Build Coastguard Worker     // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
129*8542734aSAndroid Build Coastguard Worker     // route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
130*8542734aSAndroid Build Coastguard Worker     //
131*8542734aSAndroid Build Coastguard Worker     // Routes are added to tables determined by the interface, so only |interface| is actually used.
132*8542734aSAndroid Build Coastguard Worker     // |netId| is given only to sanity check that the interface has the correct netId.
133*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int addRoute(unsigned netId, const char* interface, const char* destination,
134*8542734aSAndroid Build Coastguard Worker                                const char* nexthop, bool legacy, uid_t uid, int mtu);
135*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int updateRoute(unsigned netId, const char* interface, const char* destination,
136*8542734aSAndroid Build Coastguard Worker                                   const char* nexthop, bool legacy, uid_t uid, int mtu);
137*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int removeRoute(unsigned netId, const char* interface, const char* destination,
138*8542734aSAndroid Build Coastguard Worker                                   const char* nexthop, bool legacy, uid_t uid);
139*8542734aSAndroid Build Coastguard Worker 
140*8542734aSAndroid Build Coastguard Worker     // Notes that the specified address has appeared on the specified interface.
141*8542734aSAndroid Build Coastguard Worker     void addInterfaceAddress(unsigned ifIndex, const char* address);
142*8542734aSAndroid Build Coastguard Worker     // Notes that the specified address has been removed from the specified interface.
143*8542734aSAndroid Build Coastguard Worker     // Returns true if we should destroy sockets on this address.
144*8542734aSAndroid Build Coastguard Worker     bool removeInterfaceAddress(unsigned ifIndex, const char* address);
145*8542734aSAndroid Build Coastguard Worker 
146*8542734aSAndroid Build Coastguard Worker     bool canProtect(uid_t uid, unsigned netId) const;
147*8542734aSAndroid Build Coastguard Worker     int allowProtect(uid_t uid, unsigned netId);
148*8542734aSAndroid Build Coastguard Worker     int denyProtect(uid_t uid, unsigned netId);
149*8542734aSAndroid Build Coastguard Worker 
150*8542734aSAndroid Build Coastguard Worker     void dump(netdutils::DumpWriter& dw);
151*8542734aSAndroid Build Coastguard Worker     int setNetworkAllowlist(const std::vector<netd::aidl::NativeUidRangeConfig>& rangeConfigs);
152*8542734aSAndroid Build Coastguard Worker     bool isUidAllowed(unsigned netId, uid_t uid) const;
153*8542734aSAndroid Build Coastguard Worker 
154*8542734aSAndroid Build Coastguard Worker   private:
155*8542734aSAndroid Build Coastguard Worker     bool isValidNetworkLocked(unsigned netId) const;
156*8542734aSAndroid Build Coastguard Worker     Network* getNetworkLocked(unsigned netId) const;
157*8542734aSAndroid Build Coastguard Worker 
158*8542734aSAndroid Build Coastguard Worker     // Sets |*netId| to an appropriate NetId to use for DNS for the given user. Call with |*netId|
159*8542734aSAndroid Build Coastguard Worker     // set to a non-NETID_UNSET value if the user already has indicated a preference. Returns the
160*8542734aSAndroid Build Coastguard Worker     // fwmark value to set on the socket when performing the DNS request.
161*8542734aSAndroid Build Coastguard Worker     uint32_t getNetworkForDnsLocked(unsigned* netId, uid_t uid) const;
162*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForConnectLocked(uid_t uid) const;
163*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForInterfaceLocked(const char* interface) const;
164*8542734aSAndroid Build Coastguard Worker     unsigned getNetworkForInterfaceLocked(const int ifIndex) const;
165*8542734aSAndroid Build Coastguard Worker     bool isProtectableLocked(uid_t uid, unsigned netId) const;
166*8542734aSAndroid Build Coastguard Worker     bool canProtectLocked(uid_t uid, unsigned netId) const;
167*8542734aSAndroid Build Coastguard Worker     bool isVirtualNetworkLocked(unsigned netId) const;
168*8542734aSAndroid Build Coastguard Worker     VirtualNetwork* getVirtualNetworkForUserLocked(uid_t uid) const;
169*8542734aSAndroid Build Coastguard Worker     Network* getPhysicalOrUnreachableNetworkForUserLocked(uid_t uid) const;
170*8542734aSAndroid Build Coastguard Worker     Permission getPermissionForUserLocked(uid_t uid) const;
171*8542734aSAndroid Build Coastguard Worker     int checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const;
172*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int createPhysicalNetworkLocked(unsigned netId, Permission permission,
173*8542734aSAndroid Build Coastguard Worker                                                   bool local);
174*8542734aSAndroid Build Coastguard Worker 
175*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int modifyRoute(unsigned netId, const char* interface, const char* destination,
176*8542734aSAndroid Build Coastguard Worker                                   const char* nexthop, RouteOperation op, bool legacy, uid_t uid,
177*8542734aSAndroid Build Coastguard Worker                                   int mtu);
178*8542734aSAndroid Build Coastguard Worker     [[nodiscard]] int modifyFallthroughLocked(unsigned vpnNetId, bool add);
179*8542734aSAndroid Build Coastguard Worker     void updateTcpSocketMonitorPolling();
180*8542734aSAndroid Build Coastguard Worker     void clearAllowedUidsForAllNetworksLocked();
181*8542734aSAndroid Build Coastguard Worker 
182*8542734aSAndroid Build Coastguard Worker     class DelegateImpl;
183*8542734aSAndroid Build Coastguard Worker     DelegateImpl* const mDelegateImpl;
184*8542734aSAndroid Build Coastguard Worker 
185*8542734aSAndroid Build Coastguard Worker     // mRWLock guards all accesses to mDefaultNetId, mNetworks, mUsers, mProtectableUsers,
186*8542734aSAndroid Build Coastguard Worker     // mIfindexToLastNetId and mAddressToIfindices.
187*8542734aSAndroid Build Coastguard Worker     mutable std::shared_mutex mRWLock;
188*8542734aSAndroid Build Coastguard Worker     unsigned mDefaultNetId;
189*8542734aSAndroid Build Coastguard Worker     std::map<unsigned, Network*> mNetworks;  // Map keys are NetIds.
190*8542734aSAndroid Build Coastguard Worker     std::map<uid_t, Permission> mUsers;
191*8542734aSAndroid Build Coastguard Worker     // Set of <UID, netId> pairs that specify which UIDs can protect sockets and bypass
192*8542734aSAndroid Build Coastguard Worker     // VPNs. For each pair:
193*8542734aSAndroid Build Coastguard Worker     //
194*8542734aSAndroid Build Coastguard Worker     // - If the netId is NETID_UNSET, then the UID can call protectFromVpn and can
195*8542734aSAndroid Build Coastguard Worker     //   bypass VPNs by explicitly selecting any network.
196*8542734aSAndroid Build Coastguard Worker     // - Otherwise, the UID can bypass VPNs only by explicitly selecting the specified
197*8542734aSAndroid Build Coastguard Worker     //   network, and cannot call protectFromVpn on its sockets.
198*8542734aSAndroid Build Coastguard Worker     std::set<std::pair<uid_t, unsigned>> mProtectableUsers;
199*8542734aSAndroid Build Coastguard Worker     // Map interface (ifIndex) to its current NetId, or the last NetId if the interface was removed
200*8542734aSAndroid Build Coastguard Worker     // from the network and not added to another network. This state facilitates the interface to
201*8542734aSAndroid Build Coastguard Worker     // NetId lookup during RTM_DELADDR (NetworkController::removeInterfaceAddress), when the
202*8542734aSAndroid Build Coastguard Worker     // interface in question might already have been removed from the network.
203*8542734aSAndroid Build Coastguard Worker     // An interface is added to this map when it is added to a network and removed from this map
204*8542734aSAndroid Build Coastguard Worker     // when its network is destroyed.
205*8542734aSAndroid Build Coastguard Worker     std::unordered_map<unsigned, unsigned> mIfindexToLastNetId;
206*8542734aSAndroid Build Coastguard Worker     // Map IP address to the list of active interfaces (ifIndex) that have that address.
207*8542734aSAndroid Build Coastguard Worker     // Also contains IP addresses configured on interfaces that have not been added to any network.
208*8542734aSAndroid Build Coastguard Worker     // TODO: Does not track IP addresses present when netd is started or restarts after a crash.
209*8542734aSAndroid Build Coastguard Worker     // This is not a problem for its intended use (tracking IP addresses on VPN interfaces), but
210*8542734aSAndroid Build Coastguard Worker     // we should fix it.
211*8542734aSAndroid Build Coastguard Worker     std::unordered_map<std::string, std::unordered_set<unsigned>> mAddressToIfindices;
212*8542734aSAndroid Build Coastguard Worker 
213*8542734aSAndroid Build Coastguard Worker };
214*8542734aSAndroid Build Coastguard Worker 
215*8542734aSAndroid Build Coastguard Worker }  // namespace android::net
216