blob: c921ff2df003f73c9e164f2f4baa0445eccfe6e3 [file] [log] [blame]
Wayne Ma4d692332022-01-19 16:04:04 +08001/*
Wayne Maa9716ff2022-01-12 10:37:04 +08002 * Copyright (C) 2022 The Android Open Source Project
Wayne Ma4d692332022-01-19 16:04:04 +08003 *
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
Wayne Maa9716ff2022-01-12 10:37:04 +080017#pragma once
Wayne Ma4d692332022-01-19 16:04:04 +080018
Wayne Maa9716ff2022-01-12 10:37:04 +080019#include <set>
20#include <Common.h>
Wayne Ma4d692332022-01-19 16:04:04 +080021
Wayne Ma4d692332022-01-19 16:04:04 +080022#include "android-base/thread_annotations.h"
Wayne Ma4d692332022-01-19 16:04:04 +080023#include "bpf/BpfMap.h"
24#include "bpf_shared.h"
25#include "netdutils/DumpWriter.h"
26#include "netdutils/NetlinkListener.h"
27#include "netdutils/StatusOr.h"
Wayne Ma4d692332022-01-19 16:04:04 +080028
29namespace android {
30namespace net {
31
Wayne Maa9716ff2022-01-12 10:37:04 +080032using netdutils::StatusOr;
33
Wayne Ma4d692332022-01-19 16:04:04 +080034class TrafficController {
Patrick Rohr2b1b2c72022-02-01 15:57:48 +010035 public:
36 static constexpr char DUMP_KEYWORD[] = "trafficcontroller";
37
Wayne Ma4d692332022-01-19 16:04:04 +080038 /*
39 * Initialize the whole controller
40 */
41 netdutils::Status start();
Wayne Ma4d692332022-01-19 16:04:04 +080042
Wayne Ma4d692332022-01-19 16:04:04 +080043 /*
44 * Swap the stats map config from current active stats map to the idle one.
45 */
46 netdutils::Status swapActiveStatsMap() EXCLUDES(mMutex);
47
48 /*
49 * Add the interface name and index pair into the eBPF map.
50 */
51 int addInterface(const char* name, uint32_t ifaceIndex);
52
53 int changeUidOwnerRule(ChildChain chain, const uid_t uid, FirewallRule rule, FirewallType type);
54
55 int removeUidOwnerRule(const uid_t uid);
56
57 int replaceUidOwnerMap(const std::string& name, bool isAllowlist,
58 const std::vector<int32_t>& uids);
59
60 enum IptOp { IptOpInsert, IptOpDelete };
61
62 netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
63 FirewallType type) EXCLUDES(mMutex);
64
Ken Chene6d511f2022-01-25 11:10:42 +080065 void dump(int fd, bool verbose) EXCLUDES(mMutex);
Wayne Ma4d692332022-01-19 16:04:04 +080066
67 netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
68 EXCLUDES(mMutex);
69
70 netdutils::Status addUidInterfaceRules(const int ifIndex, const std::vector<int32_t>& uids)
71 EXCLUDES(mMutex);
72 netdutils::Status removeUidInterfaceRules(const std::vector<int32_t>& uids) EXCLUDES(mMutex);
73
Motomu Utsumi8b42e6d2022-05-19 06:23:40 +000074 netdutils::Status updateUidLockdownRule(const uid_t uid, const bool add) EXCLUDES(mMutex);
75
Wayne Maa9716ff2022-01-12 10:37:04 +080076 netdutils::Status updateUidOwnerMap(const uint32_t uid,
Wayne Ma4d692332022-01-19 16:04:04 +080077 UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex);
Wayne Ma4d692332022-01-19 16:04:04 +080078
79 int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
80
81 static netdutils::StatusOr<std::unique_ptr<netdutils::NetlinkListenerInterface>>
82 makeSkDestroyListener();
83
84 void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
85
86 FirewallType getFirewallType(ChildChain);
87
88 static const char* LOCAL_DOZABLE;
89 static const char* LOCAL_STANDBY;
90 static const char* LOCAL_POWERSAVE;
91 static const char* LOCAL_RESTRICTED;
Robert Horvathd945bf02022-01-27 19:55:16 +010092 static const char* LOCAL_LOW_POWER_STANDBY;
Motomu Utsumid9801492022-06-01 13:57:27 +000093 static const char* LOCAL_OEM_DENY_1;
94 static const char* LOCAL_OEM_DENY_2;
Motomu Utsumi1d9054b2022-06-06 07:44:05 +000095 static const char* LOCAL_OEM_DENY_3;
Wayne Ma4d692332022-01-19 16:04:04 +080096
97 private:
98 /*
99 * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
100 * DO NOT hold any locks when modifying this map, otherwise when the untag
101 * operation is waiting for a lock hold by other process and there are more
102 * sockets being closed than can fit in the socket buffer of the netlink socket
103 * that receives them, then the kernel will drop some of these sockets and we
104 * won't delete their tags.
105 * Map Key: uint64_t socket cookie
106 * Map Value: UidTagValue, contains a uint32 uid and a uint32 tag.
107 */
108 bpf::BpfMap<uint64_t, UidTagValue> mCookieTagMap GUARDED_BY(mMutex);
109
110 /*
111 * mUidCounterSetMap: Store the counterSet of a specific uid.
112 * Map Key: uint32 uid.
113 * Map Value: uint32 counterSet specifies if the traffic is a background
114 * or foreground traffic.
115 */
116 bpf::BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
117
118 /*
119 * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
120 * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
121 * API to return persistent stats for a specific uid since device boot.
122 */
123 bpf::BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
124
125 /*
126 * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
127 * combination of uid, tag, iface and counterSet. These two maps contain
128 * both tagged and untagged traffic.
129 * Map Key: StatsKey contains the uid, tag, counterSet and ifaceIndex
130 * information.
131 * Map Value: Stats, contains packet count and byte count of each
132 * transport protocol on egress and ingress direction.
133 */
134 bpf::BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
135
136 bpf::BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
137
138 /*
139 * mIfaceIndexNameMap: Store the index name pair of each interface show up
140 * on the device since boot. The interface index is used by the eBPF program
141 * to correctly match the iface name when receiving a packet.
142 */
143 bpf::BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
144
145 /*
146 * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
147 * filter.
148 */
149 bpf::BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
150
151 /*
152 * mConfigurationMap: Store the current network policy about uid filtering
153 * and the current stats map in use. There are two configuration entries in
154 * the map right now:
155 * - Entry with UID_RULES_CONFIGURATION_KEY:
156 * Store the configuration for the current uid rules. It indicates the device
Motomu Utsumid9801492022-06-01 13:57:27 +0000157 * is in doze/powersave/standby/restricted/low power standby/oem deny mode.
Wayne Ma4d692332022-01-19 16:04:04 +0800158 * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
159 * Stores the current live stats map that kernel program is writing to.
160 * Userspace can do scraping and cleaning job on the other one depending on the
161 * current configs.
162 */
Lorenzo Colitti60cbed32022-03-03 17:49:01 +0900163 bpf::BpfMap<uint32_t, uint32_t> mConfigurationMap GUARDED_BY(mMutex);
Wayne Ma4d692332022-01-19 16:04:04 +0800164
165 /*
166 * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
167 */
168 bpf::BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
169
170 /*
171 * mUidOwnerMap: Store uids that are used for INTERNET permission check.
172 */
173 bpf::BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
174
175 std::unique_ptr<netdutils::NetlinkListenerInterface> mSkDestroyListener;
176
177 netdutils::Status removeRule(uint32_t uid, UidOwnerMatchType match) REQUIRES(mMutex);
178
179 netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0)
180 REQUIRES(mMutex);
181
Wayne Ma4d692332022-01-19 16:04:04 +0800182 std::mutex mMutex;
183
Patrick Rohr2b1b2c72022-02-01 15:57:48 +0100184 netdutils::Status initMaps() EXCLUDES(mMutex);
185
Wayne Ma4d692332022-01-19 16:04:04 +0800186 // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
187 // need to call back to system server for permission check.
188 std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
189
190 bool hasUpdateDeviceStatsPermission(uid_t uid) REQUIRES(mMutex);
191
Wayne Ma4d692332022-01-19 16:04:04 +0800192 // For testing
193 friend class TrafficControllerTest;
194};
195
196} // namespace net
197} // namespace android