• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_WHITELIST_PROG_PATH BPF_PATH "/prog_netd_skfilter_whitelist_xtbpf"
99 #define XT_BPF_BLACKLIST_PROG_PATH BPF_PATH "/prog_netd_skfilter_blacklist_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