github.com/cilium/cilium@v1.16.2/bpf/lib/trace_sock.h (about) 1 /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ 2 /* Copyright Authors of Cilium */ 3 4 /* 5 * Socket based service load-balancing notification via perf event ring buffer. 6 * 7 * API: 8 * void send_trace_sock_notify(ctx, xlate_point, dst_ip, dst_port) 9 * 10 * @ctx: socket address structre 11 * @xlate_point: pre- or post- service translation point for load-balancing 12 * @dst_ip: pre- or post- service translation destination ip address 13 * @dst_port: pre- or post- service translation destination port 14 * 15 * If TRACE_SOCK_NOTIFY is not defined, the API will be compiled in as a NOP. 16 */ 17 #pragma once 18 19 #include <bpf/ctx/sock.h> 20 21 #include "common.h" 22 #include "events.h" 23 24 /* L4 protocol for the trace event */ 25 enum l4_protocol { 26 L4_PROTOCOL_UNKNOWN = 0, 27 L4_PROTOCOL_TCP = 1, 28 L4_PROTOCOL_UDP = 2, 29 } __packed; 30 31 /* Direction for translation between service and backend IP */ 32 enum xlate_point { 33 XLATE_UNKNOWN = 0, 34 XLATE_PRE_DIRECTION_FWD = 1, /* Pre service forward translation */ 35 XLATE_POST_DIRECTION_FWD = 2, /* Post service forward translation */ 36 XLATE_PRE_DIRECTION_REV = 3, /* Pre reverse service translation */ 37 XLATE_POST_DIRECTION_REV = 4, /* Post reverse service translation */ 38 } __packed; 39 40 struct ip { 41 union { 42 struct { 43 __be32 ip4; 44 __u32 pad1; 45 __u32 pad2; 46 __u32 pad3; 47 }; 48 union v6addr ip6; 49 } __packed; 50 }; 51 52 #ifdef TRACE_SOCK_NOTIFY 53 struct trace_sock_notify { 54 __u8 type; 55 __u8 xlate_point; 56 struct ip dst_ip; 57 __u16 dst_port; 58 __u64 sock_cookie; 59 __u64 cgroup_id; 60 __u8 l4_proto; 61 __u8 ipv6 : 1; 62 __u8 pad : 7; 63 } __packed; 64 65 static __always_inline enum l4_protocol 66 parse_protocol(__u32 l4_proto) { 67 switch (l4_proto) { 68 case IPPROTO_TCP: 69 return L4_PROTOCOL_TCP; 70 case IPPROTO_UDP: 71 return L4_PROTOCOL_UDP; 72 default: 73 return L4_PROTOCOL_UNKNOWN; 74 } 75 } 76 77 static __always_inline void 78 send_trace_sock_notify4(struct __ctx_sock *ctx, 79 enum xlate_point xlate_point, 80 __u32 dst_ip, __u16 dst_port) 81 { 82 __u64 cgroup_id = 0; 83 struct trace_sock_notify msg __align_stack_8; 84 85 if (is_defined(HAVE_CGROUP_ID)) 86 cgroup_id = get_current_cgroup_id(); 87 88 msg = (typeof(msg)){ 89 .type = CILIUM_NOTIFY_TRACE_SOCK, 90 .xlate_point = xlate_point, 91 .dst_ip.ip4 = dst_ip, 92 .dst_port = dst_port, 93 .sock_cookie = sock_local_cookie(ctx), 94 .cgroup_id = cgroup_id, 95 .l4_proto = parse_protocol(ctx->protocol), 96 .ipv6 = 0, 97 }; 98 99 ctx_event_output(ctx, &EVENTS_MAP, BPF_F_CURRENT_CPU, &msg, sizeof(msg)); 100 } 101 102 static __always_inline void 103 send_trace_sock_notify6(struct __ctx_sock *ctx, 104 enum xlate_point xlate_point, 105 union v6addr *dst_addr, 106 __u16 dst_port) 107 { 108 __u64 cgroup_id = 0; 109 struct trace_sock_notify msg __align_stack_8; 110 111 if (is_defined(HAVE_CGROUP_ID)) 112 cgroup_id = get_current_cgroup_id(); 113 msg = (typeof(msg)){ 114 .type = CILIUM_NOTIFY_TRACE_SOCK, 115 .xlate_point = xlate_point, 116 .dst_port = dst_port, 117 .sock_cookie = sock_local_cookie(ctx), 118 .cgroup_id = cgroup_id, 119 .l4_proto = parse_protocol(ctx->protocol), 120 .ipv6 = 1, 121 }; 122 ipv6_addr_copy_unaligned(&msg.dst_ip.ip6, dst_addr); 123 124 ctx_event_output(ctx, &EVENTS_MAP, BPF_F_CURRENT_CPU, &msg, sizeof(msg)); 125 } 126 #else 127 static __always_inline void 128 send_trace_sock_notify4(struct __ctx_sock *ctx __maybe_unused, 129 enum xlate_point xlate_point __maybe_unused, 130 __u32 dst_ip __maybe_unused, __u16 dst_port __maybe_unused) 131 { 132 } 133 134 static __always_inline void 135 send_trace_sock_notify6(struct __ctx_sock *ctx __maybe_unused, 136 enum xlate_point xlate_point __maybe_unused, 137 union v6addr *dst_addr __maybe_unused, 138 __u16 dst_port __maybe_unused) 139 { 140 } 141 #endif /* TRACE_SOCK_NOTIFY */