• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 
17 #ifndef NETD_SERVER_TRAFFIC_CONTROLLER_H
18 #define NETD_SERVER_TRAFFIC_CONTROLLER_H
19 
20 #include <linux/bpf.h>
21 
22 #include "BandwidthController.h"
23 #include "FirewallController.h"
24 #include "NetlinkListener.h"
25 #include "Network.h"
26 #include "android-base/thread_annotations.h"
27 #include "android-base/unique_fd.h"
28 #include "bpf/BpfMap.h"
29 #include "netdbpf/bpf_shared.h"
30 #include "netdutils/DumpWriter.h"
31 #include "netdutils/StatusOr.h"
32 #include "utils/String16.h"
33 
34 using android::bpf::BpfMap;
35 using android::bpf::IfaceValue;
36 using android::bpf::StatsKey;
37 using android::bpf::StatsValue;
38 using android::bpf::UidTag;
39 
40 namespace android {
41 namespace net {
42 
43 class TrafficController {
44   public:
45     TrafficController();
46     /*
47      * Initialize the whole controller
48      */
49     netdutils::Status start();
50     /*
51      * Tag the socket with the specified tag and uid. In the qtaguid module, the
52      * first tag request that grab the spinlock of rb_tree can update the tag
53      * information first and other request need to wait until it finish. All the
54      * tag request will be addressed in the order of they obtaining the spinlock.
55      * In the eBPF implementation, the kernel will try to update the eBPF map
56      * entry with the tag request. And the hashmap update process is protected by
57      * the spinlock initialized with the map. So the behavior of two modules
58      * should be the same. No additional lock needed.
59      */
60     int tagSocket(int sockFd, uint32_t tag, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
61 
62     /*
63      * The untag process is similiar to tag socket and both old qtaguid module and
64      * new eBPF module have spinlock inside the kernel for concurrent update. No
65      * external lock is required.
66      */
67     int untagSocket(int sockFd);
68 
69     /*
70      * Similiar as above, no external lock required.
71      */
72     int setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
73 
74     /*
75      * When deleting a tag data, the qtaguid module will grab the spinlock of each
76      * related rb_tree one by one and delete the tag information, counterSet
77      * information, iface stats information and uid stats information one by one.
78      * The new eBPF implementation is done similiarly by removing the entry on
79      * each map one by one. And deleting processes are also protected by the
80      * spinlock of the map. So no additional lock is required.
81      */
82     int deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
83 
84     /*
85      * Check if the current device have the bpf traffic stats accounting service
86      * running.
87      */
88     bpf::BpfLevel getBpfLevel();
89 
90     /*
91      * Swap the stats map config from current active stats map to the idle one.
92      */
93     netdutils::Status swapActiveStatsMap() EXCLUDES(mMutex);
94 
95     /*
96      * Add the interface name and index pair into the eBPF map.
97      */
98     int addInterface(const char* name, uint32_t ifaceIndex);
99 
100     int changeUidOwnerRule(ChildChain chain, const uid_t uid, FirewallRule rule, FirewallType type);
101 
102     int removeUidOwnerRule(const uid_t uid);
103 
104     int replaceUidOwnerMap(const std::string& name, bool isWhitelist,
105                            const std::vector<int32_t>& uids);
106 
107     netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
108                                           FirewallType type) EXCLUDES(mMutex);
109 
110     void dump(netdutils::DumpWriter& dw, bool verbose) EXCLUDES(mMutex);
111 
112     netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
113             EXCLUDES(mMutex);
114 
115     netdutils::Status addUidInterfaceRules(const int ifIndex, const std::vector<int32_t>& uids)
116             EXCLUDES(mMutex);
117     netdutils::Status removeUidInterfaceRules(const std::vector<int32_t>& uids) EXCLUDES(mMutex);
118 
119     netdutils::Status updateUidOwnerMap(const std::vector<std::string>& appStrUids,
120                                         BandwidthController::IptJumpOp jumpHandling,
121                                         BandwidthController::IptOp op) EXCLUDES(mMutex);
122     static const String16 DUMP_KEYWORD;
123 
124     int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
125 
126     static netdutils::StatusOr<std::unique_ptr<NetlinkListenerInterface>> makeSkDestroyListener();
127 
128     void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
129 
130   private:
131     /*
132      * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
133      * DO NOT hold any locks when modifying this map, otherwise when the untag
134      * operation is waiting for a lock hold by other process and there are more
135      * sockets being closed than can fit in the socket buffer of the netlink socket
136      * that receives them, then the kernel will drop some of these sockets and we
137      * won't delete their tags.
138      * Map Key: uint64_t socket cookie
139      * Map Value: struct UidTag, contains a uint32 uid and a uint32 tag.
140      */
141     BpfMap<uint64_t, UidTag> mCookieTagMap GUARDED_BY(mMutex);
142 
143     /*
144      * mUidCounterSetMap: Store the counterSet of a specific uid.
145      * Map Key: uint32 uid.
146      * Map Value: uint32 counterSet specifies if the traffic is a background
147      * or foreground traffic.
148      */
149     BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
150 
151     /*
152      * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
153      * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
154      * API to return persistent stats for a specific uid since device boot.
155      */
156     BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
157 
158     /*
159      * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
160      * combination of uid, tag, iface and counterSet. These two maps contain
161      * both tagged and untagged traffic.
162      * Map Key: Struct StatsKey contains the uid, tag, counterSet and ifaceIndex
163      * information.
164      * Map Value: struct Stats, contains packet count and byte count of each
165      * transport protocol on egress and ingress direction.
166      */
167     BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
168 
169     BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
170 
171     /*
172      * mIfaceIndexNameMap: Store the index name pair of each interface show up
173      * on the device since boot. The interface index is used by the eBPF program
174      * to correctly match the iface name when receiving a packet.
175      */
176     BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
177 
178     /*
179      * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
180      * filter.
181      */
182     BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
183 
184     /*
185      * mConfigurationMap: Store the current network policy about uid filtering
186      * and the current stats map in use. There are two configuration entries in
187      * the map right now:
188      * - Entry with UID_RULES_CONFIGURATION_KEY:
189      *    Store the configuration for the current uid rules. It indicates the device
190      *    is in doze/powersave/standby mode.
191      * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
192      *    Stores the current live stats map that kernel program is writing to.
193      *    Userspace can do scraping and cleaning job on the other one depending on the
194      *    current configs.
195      */
196     BpfMap<uint32_t, uint8_t> mConfigurationMap GUARDED_BY(mMutex);
197 
198     /*
199      * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
200      */
201     BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
202 
203     /*
204      * mUidOwnerMap: Store uids that are used for INTERNET permission check.
205      */
206     BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
207 
208     std::unique_ptr<NetlinkListenerInterface> mSkDestroyListener;
209 
210     netdutils::Status removeRule(BpfMap<uint32_t, UidOwnerValue>& map, uint32_t uid,
211                                  UidOwnerMatchType match) REQUIRES(mMutex);
212 
213     netdutils::Status addRule(BpfMap<uint32_t, UidOwnerValue>& map, uint32_t uid,
214                               UidOwnerMatchType match, uint32_t iif = 0) REQUIRES(mMutex);
215 
216     bpf::BpfLevel mBpfLevel;
217 
218     // mMutex guards all accesses to mConfigurationMap, mUidOwnerMap, mUidPermissionMap,
219     // mStatsMapA, mStatsMapB and mPrivilegedUser. It is designed to solve the following
220     // problems:
221     // 1. Prevent concurrent access and modification to mConfigurationMap, mUidOwnerMap,
222     //    mUidPermissionMap, and mPrivilegedUser. These data members are controlled by netd but can
223     //    be modified from different threads. TrafficController provides several APIs directly
224     //    called by the binder RPC, and different binder threads can concurrently access these data
225     //    members mentioned above. Some of the data members such as mUidPermissionMap and
226     //    mPrivilegedUsers are also accessed from a different thread when tagging sockets or
227     //    setting the counterSet through FwmarkServer
228     // 2. Coordinate the deletion of uid stats in mStatsMapA and mStatsMapB. The system server
229     //    always call into netd to ask for a live stats map change before it pull and clean up the
230     //    stats from the inactive map. The mMutex will block netd from accessing the stats map when
231     //    the mConfigurationMap is updating the current stats map so netd will not accidentally
232     //    read the map that system_server is cleaning up.
233     std::mutex mMutex;
234 
235     // The limit on the number of stats entries a uid can have in the per uid stats map.
236     // TrafficController will block that specific uid from tagging new sockets after the limit is
237     // reached.
238     const uint32_t mPerUidStatsEntriesLimit;
239 
240     // The limit on the total number of stats entries in the per uid stats map. TrafficController
241     // will block all tagging requests after the limit is reached.
242     const uint32_t mTotalUidStatsEntriesLimit;
243 
244     netdutils::Status loadAndAttachProgram(bpf_attach_type type, const char* path, const char* name,
245                                            base::unique_fd& cg_fd);
246 
247     netdutils::Status initMaps() EXCLUDES(mMutex);
248 
249     // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
250     // need to call back to system server for permission check.
251     std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
252 
253     UidOwnerMatchType jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling);
254 
255     bool hasUpdateDeviceStatsPermission(uid_t uid) REQUIRES(mMutex);
256 
257     // For testing
258     TrafficController(uint32_t perUidLimit, uint32_t totalLimit);
259 
260     // For testing
261     friend class TrafficControllerTest;
262 };
263 
264 }  // namespace net
265 }  // namespace android
266 
267 #endif  // NETD_SERVER_TRAFFIC_CONTROLLER_H
268