| Lorenzo Colitti | 734b14e | 2021-02-05 23:56:09 +0900 | [diff] [blame] | 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 |  | 
| Lorenzo Colitti | 56be03e | 2021-02-24 00:10:44 +0900 | [diff] [blame] | 19 | #include <linux/if.h> | 
|  | 20 | #include <linux/if_ether.h> | 
|  | 21 | #include <linux/in.h> | 
|  | 22 | #include <linux/in6.h> | 
|  | 23 |  | 
| Lorenzo Colitti | 734b14e | 2021-02-05 23:56:09 +0900 | [diff] [blame] | 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_tethering_headers library. | 
| Lorenzo Colitti | b81584d | 2021-02-06 00:00:58 +0900 | [diff] [blame] | 28 |  | 
|  | 29 | #define BPF_TETHER_ERRORS    \ | 
|  | 30 | ERR(INVALID_IP_VERSION)  \ | 
|  | 31 | ERR(LOW_TTL)             \ | 
|  | 32 | ERR(INVALID_TCP_HEADER)  \ | 
|  | 33 | ERR(TCP_CONTROL_PACKET)  \ | 
|  | 34 | ERR(NON_GLOBAL_SRC)      \ | 
|  | 35 | ERR(NON_GLOBAL_DST)      \ | 
|  | 36 | ERR(LOCAL_SRC_DST)       \ | 
|  | 37 | ERR(NO_STATS_ENTRY)      \ | 
|  | 38 | ERR(NO_LIMIT_ENTRY)      \ | 
| Lorenzo Colitti | d561b7f | 2021-02-09 13:20:29 +0900 | [diff] [blame] | 39 | ERR(BELOW_IPV4_MTU)      \ | 
| Lorenzo Colitti | b81584d | 2021-02-06 00:00:58 +0900 | [diff] [blame] | 40 | ERR(BELOW_IPV6_MTU)      \ | 
|  | 41 | ERR(LIMIT_REACHED)       \ | 
|  | 42 | ERR(CHANGE_HEAD_FAILED)  \ | 
| Lorenzo Colitti | 72ec3ba | 2021-02-09 11:47:46 +0900 | [diff] [blame] | 43 | ERR(TOO_SHORT)           \ | 
| Lorenzo Colitti | d561b7f | 2021-02-09 13:20:29 +0900 | [diff] [blame] | 44 | ERR(HAS_IP_OPTIONS)      \ | 
|  | 45 | ERR(IS_IP_FRAG)          \ | 
|  | 46 | ERR(CHECKSUM)            \ | 
|  | 47 | ERR(NON_TCP_UDP)         \ | 
| Maciej Żenczykowski | 3686735 | 2021-02-15 01:53:17 -0800 | [diff] [blame] | 48 | ERR(NON_TCP)             \ | 
| Maciej Żenczykowski | 82ee26b | 2021-02-16 16:10:08 -0800 | [diff] [blame] | 49 | ERR(SHORT_L4_HEADER)     \ | 
| Lorenzo Colitti | d561b7f | 2021-02-09 13:20:29 +0900 | [diff] [blame] | 50 | ERR(SHORT_TCP_HEADER)    \ | 
|  | 51 | ERR(SHORT_UDP_HEADER)    \ | 
| Maciej Żenczykowski | e4a726a | 2021-02-16 17:27:34 -0800 | [diff] [blame] | 52 | ERR(UDP_CSUM_ZERO)       \ | 
| Lorenzo Colitti | d561b7f | 2021-02-09 13:20:29 +0900 | [diff] [blame] | 53 | ERR(TRUNCATED_IPV4)      \ | 
| Lorenzo Colitti | b81584d | 2021-02-06 00:00:58 +0900 | [diff] [blame] | 54 | ERR(_MAX) | 
|  | 55 |  | 
|  | 56 | #define ERR(x) BPF_TETHER_ERR_ ##x, | 
|  | 57 | enum { | 
|  | 58 | BPF_TETHER_ERRORS | 
|  | 59 | }; | 
|  | 60 | #undef ERR | 
|  | 61 |  | 
|  | 62 | #define ERR(x) #x, | 
|  | 63 | static const char *bpf_tether_errors[] = { | 
|  | 64 | BPF_TETHER_ERRORS | 
|  | 65 | }; | 
|  | 66 | #undef ERR | 
| Lorenzo Colitti | 56be03e | 2021-02-24 00:10:44 +0900 | [diff] [blame] | 67 |  | 
|  | 68 | // This header file is shared by eBPF kernel programs (C) and netd (C++) and | 
|  | 69 | // some of the maps are also accessed directly from Java mainline module code. | 
|  | 70 | // | 
|  | 71 | // Hence: explicitly pad all relevant structures and assert that their size | 
|  | 72 | // is the sum of the sizes of their fields. | 
|  | 73 | #define STRUCT_SIZE(name, size) _Static_assert(sizeof(name) == (size), "Incorrect struct size.") | 
|  | 74 |  | 
|  | 75 |  | 
|  | 76 | #define BPF_PATH_TETHER BPF_PATH "tethering/" | 
|  | 77 |  | 
|  | 78 | #define TETHER_STATS_MAP_PATH BPF_PATH_TETHER "map_offload_tether_stats_map" | 
|  | 79 |  | 
|  | 80 | typedef uint32_t TetherStatsKey;  // upstream ifindex | 
|  | 81 |  | 
|  | 82 | typedef struct { | 
|  | 83 | uint64_t rxPackets; | 
|  | 84 | uint64_t rxBytes; | 
|  | 85 | uint64_t rxErrors; | 
|  | 86 | uint64_t txPackets; | 
|  | 87 | uint64_t txBytes; | 
|  | 88 | uint64_t txErrors; | 
|  | 89 | } TetherStatsValue; | 
|  | 90 | STRUCT_SIZE(TetherStatsValue, 6 * 8);  // 48 | 
|  | 91 |  | 
|  | 92 | #define TETHER_LIMIT_MAP_PATH BPF_PATH_TETHER "map_offload_tether_limit_map" | 
|  | 93 |  | 
|  | 94 | typedef uint32_t TetherLimitKey;    // upstream ifindex | 
|  | 95 | typedef uint64_t TetherLimitValue;  // in bytes | 
|  | 96 |  | 
|  | 97 | #define TETHER_DOWNSTREAM6_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_downstream6_rawip" | 
|  | 98 | #define TETHER_DOWNSTREAM6_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_downstream6_ether" | 
|  | 99 |  | 
|  | 100 | #define TETHER_DOWNSTREAM6_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM6_TC_PROG_RAWIP_NAME | 
|  | 101 | #define TETHER_DOWNSTREAM6_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM6_TC_PROG_ETHER_NAME | 
|  | 102 |  | 
|  | 103 | #define TETHER_DOWNSTREAM6_MAP_PATH BPF_PATH_TETHER "map_offload_tether_downstream6_map" | 
|  | 104 |  | 
|  | 105 | // For now tethering offload only needs to support downstreams that use 6-byte MAC addresses, | 
|  | 106 | // because all downstream types that are currently supported (WiFi, USB, Bluetooth and | 
|  | 107 | // Ethernet) have 6-byte MAC addresses. | 
|  | 108 |  | 
|  | 109 | typedef struct { | 
| Hungming Chen | 9b8c606 | 2021-03-18 18:35:54 +0800 | [diff] [blame] | 110 | uint32_t iif;              // The input interface index | 
|  | 111 | uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress) | 
|  | 112 | uint8_t zero[2];           // zero pad for 8 byte alignment | 
|  | 113 | struct in6_addr neigh6;    // The destination IPv6 address | 
| Lorenzo Colitti | 56be03e | 2021-02-24 00:10:44 +0900 | [diff] [blame] | 114 | } TetherDownstream6Key; | 
| Hungming Chen | 9b8c606 | 2021-03-18 18:35:54 +0800 | [diff] [blame] | 115 | STRUCT_SIZE(TetherDownstream6Key, 4 + 6 + 2 + 16);  // 28 | 
| Lorenzo Colitti | 56be03e | 2021-02-24 00:10:44 +0900 | [diff] [blame] | 116 |  | 
|  | 117 | typedef struct { | 
|  | 118 | uint32_t oif;             // The output interface to redirect to | 
|  | 119 | struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress) | 
|  | 120 | uint16_t pmtu;            // The maximum L3 output path/route mtu | 
|  | 121 | } Tether6Value; | 
|  | 122 | STRUCT_SIZE(Tether6Value, 4 + 14 + 2);  // 20 | 
|  | 123 |  | 
|  | 124 | #define TETHER_DOWNSTREAM64_MAP_PATH BPF_PATH_TETHER "map_offload_tether_downstream64_map" | 
|  | 125 |  | 
|  | 126 | typedef struct { | 
|  | 127 | uint32_t iif;              // The input interface index | 
|  | 128 | uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress) | 
|  | 129 | uint16_t l4Proto;          // IPPROTO_TCP/UDP/... | 
|  | 130 | struct in6_addr src6;      // source & | 
|  | 131 | struct in6_addr dst6;      // destination IPv6 addresses | 
|  | 132 | __be16 srcPort;            // source & | 
|  | 133 | __be16 dstPort;            // destination tcp/udp/... ports | 
|  | 134 | } TetherDownstream64Key; | 
|  | 135 | STRUCT_SIZE(TetherDownstream64Key, 4 + 6 + 2 + 16 + 16 + 2 + 2);  // 48 | 
|  | 136 |  | 
|  | 137 | typedef struct { | 
|  | 138 | uint32_t oif;             // The output interface to redirect to | 
|  | 139 | struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress) | 
|  | 140 | uint16_t pmtu;            // The maximum L3 output path/route mtu | 
|  | 141 | struct in_addr src4;      // source & | 
|  | 142 | struct in_addr dst4;      // destination IPv4 addresses | 
|  | 143 | __be16 srcPort;           // source & | 
|  | 144 | __be16 outPort;           // destination tcp/udp/... ports | 
|  | 145 | uint64_t lastUsed;        // Kernel updates on each use with bpf_ktime_get_boot_ns() | 
|  | 146 | } TetherDownstream64Value; | 
|  | 147 | STRUCT_SIZE(TetherDownstream64Value, 4 + 14 + 2 + 4 + 4 + 2 + 2 + 8);  // 40 | 
|  | 148 |  | 
|  | 149 | #define TETHER_UPSTREAM6_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_upstream6_rawip" | 
|  | 150 | #define TETHER_UPSTREAM6_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_upstream6_ether" | 
|  | 151 |  | 
|  | 152 | #define TETHER_UPSTREAM6_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_UPSTREAM6_TC_PROG_RAWIP_NAME | 
|  | 153 | #define TETHER_UPSTREAM6_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_UPSTREAM6_TC_PROG_ETHER_NAME | 
|  | 154 |  | 
|  | 155 | #define TETHER_UPSTREAM6_MAP_PATH BPF_PATH_TETHER "map_offload_tether_upstream6_map" | 
|  | 156 |  | 
|  | 157 | typedef struct { | 
| Hungming Chen | 9b8c606 | 2021-03-18 18:35:54 +0800 | [diff] [blame] | 158 | uint32_t iif;              // The input interface index | 
|  | 159 | uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress) | 
|  | 160 | uint8_t zero[2];           // zero pad for 8 byte alignment | 
|  | 161 | // TODO: extend this to include src ip /64 subnet | 
| Lorenzo Colitti | 56be03e | 2021-02-24 00:10:44 +0900 | [diff] [blame] | 162 | } TetherUpstream6Key; | 
| Hungming Chen | 9b8c606 | 2021-03-18 18:35:54 +0800 | [diff] [blame] | 163 | STRUCT_SIZE(TetherUpstream6Key, 12); | 
| Lorenzo Colitti | 56be03e | 2021-02-24 00:10:44 +0900 | [diff] [blame] | 164 |  | 
|  | 165 | #define TETHER_DOWNSTREAM4_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_downstream4_rawip" | 
|  | 166 | #define TETHER_DOWNSTREAM4_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_downstream4_ether" | 
|  | 167 |  | 
|  | 168 | #define TETHER_DOWNSTREAM4_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM4_TC_PROG_RAWIP_NAME | 
|  | 169 | #define TETHER_DOWNSTREAM4_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM4_TC_PROG_ETHER_NAME | 
|  | 170 |  | 
|  | 171 | #define TETHER_DOWNSTREAM4_MAP_PATH BPF_PATH_TETHER "map_offload_tether_downstream4_map" | 
|  | 172 |  | 
|  | 173 |  | 
|  | 174 | #define TETHER_UPSTREAM4_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_upstream4_rawip" | 
|  | 175 | #define TETHER_UPSTREAM4_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_upstream4_ether" | 
|  | 176 |  | 
|  | 177 | #define TETHER_UPSTREAM4_TC_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_UPSTREAM4_TC_PROG_RAWIP_NAME | 
|  | 178 | #define TETHER_UPSTREAM4_TC_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_UPSTREAM4_TC_PROG_ETHER_NAME | 
|  | 179 |  | 
|  | 180 | #define TETHER_UPSTREAM4_MAP_PATH BPF_PATH_TETHER "map_offload_tether_upstream4_map" | 
|  | 181 |  | 
|  | 182 | typedef struct { | 
|  | 183 | uint32_t iif;              // The input interface index | 
|  | 184 | uint8_t dstMac[ETH_ALEN];  // destination ethernet mac address (zeroed iff rawip ingress) | 
|  | 185 | uint16_t l4Proto;          // IPPROTO_TCP/UDP/... | 
|  | 186 | struct in_addr src4;       // source & | 
|  | 187 | struct in_addr dst4;       // destination IPv4 addresses | 
|  | 188 | __be16 srcPort;            // source & | 
|  | 189 | __be16 dstPort;            // destination TCP/UDP/... ports | 
|  | 190 | } Tether4Key; | 
|  | 191 | STRUCT_SIZE(Tether4Key, 4 + 6 + 2 + 4 + 4 + 2 + 2);  // 24 | 
|  | 192 |  | 
|  | 193 | typedef struct { | 
|  | 194 | uint32_t oif;             // The output interface to redirect to | 
|  | 195 | struct ethhdr macHeader;  // includes dst/src mac and ethertype (zeroed iff rawip egress) | 
|  | 196 | uint16_t pmtu;            // Maximum L3 output path/route mtu | 
|  | 197 | struct in6_addr src46;    // source &                 (always IPv4 mapped for downstream) | 
|  | 198 | struct in6_addr dst46;    // destination IP addresses (may be IPv4 mapped or IPv6 for upstream) | 
|  | 199 | __be16 srcPort;           // source & | 
|  | 200 | __be16 dstPort;           // destination tcp/udp/... ports | 
|  | 201 | uint64_t last_used;       // Kernel updates on each use with bpf_ktime_get_boot_ns() | 
|  | 202 | } Tether4Value; | 
|  | 203 | STRUCT_SIZE(Tether4Value, 4 + 14 + 2 + 16 + 16 + 2 + 2 + 8);  // 64 | 
|  | 204 |  | 
|  | 205 | #define TETHER_DOWNSTREAM_XDP_PROG_RAWIP_NAME "prog_offload_xdp_tether_downstream_rawip" | 
|  | 206 | #define TETHER_DOWNSTREAM_XDP_PROG_ETHER_NAME "prog_offload_xdp_tether_downstream_ether" | 
|  | 207 |  | 
|  | 208 | #define TETHER_DOWNSTREAM_XDP_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM_XDP_PROG_RAWIP_NAME | 
|  | 209 | #define TETHER_DOWNSTREAM_XDP_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_DOWNSTREAM_XDP_PROG_ETHER_NAME | 
|  | 210 |  | 
|  | 211 | #define TETHER_UPSTREAM_XDP_PROG_RAWIP_NAME "prog_offload_xdp_tether_upstream_rawip" | 
|  | 212 | #define TETHER_UPSTREAM_XDP_PROG_ETHER_NAME "prog_offload_xdp_tether_upstream_ether" | 
|  | 213 |  | 
|  | 214 | #define TETHER_UPSTREAM_XDP_PROG_RAWIP_PATH BPF_PATH_TETHER TETHER_UPSTREAM_XDP_PROG_RAWIP_NAME | 
|  | 215 | #define TETHER_UPSTREAM_XDP_PROG_ETHER_PATH BPF_PATH_TETHER TETHER_UPSTREAM_XDP_PROG_ETHER_NAME | 
|  | 216 |  | 
|  | 217 | #undef STRUCT_SIZE |