1 /* 2 * Copyright (C) 2018 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 NETDBPF_BPF_SHARED_H 18 #define NETDBPF_BPF_SHARED_H 19 20 #include <linux/if_ether.h> 21 #include <linux/in.h> 22 #include <linux/in6.h> 23 #include <netdutils/UidConstants.h> 24 25 // This header file is shared by eBPF kernel programs and netd 26 27 typedef struct { 28 uint32_t uid; 29 uint32_t tag; 30 } UidTagValue; 31 32 typedef struct { 33 uint32_t uid; 34 uint32_t tag; 35 uint32_t counterSet; 36 uint32_t ifaceIndex; 37 } StatsKey; 38 39 typedef struct { 40 uint64_t rxPackets; 41 uint64_t rxBytes; 42 uint64_t txPackets; 43 uint64_t txBytes; 44 } StatsValue; 45 46 typedef struct { 47 char name[IFNAMSIZ]; 48 } IfaceValue; 49 50 typedef struct { 51 uint64_t rxBytes; 52 uint64_t rxPackets; 53 uint64_t txBytes; 54 uint64_t txPackets; 55 uint64_t tcpRxPackets; 56 uint64_t tcpTxPackets; 57 } Stats; 58 59 // Since we cannot garbage collect the stats map since device boot, we need to make these maps as 60 // large as possible. The maximum size of number of map entries we can have is depend on the rlimit 61 // of MEM_LOCK granted to netd. The memory space needed by each map can be calculated by the 62 // following fomula: 63 // elem_size = 40 + roundup(key_size, 8) + roundup(value_size, 8) 64 // cost = roundup_pow_of_two(max_entries) * 16 + elem_size * max_entries + 65 // elem_size * number_of_CPU 66 // And the cost of each map currently used is(assume the device have 8 CPUs): 67 // cookie_tag_map: key: 8 bytes, value: 8 bytes, cost: 822592 bytes = 823Kbytes 68 // uid_counter_set_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes 69 // app_uid_stats_map: key: 4 bytes, value: 32 bytes, cost: 1062784 bytes = 1063Kbytes 70 // uid_stats_map: key: 16 bytes, value: 32 bytes, cost: 1142848 bytes = 1143Kbytes 71 // tag_stats_map: key: 16 bytes, value: 32 bytes, cost: 1142848 bytes = 1143Kbytes 72 // iface_index_name_map:key: 4 bytes, value: 16 bytes, cost: 80896 bytes = 81Kbytes 73 // iface_stats_map: key: 4 bytes, value: 32 bytes, cost: 97024 bytes = 97Kbytes 74 // dozable_uid_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes 75 // standby_uid_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes 76 // powersave_uid_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes 77 // total: 4930Kbytes 78 // It takes maximum 4.9MB kernel memory space if all maps are full, which requires any devices 79 // running this module to have a memlock rlimit to be larger then 5MB. In the old qtaguid module, 80 // we don't have a total limit for data entries but only have limitation of tags each uid can have. 81 // (default is 1024 in kernel); 82 83 const int COOKIE_UID_MAP_SIZE = 10000; 84 const int UID_COUNTERSET_MAP_SIZE = 2000; 85 const int APP_STATS_MAP_SIZE = 10000; 86 const int STATS_MAP_SIZE = 5000; 87 const int IFACE_INDEX_NAME_MAP_SIZE = 1000; 88 const int IFACE_STATS_MAP_SIZE = 1000; 89 const int CONFIGURATION_MAP_SIZE = 2; 90 const int UID_OWNER_MAP_SIZE = 2000; 91 92 #define BPF_PATH "/sys/fs/bpf" 93 94 #define BPF_EGRESS_PROG_PATH BPF_PATH "/prog_netd_cgroupskb_egress_stats" 95 #define BPF_INGRESS_PROG_PATH BPF_PATH "/prog_netd_cgroupskb_ingress_stats" 96 #define XT_BPF_INGRESS_PROG_PATH BPF_PATH "/prog_netd_skfilter_ingress_xtbpf" 97 #define XT_BPF_EGRESS_PROG_PATH BPF_PATH "/prog_netd_skfilter_egress_xtbpf" 98 #define XT_BPF_ALLOWLIST_PROG_PATH BPF_PATH "/prog_netd_skfilter_allowlist_xtbpf" 99 #define XT_BPF_DENYLIST_PROG_PATH BPF_PATH "/prog_netd_skfilter_denylist_xtbpf" 100 #define CGROUP_SOCKET_PROG_PATH BPF_PATH "/prog_netd_cgroupsock_inet_create" 101 102 #define COOKIE_TAG_MAP_PATH BPF_PATH "/map_netd_cookie_tag_map" 103 #define UID_COUNTERSET_MAP_PATH BPF_PATH "/map_netd_uid_counterset_map" 104 #define APP_UID_STATS_MAP_PATH BPF_PATH "/map_netd_app_uid_stats_map" 105 #define STATS_MAP_A_PATH BPF_PATH "/map_netd_stats_map_A" 106 #define STATS_MAP_B_PATH BPF_PATH "/map_netd_stats_map_B" 107 #define IFACE_INDEX_NAME_MAP_PATH BPF_PATH "/map_netd_iface_index_name_map" 108 #define IFACE_STATS_MAP_PATH BPF_PATH "/map_netd_iface_stats_map" 109 #define CONFIGURATION_MAP_PATH BPF_PATH "/map_netd_configuration_map" 110 #define UID_OWNER_MAP_PATH BPF_PATH "/map_netd_uid_owner_map" 111 #define UID_PERMISSION_MAP_PATH BPF_PATH "/map_netd_uid_permission_map" 112 113 enum UidOwnerMatchType { 114 NO_MATCH = 0, 115 HAPPY_BOX_MATCH = (1 << 0), 116 PENALTY_BOX_MATCH = (1 << 1), 117 DOZABLE_MATCH = (1 << 2), 118 STANDBY_MATCH = (1 << 3), 119 POWERSAVE_MATCH = (1 << 4), 120 IIF_MATCH = (1 << 5), 121 }; 122 123 enum BpfPermissionMatch { 124 BPF_PERMISSION_INTERNET = 1 << 2, 125 BPF_PERMISSION_UPDATE_DEVICE_STATS = 1 << 3, 126 }; 127 // In production we use two identical stats maps to record per uid stats and 128 // do swap and clean based on the configuration specified here. The statsMapType 129 // value in configuration map specified which map is currently in use. 130 enum StatsMapType { 131 SELECT_MAP_A, 132 SELECT_MAP_B, 133 }; 134 135 // TODO: change the configuration object from an 8-bit bitmask to an object with clearer 136 // semantics, like a struct. 137 typedef uint8_t BpfConfig; 138 const BpfConfig DEFAULT_CONFIG = 0; 139 140 typedef struct { 141 // Allowed interface index. Only applicable if IIF_MATCH is set in the rule bitmask above. 142 uint32_t iif; 143 // A bitmask of enum values in UidOwnerMatchType. 144 uint8_t rule; 145 } UidOwnerValue; 146 147 #define UID_RULES_CONFIGURATION_KEY 1 148 #define CURRENT_STATS_MAP_CONFIGURATION_KEY 2 149 150 #define CLAT_INGRESS_PROG_RAWIP_NAME "prog_clatd_schedcls_ingress_clat_rawip" 151 #define CLAT_INGRESS_PROG_ETHER_NAME "prog_clatd_schedcls_ingress_clat_ether" 152 153 #define CLAT_INGRESS_PROG_RAWIP_PATH BPF_PATH "/" CLAT_INGRESS_PROG_RAWIP_NAME 154 #define CLAT_INGRESS_PROG_ETHER_PATH BPF_PATH "/" CLAT_INGRESS_PROG_ETHER_NAME 155 156 #define CLAT_INGRESS_MAP_PATH BPF_PATH "/map_clatd_clat_ingress_map" 157 158 typedef struct { 159 uint32_t iif; // The input interface index 160 struct in6_addr pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0 161 struct in6_addr local6; // The full 128-bits of the destination IPv6 address 162 } ClatIngressKey; 163 164 typedef struct { 165 uint32_t oif; // The output interface to redirect to (0 means don't redirect) 166 struct in_addr local4; // The destination IPv4 address 167 } ClatIngressValue; 168 169 #define CLAT_EGRESS_PROG_RAWIP_NAME "prog_clatd_schedcls_egress_clat_rawip" 170 #define CLAT_EGRESS_PROG_ETHER_NAME "prog_clatd_schedcls_egress_clat_ether" 171 172 #define CLAT_EGRESS_PROG_RAWIP_PATH BPF_PATH "/" CLAT_EGRESS_PROG_RAWIP_NAME 173 #define CLAT_EGRESS_PROG_ETHER_PATH BPF_PATH "/" CLAT_EGRESS_PROG_ETHER_NAME 174 175 #define CLAT_EGRESS_MAP_PATH BPF_PATH "/map_clatd_clat_egress_map" 176 177 typedef struct { 178 uint32_t iif; // The input interface index 179 struct in_addr local4; // The source IPv4 address 180 } ClatEgressKey; 181 182 typedef struct { 183 uint32_t oif; // The output interface to redirect to 184 struct in6_addr local6; // The full 128-bits of the source IPv6 address 185 struct in6_addr pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0 186 bool oifIsEthernet; // Whether the output interface requires ethernet header 187 } ClatEgressValue; 188 189 #define TETHER_INGRESS_PROG_RAWIP_NAME "prog_offload_schedcls_ingress_tether_rawip" 190 #define TETHER_INGRESS_PROG_ETHER_NAME "prog_offload_schedcls_ingress_tether_ether" 191 192 #define TETHER_INGRESS_PROG_RAWIP_PATH BPF_PATH "/" TETHER_INGRESS_PROG_RAWIP_NAME 193 #define TETHER_INGRESS_PROG_ETHER_PATH BPF_PATH "/" TETHER_INGRESS_PROG_ETHER_NAME 194 195 #define TETHER_INGRESS_MAP_PATH BPF_PATH "/map_offload_tether_ingress_map" 196 197 typedef struct { 198 uint32_t iif; // The input interface index 199 struct in6_addr neigh6; // The destination IPv6 address 200 } TetherIngressKey; 201 202 typedef struct { 203 uint32_t oif; // The output interface to redirect to 204 // For now tethering offload only needs to support downstreams that use 6-byte MAC addresses, 205 // because all downstream types that are currently supported (WiFi, USB, Bluetooth and 206 // Ethernet) have 6-byte MAC addresses. 207 struct ethhdr macHeader; // includes dst/src mac and ethertype 208 uint16_t pmtu; // The maximum L3 output path/route mtu 209 } TetherIngressValue; 210 211 #define TETHER_STATS_MAP_PATH BPF_PATH "/map_offload_tether_stats_map" 212 213 typedef struct { 214 uint64_t rxPackets; 215 uint64_t rxBytes; 216 uint64_t rxErrors; 217 uint64_t txPackets; 218 uint64_t txBytes; 219 uint64_t txErrors; 220 } TetherStatsValue; 221 222 #define TETHER_LIMIT_MAP_PATH BPF_PATH "/map_offload_tether_limit_map" 223 224 #endif // NETDBPF_BPF_SHARED_H 225