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_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) \ 39 ERR(BELOW_IPV4_MTU) \ 40 ERR(BELOW_IPV6_MTU) \ 41 ERR(LIMIT_REACHED) \ 42 ERR(CHANGE_HEAD_FAILED) \ 43 ERR(TOO_SHORT) \ 44 ERR(HAS_IP_OPTIONS) \ 45 ERR(IS_IP_FRAG) \ 46 ERR(CHECKSUM) \ 47 ERR(NON_TCP_UDP) \ 48 ERR(NON_TCP) \ 49 ERR(SHORT_L4_HEADER) \ 50 ERR(SHORT_TCP_HEADER) \ 51 ERR(SHORT_UDP_HEADER) \ 52 ERR(UDP_CSUM_ZERO) \ 53 ERR(TRUNCATED_IPV4) \ 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 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 typedef uint32_t TetherStatsKey; // upstream ifindex 77 78 typedef struct { 79 uint64_t rxPackets; 80 uint64_t rxBytes; 81 uint64_t rxErrors; 82 uint64_t txPackets; 83 uint64_t txBytes; 84 uint64_t txErrors; 85 } TetherStatsValue; 86 STRUCT_SIZE(TetherStatsValue, 6 * 8); // 48 87 88 typedef uint32_t TetherLimitKey; // upstream ifindex 89 typedef uint64_t TetherLimitValue; // in bytes 90 91 // For now tethering offload only needs to support downstreams that use 6-byte MAC addresses, 92 // because all downstream types that are currently supported (WiFi, USB, Bluetooth and 93 // Ethernet) have 6-byte MAC addresses. 94 95 typedef struct { 96 uint32_t iif; // The input interface index 97 uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress) 98 uint8_t zero[2]; // zero pad for 8 byte alignment 99 struct in6_addr neigh6; // The destination IPv6 address 100 } TetherDownstream6Key; 101 STRUCT_SIZE(TetherDownstream6Key, 4 + 6 + 2 + 16); // 28 102 103 typedef struct { 104 uint32_t oif; // The output interface to redirect to 105 struct ethhdr macHeader; // includes dst/src mac and ethertype (zeroed iff rawip egress) 106 uint16_t pmtu; // The maximum L3 output path/route mtu 107 } Tether6Value; 108 STRUCT_SIZE(Tether6Value, 4 + 14 + 2); // 20 109 110 typedef struct { 111 uint32_t iif; // The input interface index 112 uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress) 113 uint16_t l4Proto; // IPPROTO_TCP/UDP/... 114 struct in6_addr src6; // source & 115 struct in6_addr dst6; // destination IPv6 addresses 116 __be16 srcPort; // source & 117 __be16 dstPort; // destination tcp/udp/... ports 118 } TetherDownstream64Key; 119 STRUCT_SIZE(TetherDownstream64Key, 4 + 6 + 2 + 16 + 16 + 2 + 2); // 48 120 121 typedef struct { 122 uint32_t oif; // The output interface to redirect to 123 struct ethhdr macHeader; // includes dst/src mac and ethertype (zeroed iff rawip egress) 124 uint16_t pmtu; // The maximum L3 output path/route mtu 125 struct in_addr src4; // source & 126 struct in_addr dst4; // destination IPv4 addresses 127 __be16 srcPort; // source & 128 __be16 outPort; // destination tcp/udp/... ports 129 uint64_t lastUsed; // Kernel updates on each use with bpf_ktime_get_boot_ns() 130 } TetherDownstream64Value; 131 STRUCT_SIZE(TetherDownstream64Value, 4 + 14 + 2 + 4 + 4 + 2 + 2 + 8); // 40 132 133 typedef struct { 134 uint32_t iif; // The input interface index 135 uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress) 136 uint8_t zero[2]; // zero pad for 8 byte alignment 137 // TODO: extend this to include src ip /64 subnet 138 } TetherUpstream6Key; 139 STRUCT_SIZE(TetherUpstream6Key, 12); 140 141 typedef struct { 142 uint32_t iif; // The input interface index 143 uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress) 144 uint16_t l4Proto; // IPPROTO_TCP/UDP/... 145 struct in_addr src4; // source & 146 struct in_addr dst4; // destination IPv4 addresses 147 __be16 srcPort; // source & 148 __be16 dstPort; // destination TCP/UDP/... ports 149 } Tether4Key; 150 STRUCT_SIZE(Tether4Key, 4 + 6 + 2 + 4 + 4 + 2 + 2); // 24 151 152 typedef struct { 153 uint32_t oif; // The output interface to redirect to 154 struct ethhdr macHeader; // includes dst/src mac and ethertype (zeroed iff rawip egress) 155 uint16_t pmtu; // Maximum L3 output path/route mtu 156 struct in6_addr src46; // source & (always IPv4 mapped for downstream) 157 struct in6_addr dst46; // destination IP addresses (may be IPv4 mapped or IPv6 for upstream) 158 __be16 srcPort; // source & 159 __be16 dstPort; // destination tcp/udp/... ports 160 uint64_t last_used; // Kernel updates on each use with bpf_ktime_get_boot_ns() 161 } Tether4Value; 162 STRUCT_SIZE(Tether4Value, 4 + 14 + 2 + 16 + 16 + 2 + 2 + 8); // 64 163 164 #undef STRUCT_SIZE 165