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