github.com/datadog/cilium@v1.6.12/bpf/sockops/bpf_sockops.h (about) 1 /* 2 * Copyright (C) 2018-2019 Authors of Cilium 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include "sockops_config.h" 20 21 /* Structure representing an L7 sock */ 22 struct sock_key { 23 union { 24 struct { 25 __u32 sip4; 26 __u32 pad1; 27 __u32 pad2; 28 __u32 pad3; 29 }; 30 union v6addr sip6; 31 }; 32 union { 33 struct { 34 __u32 dip4; 35 __u32 pad4; 36 __u32 pad5; 37 __u32 pad6; 38 }; 39 union v6addr dip6; 40 }; 41 __u8 family; 42 __u8 pad7; 43 __u16 pad8; 44 __u32 sport; 45 __u32 dport; 46 } __attribute__((packed)); 47 48 struct bpf_elf_map __section_maps SOCK_OPS_MAP = { 49 .type = BPF_MAP_TYPE_SOCKHASH, 50 .size_key = sizeof(struct sock_key), 51 .size_value = sizeof(int), 52 .pinning = PIN_GLOBAL_NS, 53 .max_elem = SOCKOPS_MAP_SIZE, 54 }; 55 56 static __always_inline void sk_extract4_key(struct bpf_sock_ops *ops, 57 struct sock_key *key) 58 { 59 key->dip4 = ops->remote_ip4; 60 key->sip4 = ops->local_ip4; 61 key->family = ENDPOINT_KEY_IPV4; 62 63 key->sport = (bpf_ntohl(ops->local_port) >> 16); 64 /* clang-7.1 or higher seems to think it can do a 16-bit read here 65 * which unfortunately most kernels (as of October 2019) do not 66 * support, which leads to verifier failures. Insert a READ_ONCE 67 * to make sure that a 32-bit read followed by shift is generated. */ 68 key->dport = READ_ONCE(ops->remote_port) >> 16; 69 } 70 71 static __always_inline void sk_msg_extract4_key(struct sk_msg_md *msg, 72 struct sock_key *key) 73 { 74 key->dip4 = msg->remote_ip4; 75 key->sip4 = msg->local_ip4; 76 key->family = ENDPOINT_KEY_IPV4; 77 78 key->sport = (bpf_ntohl(msg->local_port) >> 16); 79 /* clang-7.1 or higher seems to think it can do a 16-bit read here 80 * which unfortunately most kernels (as of October 2019) do not 81 * support, which leads to verifier failures. Insert a READ_ONCE 82 * to make sure that a 32-bit read followed by shift is generated. */ 83 key->dport = READ_ONCE(msg->remote_port) >> 16; 84 } 85 86 static __always_inline void sk_lb4_key_v2(struct lb4_key_v2 *lb4, 87 struct sock_key *key) 88 { 89 /* SK MSG is always egress, so use daddr */ 90 lb4->address = key->dip4; 91 lb4->dport = key->dport; 92 } 93 94 static __always_inline bool redirect_to_proxy(int verdict) 95 { 96 return verdict > 0; 97 }