blob: 2d89344339931e4e75855892a1d3a55c49a06244 [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 Rohrc2984fd2022-01-31 18:06:19 +010035 // TODO: marking this private for right now, as start is already called by
36 // netd. start() calls initMaps(), initPrograms(), and sets up the socket
37 // destroy listener. Both initPrograms() and setting up the socket destroy
38 // listener should only be done once.
Wayne Ma4d692332022-01-19 16:04:04 +080039 /*
40 * Initialize the whole controller
41 */
42 netdutils::Status start();
Wayne Ma4d692332022-01-19 16:04:04 +080043
Patrick Rohrc2984fd2022-01-31 18:06:19 +010044 public:
45 static constexpr char DUMP_KEYWORD[] = "trafficcontroller";
46
47 // TODO: marking this public for right now, as start() is already called by
48 // netd.
49 netdutils::Status initMaps() EXCLUDES(mMutex);
50
Wayne Ma4d692332022-01-19 16:04:04 +080051 int setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
52
53 /*
54 * When deleting a tag data, the qtaguid module will grab the spinlock of each
55 * related rb_tree one by one and delete the tag information, counterSet
56 * information, iface stats information and uid stats information one by one.
57 * The new eBPF implementation is done similiarly by removing the entry on
58 * each map one by one. And deleting processes are also protected by the
59 * spinlock of the map. So no additional lock is required.
60 */
61 int deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
62
63 /*
64 * Swap the stats map config from current active stats map to the idle one.
65 */
66 netdutils::Status swapActiveStatsMap() EXCLUDES(mMutex);
67
68 /*
69 * Add the interface name and index pair into the eBPF map.
70 */
71 int addInterface(const char* name, uint32_t ifaceIndex);
72
73 int changeUidOwnerRule(ChildChain chain, const uid_t uid, FirewallRule rule, FirewallType type);
74
75 int removeUidOwnerRule(const uid_t uid);
76
77 int replaceUidOwnerMap(const std::string& name, bool isAllowlist,
78 const std::vector<int32_t>& uids);
79
80 enum IptOp { IptOpInsert, IptOpDelete };
81
82 netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
83 FirewallType type) EXCLUDES(mMutex);
84
85 void dump(netdutils::DumpWriter& dw, bool verbose) EXCLUDES(mMutex);
86
87 netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
88 EXCLUDES(mMutex);
89
90 netdutils::Status addUidInterfaceRules(const int ifIndex, const std::vector<int32_t>& uids)
91 EXCLUDES(mMutex);
92 netdutils::Status removeUidInterfaceRules(const std::vector<int32_t>& uids) EXCLUDES(mMutex);
93
Wayne Maa9716ff2022-01-12 10:37:04 +080094 netdutils::Status updateUidOwnerMap(const uint32_t uid,
Wayne Ma4d692332022-01-19 16:04:04 +080095 UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex);
Wayne Ma4d692332022-01-19 16:04:04 +080096
97 int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
98
99 static netdutils::StatusOr<std::unique_ptr<netdutils::NetlinkListenerInterface>>
100 makeSkDestroyListener();
101
102 void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
103
104 FirewallType getFirewallType(ChildChain);
105
106 static const char* LOCAL_DOZABLE;
107 static const char* LOCAL_STANDBY;
108 static const char* LOCAL_POWERSAVE;
109 static const char* LOCAL_RESTRICTED;
110
111 private:
112 /*
113 * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
114 * DO NOT hold any locks when modifying this map, otherwise when the untag
115 * operation is waiting for a lock hold by other process and there are more
116 * sockets being closed than can fit in the socket buffer of the netlink socket
117 * that receives them, then the kernel will drop some of these sockets and we
118 * won't delete their tags.
119 * Map Key: uint64_t socket cookie
120 * Map Value: UidTagValue, contains a uint32 uid and a uint32 tag.
121 */
122 bpf::BpfMap<uint64_t, UidTagValue> mCookieTagMap GUARDED_BY(mMutex);
123
124 /*
125 * mUidCounterSetMap: Store the counterSet of a specific uid.
126 * Map Key: uint32 uid.
127 * Map Value: uint32 counterSet specifies if the traffic is a background
128 * or foreground traffic.
129 */
130 bpf::BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
131
132 /*
133 * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
134 * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
135 * API to return persistent stats for a specific uid since device boot.
136 */
137 bpf::BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
138
139 /*
140 * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
141 * combination of uid, tag, iface and counterSet. These two maps contain
142 * both tagged and untagged traffic.
143 * Map Key: StatsKey contains the uid, tag, counterSet and ifaceIndex
144 * information.
145 * Map Value: Stats, contains packet count and byte count of each
146 * transport protocol on egress and ingress direction.
147 */
148 bpf::BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
149
150 bpf::BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
151
152 /*
153 * mIfaceIndexNameMap: Store the index name pair of each interface show up
154 * on the device since boot. The interface index is used by the eBPF program
155 * to correctly match the iface name when receiving a packet.
156 */
157 bpf::BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
158
159 /*
160 * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
161 * filter.
162 */
163 bpf::BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
164
165 /*
166 * mConfigurationMap: Store the current network policy about uid filtering
167 * and the current stats map in use. There are two configuration entries in
168 * the map right now:
169 * - Entry with UID_RULES_CONFIGURATION_KEY:
170 * Store the configuration for the current uid rules. It indicates the device
171 * is in doze/powersave/standby/restricted mode.
172 * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
173 * Stores the current live stats map that kernel program is writing to.
174 * Userspace can do scraping and cleaning job on the other one depending on the
175 * current configs.
176 */
177 bpf::BpfMap<uint32_t, uint8_t> mConfigurationMap GUARDED_BY(mMutex);
178
179 /*
180 * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
181 */
182 bpf::BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
183
184 /*
185 * mUidOwnerMap: Store uids that are used for INTERNET permission check.
186 */
187 bpf::BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
188
189 std::unique_ptr<netdutils::NetlinkListenerInterface> mSkDestroyListener;
190
191 netdutils::Status removeRule(uint32_t uid, UidOwnerMatchType match) REQUIRES(mMutex);
192
193 netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0)
194 REQUIRES(mMutex);
195
Wayne Ma4d692332022-01-19 16:04:04 +0800196 std::mutex mMutex;
197
Wayne Ma4d692332022-01-19 16:04:04 +0800198 // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
199 // need to call back to system server for permission check.
200 std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
201
202 bool hasUpdateDeviceStatsPermission(uid_t uid) REQUIRES(mMutex);
203
Wayne Ma4d692332022-01-19 16:04:04 +0800204 // For testing
205 friend class TrafficControllerTest;
206};
207
208} // namespace net
209} // namespace android