summaryrefslogtreecommitdiff
path: root/Tethering/bpf_progs/bpf_tethering.h
blob: 5fdf8cd88eadadcbce850a9bfd318829902996a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/in.h>
#include <linux/in6.h>

// Common definitions for BPF code in the tethering mainline module.
// These definitions are available to:
// - The BPF programs in Tethering/bpf_progs/
// - JNI code that depends on the bpf_tethering_headers library.

#define BPF_TETHER_ERRORS    \
    ERR(INVALID_IP_VERSION)  \
    ERR(LOW_TTL)             \
    ERR(INVALID_TCP_HEADER)  \
    ERR(TCP_CONTROL_PACKET)  \
    ERR(NON_GLOBAL_SRC)      \
    ERR(NON_GLOBAL_DST)      \
    ERR(LOCAL_SRC_DST)       \
    ERR(NO_STATS_ENTRY)      \
    ERR(NO_LIMIT_ENTRY)      \
    ERR(BELOW_IPV4_MTU)      \
    ERR(BELOW_IPV6_MTU)      \
    ERR(LIMIT_REACHED)       \
    ERR(CHANGE_HEAD_FAILED)  \
    ERR(TOO_SHORT)           \
    ERR(HAS_IP_OPTIONS)      \
    ERR(IS_IP_FRAG)          \
    ERR(CHECKSUM)            \
    ERR(NON_TCP_UDP)         \
    ERR(NON_TCP)             \
    ERR(SHORT_L4_HEADER)     \
    ERR(SHORT_TCP_HEADER)    \
    ERR(SHORT_UDP_HEADER)    \
    ERR(UDP_CSUM_ZERO)       \
    ERR(TRUNCATED_IPV4)      \
    ERR(_MAX)

#define ERR(x) BPF_TETHER_ERR_ ##x,
enum {
    BPF_TETHER_ERRORS
};
#undef ERR

#define ERR(x) #x,
static const char *bpf_tether_errors[] = {
    BPF_TETHER_ERRORS
};
#undef ERR

// This header file is shared by eBPF kernel programs (C) and netd (C++) and
// some of the maps are also accessed directly from Java mainline module code.
//
// Hence: explicitly pad all relevant structures and assert that their size
// is the sum of the sizes of their fields.
#define STRUCT_SIZE(name, size) _Static_assert(sizeof(name) == (size), "Incorrect struct size.")


#define BPF_PATH_TETHER BPF_PATH "tethering/"

#define TETHER_STATS_MAP_PATH BPF_PATH_TETHER "map_offload_tether_stats_map"

typedef uint32_t TetherStatsKey;  // upstream ifindex

typedef struct {
    uint64_t rxPackets;
    uint64_t rxBytes;
    uint64_t rxErrors;
    uint64_t txPackets;
    uint64_t txBytes;
    uint64_t txErrors;
} TetherStatsValue;
STRUCT_SIZE(TetherStatsValue, 6 * 8);  // 48

#define TETHER_LIMIT_MAP_PATH BPF_PATH_TETHER "map_offload_tether_limit_map"

typedef uint32_t TetherLimitKey;    // upstream ifindex
typedef uint64_t TetherLimitValue;  // in bytes

#define TETHER_DOWNSTREAM6_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_downstream6_rawip"
#define TETHER_DOWNSTREAM6_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_downstream6_ether"

#define TETHER_DOWNSTREAM6_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM6_TC_PROG_RAWIP_NAME
#define TETHER_DOWNSTREAM6_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM6_TC_PROG_ETHER_NAME

#define TETHER_DOWNSTREAM6_MAP_PATH BPF_PATH_TETHER "map_offload_tether_downstream6_map"

// For now tethering offload only needs to support downstreams that use 6-byte MAC addresses,
// because all downstream types that are currently supported (WiFi, USB, Bluetooth and
// Ethernet) have 6-byte MAC addresses.

typedef struct {
    uint32_t iif;              // The input interface index
    uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
    uint8_t zero[2];           // zero pad for 8 byte alignment
    struct in6_addr neigh6;    // The destination IPv6 address
} TetherDownstream6Key;
STRUCT_SIZE(TetherDownstream6Key, 4 + 6 + 2 + 16);  // 28

typedef struct {
    uint32_t oif;             // The output interface to redirect to
    struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress)
    uint16_t pmtu;            // The maximum L3 output path/route mtu
} Tether6Value;
STRUCT_SIZE(Tether6Value, 4 + 14 + 2);  // 20

#define TETHER_DOWNSTREAM64_MAP_PATH BPF_PATH_TETHER "map_offload_tether_downstream64_map"

typedef struct {
    uint32_t iif;              // The input interface index
    uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
    uint16_t l4Proto;          // IPPROTO_TCP/UDP/...
    struct in6_addr src6;      // source &
    struct in6_addr dst6;      // destination IPv6 addresses
    __be16 srcPort;            // source &
    __be16 dstPort;            // destination tcp/udp/... ports
} TetherDownstream64Key;
STRUCT_SIZE(TetherDownstream64Key, 4 + 6 + 2 + 16 + 16 + 2 + 2);  // 48

