• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 #pragma once
18 
19 #include <set>
20 #include <Common.h>
21 
22 #include "android-base/thread_annotations.h"
23 #include "bpf/BpfMap.h"
24 #include "bpf_shared.h"
25 #include "netdutils/DumpWriter.h"
26 #include "netdutils/NetlinkListener.h"
27 #include "netdutils/StatusOr.h"
28 
29 namespace android {
30 namespace net {
31 
32 using netdutils::StatusOr;
33 
34 class TrafficController {
35   public:
36     static constexpr char DUMP_KEYWORD[] = "trafficcontroller";
37 
38     /*
39      * Initialize the whole controller
40      */
41     netdutils::Status start();
42 
43     /*
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 
65     void dump(int fd, bool verbose) EXCLUDES(mMutex);
66 
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 
74     netdutils::Status updateUidOwnerMap(const uint32_t uid,
75                                         UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex);
76 
77     int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
78 
79     static netdutils::StatusOr<std::unique_ptr<netdutils::NetlinkListenerInterface>>
80     makeSkDestroyListener();
81 
82     void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
83 
84     FirewallType getFirewallType(ChildChain);
85 
86     static const char* LOCAL_DOZABLE;
87     static const char* LOCAL_STANDBY;
88     static const char* LOCAL_POWERSAVE;
89     static const char* LOCAL_RESTRICTED;
90     static const char* LOCAL_LOW_POWER_STANDBY;
91     static const char* LOCAL_OEM_DENY_1;
92     static const char* LOCAL_OEM_DENY_2;
93     static const char* LOCAL_OEM_DENY_3;
94 
95   private:
96     /*
97      * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
98      * DO NOT hold any locks when modifying this map, otherwise when the untag
99      * operation is waiting for a lock hold by other process and there are more
100      * sockets being closed than can fit in the socket buffer of the netlink socket
101      * that receives them, then the kernel will drop some of these sockets and we
102      * won't delete their tags.
103      * Map Key: uint64_t socket cookie
104      * Map Value: UidTagValue, contains a uint32 uid and a uint32 tag.
105      */
106     bpf::BpfMap<uint64_t, UidTagValue> mCookieTagMap GUARDED_BY(mMutex);
107 
108     /*
109      * mUidCounterSetMap: Store the counterSet of a specific uid.
110      * Map Key: uint32 uid.
111      * Map Value: uint32 counterSet specifies if the traffic is a background
112      * or foreground traffic.
113      */
114     bpf::BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
115 
116     /*
117      * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
118      * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
119      * API to return persistent stats for a specific uid since device boot.
120      */
121     bpf::BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
122 
123     /*
124      * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
125      * combination of uid, tag, iface and counterSet. These two maps contain
126      * both tagged and untagged traffic.
127      * Map Key: StatsKey contains the uid, tag, counterSet and ifaceIndex
128      * information.
129      * Map Value: Stats, contains packet count and byte count of each
130      * transport protocol on egress and ingress direction.
131      */
132     bpf::BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
133 
134     bpf::BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
135 
136     /*
137      * mIfaceIndexNameMap: Store the index name pair of each interface show up
138      * on the device since boot. The interface index is used by the eBPF program
139      * to correctly match the iface name when receiving a packet.
140      */
141     bpf::BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
142 
143     /*
144      * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
145      * filter.
146      */
147     bpf::BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
148 
149     /*
150      * mConfigurationMap: Store the current network policy about uid filtering
151      * and the current stats map in use. There are two configuration entries in
152      * the map right now:
153      * - Entry with UID_RULES_CONFIGURATION_KEY:
154      *    Store the configuration for the current uid rules. It indicates the device
155      *    is in doze/powersave/standby/restricted/low power standby/oem deny mode.
156      * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
157      *    Stores the current live stats map that kernel program is writing to.
158      *    Userspace can do scraping and cleaning job on the other one depending on the
159      *    current configs.
160      */
161     bpf::BpfMap<uint32_t, uint32_t> mConfigurationMap GUARDED_BY(mMutex);
162 
163     /*
164      * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
165      */
166     bpf::BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
167 
168     /*
169      * mUidOwnerMap: Store uids that are used for INTERNET permission check.
170      */
171     bpf::BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
172 
173     std::unique_ptr<netdutils::NetlinkListenerInterface> mSkDestroyListener;
174 
175     netdutils::Status removeRule(uint32_t uid, UidOwnerMatchType match) REQUIRES(mMutex);
176 
177     netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0)
178             REQUIRES(mMutex);
179 
180     std::mutex mMutex;
181 
182     netdutils::Status initMaps() EXCLUDES(mMutex);
183 
184     // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
185     // need to call back to system server for permission check.
186     std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
187 
188     bool hasUpdateDeviceStatsPermission(uid_t uid) REQUIRES(mMutex);
189 
190     // For testing
191     friend class TrafficControllerTest;
192 };
193 
194 }  // namespace net
195 }  // namespace android
196