1 /*
2  * Copyright (C) 2021 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 <linux/if.h>
20 #include <linux/if_ether.h>
21 #include <linux/in.h>
22 #include <linux/in6.h>
23 
24 // Common definitions for BPF code in the tethering mainline module.
25 // These definitions are available to:
26 // - The BPF programs in Tethering/bpf_progs/
27 // - JNI code that depends on the bpf_connectivity_headers library.
28 
29 #define BPF_TETHER_ERRORS     \
30     ERR(INVALID_IPV4_VERSION) \
31     ERR(INVALID_IPV6_VERSION) \
32     ERR(LOW_TTL)              \
33     ERR(INVALID_TCP_HEADER)   \
34     ERR(TCPV4_CONTROL_PACKET) \
35     ERR(TCPV6_CONTROL_PACKET) \
36     ERR(NON_GLOBAL_SRC)       \
37     ERR(NON_GLOBAL_DST)       \
38     ERR(LOCAL_SRC_DST)        \
39     ERR(NO_STATS_ENTRY)       \
40     ERR(NO_LIMIT_ENTRY)       \
41     ERR(BELOW_IPV4_MTU)       \
42     ERR(BELOW_IPV6_MTU)       \
43     ERR(LIMIT_REACHED)        \
44     ERR(CHANGE_HEAD_FAILED)   \
45     ERR(TOO_SHORT)            \
46     ERR(HAS_IP_OPTIONS)       \
47     ERR(IS_IP_FRAG)           \
48     ERR(CHECKSUM)             \
49     ERR(NON_TCP_UDP)          \
50     ERR(NON_TCP)              \
51     ERR(SHORT_L4_HEADER)      \
52     ERR(SHORT_TCP_HEADER)     \
53     ERR(SHORT_UDP_HEADER)     \
54     ERR(UDP_CSUM_ZERO)        \
55     ERR(TRUNCATED_IPV4)       \
56     ERR(_MAX)
57 
58 #define ERR(x) BPF_TETHER_ERR_ ##x,
59 enum {
60     BPF_TETHER_ERRORS
61 };
62 #undef ERR
63 
64 #define ERR(x) #x,
65 static const char *bpf_tether_errors[] = {
66     BPF_TETHER_ERRORS
67 };
68 #undef ERR
69 
70 // This header file is shared by eBPF kernel programs (C) and netd (C++) and
71 // some of the maps are also accessed directly from Java mainline module code.
72 //
73 // Hence: explicitly pad all relevant structures and assert that their size
74 // is the sum of the sizes of their fields.
75 #define STRUCT_SIZE(name, size) _Static_assert(sizeof(name) == (size), "Incorrect struct size.")
76 
77 
78 typedef uint32_t TetherStatsKey;  // upstream ifindex
79 
80 typedef struct {
81     uint64_t rxPackets;
82     uint64_t rxBytes;
83     uint64_t rxErrors;
84     uint64_t txPackets;
85     uint64_t txBytes;
86     uint64_t txErrors;
87 } TetherStatsValue;
88 STRUCT_SIZE(TetherStatsValue, 6 * 8);  // 48
89 
90 typedef uint32_t TetherLimitKey;    // upstream ifindex
91 typedef uint64_t TetherLimitValue;  // in bytes
92 
93 // For now tethering offload only needs to support downstreams that use 6-byte MAC addresses,
94 // because all downstream types that are currently supported (WiFi, USB, Bluetooth and
95 // Ethernet) have 6-byte MAC addresses.
96 
97 typedef struct {
98     uint32_t iif;              // The input interface index
99     uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
100     uint8_t zero[2];           // zero pad for 8 byte alignment
101     struct in6_addr neigh6;    // The destination IPv6 address
102 } TetherDownstream6Key;
103 STRUCT_SIZE(TetherDownstream6Key, 4 + 6 + 2 + 16);  // 28
104 
105 typedef struct {
106     uint32_t oif;             // The output interface to redirect to
107     struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress)
108     uint16_t pmtu;            // The maximum L3 output path/route mtu
109 } Tether6Value;
110 STRUCT_SIZE(Tether6Value, 4 + 14 + 2);  // 20
111 
112 typedef struct {
113     uint32_t iif;              // The input interface index
114     uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
115     uint16_t l4Proto;          // IPPROTO_TCP/UDP/...
116     struct in6_addr src6;      // source &
117     struct in6_addr dst6;      // destination IPv6 addresses
118     __be16 srcPort;            // source &
119     __be16 dstPort;            // destination tcp/udp/... ports
120 } TetherDownstream64Key;
121 STRUCT_SIZE(TetherDownstream64Key, 4 + 6 + 2 + 16 + 16 + 2 + 2);  // 48
122 
123 typedef struct {
124     uint32_t oif;             // The output interface to redirect to
125     struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress)
126     uint16_t pmtu;            // The maximum L3 output path/route mtu
127     struct in_addr src4;      // source &
128     struct in_addr dst4;      // destination IPv4 addresses
129     __be16 srcPort;           // source &
130     __be16 outPort;           // destination tcp/udp/... ports
131     uint64_t lastUsed;        // Kernel updates on each use with bpf_ktime_get_boot_ns()
132 } TetherDownstream64Value;
133 STRUCT_SIZE(TetherDownstream64Value, 4 + 14 + 2 + 4 + 4 + 2 + 2 + 8);  // 40
134 
135 typedef struct {
136     uint32_t iif;              // The input interface index
137     uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
138     uint8_t zero[6];           // zero pad for 8 byte alignment
139     uint64_t src64;            // Top 64-bits of the src ip
140 } TetherUpstream6Key;
141 STRUCT_SIZE(TetherUpstream6Key, 4 + 6 + 6 + 8);  // 24
142 
143 typedef struct {
144     uint32_t iif;              // The input interface index
145     uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress)
146     uint16_t l4Proto;          // IPPROTO_TCP/UDP/...
147     struct in_addr src4;       // source &
148     struct in_addr dst4;       // destination IPv4 addresses
149     __be16 srcPort;            // source &
150     __be16 dstPort;            // destination TCP/UDP/... ports
151 } Tether4Key;
152 STRUCT_SIZE(Tether4Key, 4 + 6 + 2 + 4 + 4 + 2 + 2);  // 24
153 
154 typedef struct {
155     uint32_t oif;             // The output interface to redirect to
156     struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress)
157     uint16_t pmtu;            // Maximum L3 output path/route mtu
158     struct in6_addr src46;    // source &                 (always IPv4 mapped for downstream)
159     struct in6_addr dst46;    // destination IP addresses (may be IPv4 mapped or IPv6 for upstream)
160     __be16 srcPort;           // source &
161     __be16 dstPort;           // destination tcp/udp/... ports
162     uint64_t last_used;       // Kernel updates on each use with bpf_ktime_get_boot_ns()
163 } Tether4Value;
164 STRUCT_SIZE(Tether4Value, 4 + 14 + 2 + 16 + 16 + 2 + 2 + 8);  // 64
165 
166 #undef STRUCT_SIZE
167