• 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 "netd.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(bool startSkDestroyListener);
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     int changeUidOwnerRule(ChildChain chain, const uid_t uid, FirewallRule rule, FirewallType type);
49 
50     int removeUidOwnerRule(const uid_t uid);
51 
52     int replaceUidOwnerMap(const std::string& name, bool isAllowlist,
53                            const std::vector<int32_t>& uids);
54 
55     enum IptOp { IptOpInsert, IptOpDelete };
56 
57     netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
58                                           FirewallType type) EXCLUDES(mMutex);
59 
60     void dump(int fd, bool verbose) EXCLUDES(mMutex);
61 
62     netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
63             EXCLUDES(mMutex);
64 
65     netdutils::Status addUidInterfaceRules(const int ifIndex, const std::vector<int32_t>& uids)
66             EXCLUDES(mMutex);
67     netdutils::Status removeUidInterfaceRules(const std::vector<int32_t>& uids) EXCLUDES(mMutex);
68 
69     netdutils::Status updateUidLockdownRule(const uid_t uid, const bool add) EXCLUDES(mMutex);
70 
71     netdutils::Status updateUidOwnerMap(const uint32_t uid,
72                                         UidOwnerMatchType matchType, IptOp op) EXCLUDES(mMutex);
73 
74     int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
75 
76     static netdutils::StatusOr<std::unique_ptr<netdutils::NetlinkListenerInterface>>
77     makeSkDestroyListener();
78 
79     void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
80 
81     FirewallType getFirewallType(ChildChain);
82 
83     static const char* LOCAL_DOZABLE;
84     static const char* LOCAL_STANDBY;
85     static const char* LOCAL_POWERSAVE;
86     static const char* LOCAL_RESTRICTED;
87     static const char* LOCAL_LOW_POWER_STANDBY;
88     static const char* LOCAL_OEM_DENY_1;
89     static const char* LOCAL_OEM_DENY_2;
90     static const char* LOCAL_OEM_DENY_3;
91 
92   private:
93     /*
94      * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
95      * DO NOT hold any locks when modifying this map, otherwise when the untag
96      * operation is waiting for a lock hold by other process and there are more
97      * sockets being closed than can fit in the socket buffer of the netlink socket
98      * that receives them, then the kernel will drop some of these sockets and we
99      * won't delete their tags.
100      * Map Key: uint64_t socket cookie
101      * Map Value: UidTagValue, contains a uint32 uid and a uint32 tag.
102      */
103     bpf::BpfMap<uint64_t, UidTagValue> mCookieTagMap GUARDED_BY(mMutex);
104 
105     /*
106      * mUidCounterSetMap: Store the counterSet of a specific uid.
107      * Map Key: uint32 uid.
108      * Map Value: uint32 counterSet specifies if the traffic is a background
109      * or foreground traffic.
110      */
111     bpf::BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
112 
113     /*
114      * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
115      * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
116      * API to return persistent stats for a specific uid since device boot.
117      */
118     bpf::BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
119 
120     /*
121      * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
122      * combination of uid, tag, iface and counterSet. These two maps contain
123      * both tagged and untagged traffic.
124      * Map Key: StatsKey contains the uid, tag, counterSet and ifaceIndex
125      * information.
126      * Map Value: Stats, contains packet count and byte count of each
127      * transport protocol on egress and ingress direction.
128      */
129     bpf::BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
130 
131     bpf::BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
132 
133     /*
134      * mIfaceIndexNameMap: Store the index name pair of each interface show up
135      * on the device since boot. The interface index is used by the eBPF program
136      * to correctly match the iface name when receiving a packet.
137      */
138     bpf::BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
139 
140     /*
141      * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
142      * filter.
143      */
144     bpf::BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
145 
146     /*
147      * mConfigurationMap: Store the current network policy about uid filtering
148      * and the current stats map in use. There are two configuration entries in
149      * the map right now:
150      * - Entry with UID_RULES_CONFIGURATION_KEY:
151      *    Store the configuration for the current uid rules. It indicates the device
152      *    is in doze/powersave/standby/restricted/low power standby/oem deny mode.
153      * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
154      *    Stores the current live stats map that kernel program is writing to.
155      *    Userspace can do scraping and cleaning job on the other one depending on the
156      *    current configs.
157      */
158     bpf::BpfMap<uint32_t, uint32_t> mConfigurationMap GUARDED_BY(mMutex);
159 
160     /*
161      * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
162      */
163     bpf::BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
164 
165     /*
166      * mUidOwnerMap: Store uids that are used for INTERNET permission check.
167      */
168     bpf::BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
169 
170     std::unique_ptr<netdutils::NetlinkListenerInterface> mSkDestroyListener;
171 
172     netdutils::Status removeRule(uint32_t uid, UidOwnerMatchType match) REQUIRES(mMutex);
173 
174     netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0)
175             REQUIRES(mMutex);
176 
177     std::mutex mMutex;
178 
179     netdutils::Status initMaps() EXCLUDES(mMutex);
180 
181     // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
182     // need to call back to system server for permission check.
183     std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
184 
185     // For testing
186     friend class TrafficControllerTest;
187 };
188 
189 }  // namespace net
190 }  // namespace android
191