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