typedef struct {
    uint32_t oif;             // The output interface to redirect to
    struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress)
    uint16_t pmtu;            // The maximum L3 output path/route mtu
    struct in_addr src4;      // source &
    struct in_addr dst4;      // destination IPv4 addresses
    __be16 srcPort;           // source &
    __be16 outPort;           // destination tcp/udp/... ports
    uint64_t lastUsed;        // Kernel updates on each use with bpf_ktime_get_boot_ns()
} TetherDownstream64Value;
STRUCT_SIZE(TetherDownstream64Value, 4 + 14 + 2 + 4 + 4 + 2 + 2 + 8);  // 40

#define TETHER_UPSTREAM6_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_upstream6_rawip"
#define TETHER_UPSTREAM6_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_upstream6_ether"

#define TETHER_UPSTREAM6_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_UPSTREAM6_TC_PROG_RAWIP_NAME
#define TETHER_UPSTREAM6_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_UPSTREAM6_TC_PROG_ETHER_NAME

#define TETHER_UPSTREAM6_MAP_PATH BPF_PATH_TETHER "map_offload_tether_upstream6_map"

typedef struct {
    uint32_t iif;              // The input interface index
    uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
    uint8_t zero[2];           // zero pad for 8 byte alignment
                               // TODO: extend this to include src ip /64 subnet
} TetherUpstream6Key;
STRUCT_SIZE(TetherUpstream6Key, 12);

#define TETHER_DOWNSTREAM4_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_downstream4_rawip"
#define TETHER_DOWNSTREAM4_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_downstream4_ether"

#define TETHER_DOWNSTREAM4_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM4_TC_PROG_RAWIP_NAME
#define TETHER_DOWNSTREAM4_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM4_TC_PROG_ETHER_NAME

#define TETHER_DOWNSTREAM4_MAP_PATH BPF_PATH_TETHER "map_offload_tether_downstream4_map"


#define TETHER_UPSTREAM4_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_upstream4_rawip"
#define TETHER_UPSTREAM4_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_upstream4_ether"

#define TETHER_UPSTREAM4_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_UPSTREAM4_TC_PROG_RAWIP_NAME
#define TETHER_UPSTREAM4_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_UPSTREAM4_TC_PROG_ETHER_NAME

#define TETHER_UPSTREAM4_MAP_PATH BPF_PATH_TETHER "map_offload_tether_upstream4_map"

typedef struct {
    uint32_t iif;              // The input interface index
    uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
    uint16_t l4Proto;          // IPPROTO_TCP/UDP/...
    struct in_addr src4;       // source &
    struct in_addr dst4;       // destination IPv4 addresses
    __be16 srcPort;            // source &
    __be16 dstPort;            // destination TCP/UDP/... ports
} Tether4Key;
STRUCT_SIZE(Tether4Key, 4 + 6 + 2 + 4 + 4 + 2 + 2);  // 24

typedef struct {
    uint32_t oif;             // The output interface to redirect to
    struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress)
    uint16_t pmtu;            // Maximum L3 output path/route mtu
    struct in6_addr src46;    // source &                 (always IPv4 mapped for downstream)
    struct in6_addr dst46;    // destination IP addresses (may be IPv4 mapped or IPv6 for upstream)
    __be16 srcPort;           // source &
    __be16 dstPort;           // destination tcp/udp/... ports
    uint64_t last_used;       // Kernel updates on each use with bpf_ktime_get_boot_ns()
} Tether4Value;
STRUCT_SIZE(Tether4Value, 4 + 14 + 2 + 16 + 16 + 2 + 2 + 8);  // 64

#define TETHER_DOWNSTREAM_XDP_PROG_RAWIP_NAME "prog_offload_xdp_tether_downstream_rawip"
#define TETHER_DOWNSTREAM_XDP_PROG_ETHER_NAME "prog_offload_xdp_tether_downstream_ether"

#define TETHER_DOWNSTREAM_XDP_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM_XDP_PROG_RAWIP_NAME
#define TETHER_DOWNSTREAM_XDP_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM_XDP_PROG_ETHER_NAME

#define TETHER_UPSTREAM_XDP_PROG_RAWIP_NAME "prog_offload_xdp_tether_upstream_rawip"
#define TETHER_UPSTREAM_XDP_PROG_ETHER_NAME "prog_offload_xdp_tether_upstream_ether"

#define TETHER_UPSTREAM_XDP_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_UPSTREAM_XDP_PROG_RAWIP_NAME
#define TETHER_UPSTREAM_XDP_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_UPSTREAM_XDP_PROG_ETHER_NAME

#undef STRUCT_SIZE