diff --git a/bpf/go_common.h b/bpf/go_common.h index 8300aacf7..34925fc2a 100644 --- a/bpf/go_common.h +++ b/bpf/go_common.h @@ -78,19 +78,23 @@ static __always_inline u64 find_parent_goroutine(void *goroutine_addr) { return 0; } -static __always_inline void decode_go_traceparent(unsigned char *buf, unsigned char *trace_id, unsigned char *span_id) { +static __always_inline void decode_go_traceparent(unsigned char *buf, unsigned char *trace_id, unsigned char *span_id, unsigned char *flags) { unsigned char *t_id = buf + 2 + 1; // strlen(ver) + strlen("-") unsigned char *s_id = buf + 2 + 1 + 32 + 1; // strlen(ver) + strlen("-") + strlen(trace_id) + strlen("-") + unsigned char *f_id = buf + 2 + 1 + 32 + 1 + 16 + 1; // strlen(ver) + strlen("-") + strlen(trace_id) + strlen("-") + strlen(span_id) + strlen("-") decode_hex(trace_id, t_id, TRACE_ID_CHAR_LEN); decode_hex(span_id, s_id, SPAN_ID_CHAR_LEN); + decode_hex(flags, f_id, FLAGS_CHAR_LEN); } static __always_inline void server_trace_parent(void *goroutine_addr, tp_info_t *tp, void *req_header) { + // May get overriden when decoding existing traceparent, but otherwise we set sample ON + tp->flags = 1; // Get traceparent from the Request.Header void *traceparent_ptr = extract_traceparent_from_req_headers(req_header); if (traceparent_ptr != NULL) { - unsigned char buf[W3C_VAL_LENGTH]; + unsigned char buf[TP_MAX_VAL_LENGTH]; long res = bpf_probe_read(buf, sizeof(buf), traceparent_ptr); if (res < 0) { bpf_dbg_printk("can't copy traceparent header"); @@ -98,7 +102,7 @@ static __always_inline void server_trace_parent(void *goroutine_addr, tp_info_t *((u64 *)tp->parent_id) = 0; } else { bpf_dbg_printk("Decoding traceparent from headers %s", buf); - decode_go_traceparent(buf, tp->trace_id, tp->parent_id); + decode_go_traceparent(buf, tp->trace_id, tp->parent_id, &tp->flags); } } else { bpf_dbg_printk("No traceparent in headers, generating"); @@ -110,20 +114,25 @@ static __always_inline void server_trace_parent(void *goroutine_addr, tp_info_t bpf_map_update_elem(&go_trace_map, &goroutine_addr, tp, BPF_ANY); } -static __always_inline void client_trace_parent(void *goroutine_addr, tp_info_t *tp_i, void *req_header) { +static __always_inline u8 client_trace_parent(void *goroutine_addr, tp_info_t *tp_i, void *req_header) { // Get traceparent from the Request.Header u8 found_trace_id = 0; + u8 trace_id_exists = 0; + // May get overriden when decoding existing traceparent or finding a server span, but otherwise we set sample ON + tp_i->flags = 1; + if (req_header) { void *traceparent_ptr = extract_traceparent_from_req_headers(req_header); if (traceparent_ptr != NULL) { unsigned char buf[W3C_VAL_LENGTH]; + trace_id_exists = 1; long res = bpf_probe_read(buf, sizeof(buf), traceparent_ptr); if (res < 0) { bpf_dbg_printk("can't copy traceparent header"); } else { found_trace_id = 1; - decode_go_traceparent(buf, tp_i->trace_id, tp_i->span_id); + decode_go_traceparent(buf, tp_i->trace_id, tp_i->span_id, &tp_i->flags); } } } @@ -142,12 +151,15 @@ static __always_inline void client_trace_parent(void *goroutine_addr, tp_info_t *((u64 *)tp_i->trace_id) = *((u64 *)tp->trace_id); *((u64 *)(tp_i->trace_id + 8)) = *((u64 *)(tp->trace_id + 8)); *((u64 *)tp_i->parent_id) = *((u64 *)tp->span_id); + tp_i->flags = tp->flags; } else { urand_bytes(tp_i->trace_id, TRACE_ID_SIZE_BYTES); } urand_bytes(tp_i->span_id, SPAN_ID_SIZE_BYTES); } + + return trace_id_exists; } diff --git a/bpf/go_nethttp.c b/bpf/go_nethttp.c index 28f511963..ba6fac22e 100644 --- a/bpf/go_nethttp.c +++ b/bpf/go_nethttp.c @@ -61,6 +61,8 @@ int uprobe_ServeHTTP(struct pt_regs *ctx) { if (req) { server_trace_parent(goroutine_addr, &invocation.tp, (void*)(req + req_header_ptr_pos)); + // TODO: if context propagation is supported, overwrite the header value in the map with the + // new span context and the same thread id. } // Write event @@ -193,6 +195,16 @@ int uprobe_WriteHeader(struct pt_regs *ctx) { return 0; } +#ifndef NO_HEADER_PROPAGATION +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __type(key, void *); // key: pointer to the request header map + __type(value, u64); // the goroutine of the transport request + __uint(max_entries, MAX_CONCURRENT_REQUESTS); +} header_req_map SEC(".maps"); + +#endif + /* HTTP Client. We expect to see HTTP client in both HTTP server and gRPC server calls.*/ SEC("uprobe/roundTrip") @@ -210,13 +222,25 @@ int uprobe_roundTrip(struct pt_regs *ctx) { .tp = {0} }; - client_trace_parent(goroutine_addr, &invocation.tp, (void*)(req + req_header_ptr_pos)); + __attribute__((__unused__)) u8 existing_tp = client_trace_parent(goroutine_addr, &invocation.tp, (void*)(req + req_header_ptr_pos)); // Write event if (bpf_map_update_elem(&ongoing_http_client_requests, &goroutine_addr, &invocation, BPF_ANY)) { bpf_dbg_printk("can't update http client map element"); } +#ifndef NO_HEADER_PROPAGATION + if (!existing_tp) { + void *headers_ptr = 0; + bpf_probe_read(&headers_ptr, sizeof(headers_ptr), (void*)(req + req_header_ptr_pos)); + bpf_dbg_printk("goroutine_addr %lx, req ptr %llx, headers_ptr %llx", goroutine_addr, req, headers_ptr); + + if (headers_ptr) { + bpf_map_update_elem(&header_req_map, &headers_ptr, &goroutine_addr, BPF_ANY); + } + } +#endif + return 0; } @@ -290,3 +314,68 @@ int uprobe_roundTripReturn(struct pt_regs *ctx) { return 0; } + +#ifndef NO_HEADER_PROPAGATION +// Context propagation through HTTP headers +SEC("uprobe/header_writeSubset") +int uprobe_writeSubset(struct pt_regs *ctx) { + bpf_dbg_printk("=== uprobe/proc header writeSubset === "); + + void *header_addr = GO_PARAM1(ctx); + void *io_writer_addr = GO_PARAM3(ctx); + + bpf_dbg_printk("goroutine_addr %lx, header ptr %llx", GOROUTINE_PTR(ctx), header_addr); + + u64 *request_goaddr = bpf_map_lookup_elem(&header_req_map, &header_addr); + + if (!request_goaddr) { + bpf_dbg_printk("Can't find parent go routine for header %llx", header_addr); + return 0; + } + + u64 parent_goaddr = *request_goaddr; + + http_func_invocation_t *func_inv = bpf_map_lookup_elem(&ongoing_http_client_requests, &parent_goaddr); + if (!func_inv) { + bpf_dbg_printk("Can't find client request for goroutine %llx", parent_goaddr); + return 0; + } + + unsigned char buf[TRACEPARENT_LEN]; + + make_tp_string(buf, &func_inv->tp); + + void *buf_ptr = 0; + bpf_probe_read(&buf_ptr, sizeof(buf_ptr), (void *)(io_writer_addr + io_writer_buf_ptr_pos)); + if (!buf_ptr) { + return 0; + } + + s64 size = 0; + bpf_probe_read(&size, sizeof(s64), (void *)(io_writer_addr + io_writer_buf_ptr_pos + 8)); // grab size + + s64 len = 0; + bpf_probe_read(&len, sizeof(s64), (void *)(io_writer_addr + io_writer_n_pos)); // grab len + + bpf_dbg_printk("buf_ptr %llx, len=%d, size=%d", (void*)buf_ptr, len, size); + + if (len < (size - TP_MAX_VAL_LENGTH - TP_MAX_KEY_LENGTH - 4)) { // 4 = strlen(":_") + strlen("\r\n") + char key[TP_MAX_KEY_LENGTH + 2] = "Traceparent: "; + char end[2] = "\r\n"; + bpf_probe_write_user(buf_ptr + (len & 0x0ffff), key, sizeof(key)); + len += TP_MAX_KEY_LENGTH + 2; + bpf_probe_write_user(buf_ptr + (len & 0x0ffff), buf, sizeof(buf)); + len += TP_MAX_VAL_LENGTH; + bpf_probe_write_user(buf_ptr + (len & 0x0ffff), end, sizeof(end)); + len += 2; + bpf_probe_write_user((void *)(io_writer_addr + io_writer_n_pos), &len, sizeof(len)); + } + + return 0; +} +#else +SEC("uprobe/header_writeSubset") +int uprobe_writeSubset(struct pt_regs *ctx) { + return 0; +} +#endif \ No newline at end of file diff --git a/bpf/go_nethttp.h b/bpf/go_nethttp.h index 3d000dd7c..18c29b474 100644 --- a/bpf/go_nethttp.h +++ b/bpf/go_nethttp.h @@ -27,5 +27,7 @@ volatile const u64 host_ptr_pos; volatile const u64 content_length_ptr_pos; volatile const u64 resp_req_pos; volatile const u64 req_header_ptr_pos; +volatile const u64 io_writer_buf_ptr_pos; +volatile const u64 io_writer_n_pos; #endif diff --git a/bpf/trace_common.h b/bpf/trace_common.h index a691e105e..dfdab0912 100644 --- a/bpf/trace_common.h +++ b/bpf/trace_common.h @@ -97,6 +97,10 @@ static __always_inline unsigned char *extract_span_id(unsigned char *tp_start) { return tp_start + 13 + 2 + 1 + 32 + 1; // strlen("Traceparent: ") + strlen(ver) + strlen("-") + strlen(trace_id) + strlen("-") } +static __always_inline unsigned char *extract_flags(unsigned char *tp_start) { + return tp_start + 13 + 2 + 1 + 32 + 1 + 16 + 1; // strlen("Traceparent: ") + strlen(ver) + strlen("-") + strlen(trace_id) + strlen("-") + strlen(span_id) + strlen("-") +} + static __always_inline u64 current_epoch() { u64 ts = bpf_ktime_get_ns(); u64 temp = ts / NANOSECONDS_PER_EPOCH; @@ -122,6 +126,7 @@ static __always_inline void get_or_create_trace_info(http_connection_metadata_t } tp->epoch = current_epoch(); + tp->flags = 1; urand_bytes(tp->span_id, SPAN_ID_SIZE_BYTES); bpf_memset(tp->parent_id, 0, sizeof(tp->span_id)); @@ -151,8 +156,10 @@ static __always_inline void get_or_create_trace_info(http_connection_metadata_t bpf_dbg_printk("Found traceparent %s", res); unsigned char *t_id = extract_trace_id(res); unsigned char *s_id = extract_span_id(res); + unsigned char *f_id = extract_flags(res); decode_hex(tp->trace_id, t_id, TRACE_ID_CHAR_LEN); + decode_hex((unsigned char *)&tp->flags, f_id, FLAGS_CHAR_LEN); if (meta && meta->type == EVENT_HTTP_CLIENT) { decode_hex(tp->span_id, s_id, SPAN_ID_CHAR_LEN); } else { diff --git a/bpf/trace_util.h b/bpf/trace_util.h index 4524c7131..a6091bf6b 100644 --- a/bpf/trace_util.h +++ b/bpf/trace_util.h @@ -1,8 +1,6 @@ #ifndef TRACE_UTIL_H #define TRACE_UTIL_H -#include "utils.h" - // 55+13 #define TRACE_PARENT_HEADER_LEN 68 diff --git a/bpf/tracing.h b/bpf/tracing.h index 9354a4a79..43bd98bb1 100644 --- a/bpf/tracing.h +++ b/bpf/tracing.h @@ -1,18 +1,41 @@ #ifndef TRACING_H #define TRACING_H #include "vmlinux.h" +#include "trace_util.h" #define TRACE_ID_SIZE_BYTES 16 #define SPAN_ID_SIZE_BYTES 8 +#define FLAGS_SIZE_BYTES 1 #define TRACE_ID_CHAR_LEN 32 #define SPAN_ID_CHAR_LEN 16 +#define FLAGS_CHAR_LEN 2 #define TP_MAX_VAL_LENGTH 55 +#define TP_MAX_KEY_LENGTH 11 typedef struct tp_info { unsigned char trace_id[TRACE_ID_SIZE_BYTES]; unsigned char span_id[SPAN_ID_SIZE_BYTES]; unsigned char parent_id[SPAN_ID_SIZE_BYTES]; u64 epoch; + u8 flags; } tp_info_t; +static __always_inline void make_tp_string(unsigned char *buf, tp_info_t *tp) { + // Version + *buf++ = '0'; *buf++ = '0'; *buf++ = '-'; + + // TraceID + encode_hex(buf, tp->trace_id, TRACE_ID_SIZE_BYTES); + buf += TRACE_ID_CHAR_LEN; + *buf++ = '-'; + + // SpanID + encode_hex(buf, tp->span_id, SPAN_ID_SIZE_BYTES); + buf += SPAN_ID_CHAR_LEN; + *buf++ = '-'; + + // Flags + *buf++ = '0'; *buf = (tp->flags == 0) ? '0' : '1'; +} + #endif \ No newline at end of file diff --git a/configs/offsets/tracker_input.json b/configs/offsets/tracker_input.json index 59171e1db..325428a8e 100644 --- a/configs/offsets/tracker_input.json +++ b/configs/offsets/tracker_input.json @@ -27,6 +27,10 @@ ], "context.valueCtx": [ "val" + ], + "bufio.Writer": [ + "buf", + "n" ] } }, diff --git a/examples/greeting-apps/docker-compose.yaml b/examples/greeting-apps/docker-compose.yaml index e1141dfff..36e8fa1f1 100644 --- a/examples/greeting-apps/docker-compose.yaml +++ b/examples/greeting-apps/docker-compose.yaml @@ -86,6 +86,7 @@ services: - --config=/configs/beyla-config.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security container_name: demo-javabeyla privileged: true network_mode: "service:javatestserver" diff --git a/examples/greeting-apps/system/sys/kernel/security/lockdown b/examples/greeting-apps/system/sys/kernel/security/lockdown new file mode 100644 index 000000000..2473d0d89 --- /dev/null +++ b/examples/greeting-apps/system/sys/kernel/security/lockdown @@ -0,0 +1 @@ +none [integrity] confidentiality \ No newline at end of file diff --git a/pkg/internal/ebpf/common/bpf_bpfel_arm64.go b/pkg/internal/ebpf/common/bpf_bpfel_arm64.go index e514c0f5a..34625ca3a 100644 --- a/pkg/internal/ebpf/common/bpf_bpfel_arm64.go +++ b/pkg/internal/ebpf/common/bpf_bpfel_arm64.go @@ -32,6 +32,8 @@ type bpfHttpRequestTrace struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } Pid struct { HostPid uint32 @@ -56,6 +58,8 @@ type bpfSqlRequestTrace struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } Pid struct { HostPid uint32 diff --git a/pkg/internal/ebpf/common/bpf_bpfel_arm64.o b/pkg/internal/ebpf/common/bpf_bpfel_arm64.o index 2de6144da..fbc477afc 100644 Binary files a/pkg/internal/ebpf/common/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/common/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/common/bpf_bpfel_x86.go b/pkg/internal/ebpf/common/bpf_bpfel_x86.go index e421a28cd..03f2814af 100644 --- a/pkg/internal/ebpf/common/bpf_bpfel_x86.go +++ b/pkg/internal/ebpf/common/bpf_bpfel_x86.go @@ -32,6 +32,8 @@ type bpfHttpRequestTrace struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } Pid struct { HostPid uint32 @@ -56,6 +58,8 @@ type bpfSqlRequestTrace struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } Pid struct { HostPid uint32 diff --git a/pkg/internal/ebpf/common/bpf_bpfel_x86.o b/pkg/internal/ebpf/common/bpf_bpfel_x86.o index 2de6144da..fbc477afc 100644 Binary files a/pkg/internal/ebpf/common/bpf_bpfel_x86.o and b/pkg/internal/ebpf/common/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/common/spanner.go b/pkg/internal/ebpf/common/spanner.go index cfe1a01af..2c71622e1 100644 --- a/pkg/internal/ebpf/common/spanner.go +++ b/pkg/internal/ebpf/common/spanner.go @@ -60,6 +60,7 @@ func HTTPRequestTraceToSpan(trace *HTTPRequestTrace) request.Span { TraceID: trace2.TraceID(trace.Tp.TraceId), SpanID: trace2.SpanID(trace.Tp.SpanId), ParentSpanID: trace2.SpanID(trace.Tp.ParentId), + Flags: trace.Tp.Flags, Pid: request.PidInfo{ HostPID: trace.Pid.HostPid, UserPID: trace.Pid.UserPid, @@ -98,6 +99,7 @@ func SQLRequestTraceToSpan(trace *SQLRequestTrace) request.Span { TraceID: trace2.TraceID(trace.Tp.TraceId), SpanID: trace2.SpanID(trace.Tp.SpanId), ParentSpanID: trace2.SpanID(trace.Tp.ParentId), + Flags: trace.Tp.Flags, Pid: request.PidInfo{ HostPID: trace.Pid.HostPid, UserPID: trace.Pid.UserPid, diff --git a/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.go b/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.go index 7ee36fdad..b5ac31f97 100644 --- a/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.go +++ b/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.go @@ -30,6 +30,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.o b/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.o index 8eebae451..e7c7d628c 100644 Binary files a/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/goruntime/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.go b/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.go index e48204e2f..3bd724076 100644 --- a/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.go +++ b/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.go @@ -30,6 +30,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.o b/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.o index 299fa4480..059d44287 100644 Binary files a/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.o and b/pkg/internal/ebpf/goruntime/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.go b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.go index 15a826925..0f778121a 100644 --- a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.go @@ -30,6 +30,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.o index 6d1652b3d..9ba3ccbf6 100644 Binary files a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.go b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.go index 79053fb71..d05dafa28 100644 --- a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.go @@ -30,6 +30,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.o index 0f5d16815..01aa38a71 100644 Binary files a/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/goruntime/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/gosql/bpf_bpfel_arm64.o b/pkg/internal/ebpf/gosql/bpf_bpfel_arm64.o index 41b63a17c..0335b85f2 100644 Binary files a/pkg/internal/ebpf/gosql/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/gosql/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/gosql/bpf_bpfel_x86.o b/pkg/internal/ebpf/gosql/bpf_bpfel_x86.o index b5faf791a..c70ead2b5 100644 Binary files a/pkg/internal/ebpf/gosql/bpf_bpfel_x86.o and b/pkg/internal/ebpf/gosql/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/gosql/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/gosql/bpf_debug_bpfel_arm64.o index c934548e8..576c36099 100644 Binary files a/pkg/internal/ebpf/gosql/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/gosql/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/gosql/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/gosql/bpf_debug_bpfel_x86.o index 0101ed50d..efd76956e 100644 Binary files a/pkg/internal/ebpf/gosql/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/gosql/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.go b/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.go index fae512bf3..bdf73c016 100644 --- a/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.go +++ b/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.go @@ -42,6 +42,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.o b/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.o index 8cbcd1f4c..cebd8a29e 100644 Binary files a/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/grpc/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/grpc/bpf_bpfel_x86.go b/pkg/internal/ebpf/grpc/bpf_bpfel_x86.go index 9a66a0765..f9c6809d2 100644 --- a/pkg/internal/ebpf/grpc/bpf_bpfel_x86.go +++ b/pkg/internal/ebpf/grpc/bpf_bpfel_x86.go @@ -42,6 +42,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/grpc/bpf_bpfel_x86.o b/pkg/internal/ebpf/grpc/bpf_bpfel_x86.o index 50729f648..e027006d0 100644 Binary files a/pkg/internal/ebpf/grpc/bpf_bpfel_x86.o and b/pkg/internal/ebpf/grpc/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.go b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.go index 92c032b00..4b681f4d8 100644 --- a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.go @@ -42,6 +42,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.o index 7c2a6f078..ea5f6dd1c 100644 Binary files a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.go b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.go index 73e4fd451..710a74b40 100644 --- a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.go @@ -42,6 +42,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.o index 086f7985c..1579885d9 100644 Binary files a/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/grpc/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.go b/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.go index e0e8b174e..161602208 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.go @@ -82,6 +82,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.o b/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.o index da9a0984f..b5c830f35 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/httpfltr/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.go b/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.go index f3da58399..a3310e306 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.go +++ b/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.go @@ -82,6 +82,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.o b/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.o index a0371abee..a58edd79b 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.o and b/pkg/internal/ebpf/httpfltr/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.go b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.go index 9ea553e3f..9b951f3e0 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.go @@ -82,6 +82,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.o index accb19b3d..a0be41bc2 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.go b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.go index e1e351274..0b8636d42 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.go @@ -82,6 +82,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.o index db82d2df8..4d58e779c 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/httpfltr/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.go b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.go index 8903be960..aad17b612 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.go @@ -82,6 +82,8 @@ type bpf_tpTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.o b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.o index 8dd829754..77facf50f 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.go b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.go index bd1dfc882..835a71259 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.go @@ -82,6 +82,8 @@ type bpf_tpTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.o b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.o index 29c058620..e99fd30b9 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.go b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.go index 532a7f59e..565dc6884 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.go @@ -82,6 +82,8 @@ type bpf_tp_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.o b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.o index 5bbdc0831..c0fdaf960 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.go b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.go index 9362b94b7..581a76639 100644 --- a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.go @@ -82,6 +82,8 @@ type bpf_tp_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. diff --git a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.o b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.o index 622f25ec5..89bae9921 100644 Binary files a/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.o and b/pkg/internal/ebpf/httpfltr/bpf_tp_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpfltr/httpfltr_transform.go b/pkg/internal/ebpf/httpfltr/httpfltr_transform.go index d64293b1a..cdb2da49e 100644 --- a/pkg/internal/ebpf/httpfltr/httpfltr_transform.go +++ b/pkg/internal/ebpf/httpfltr/httpfltr_transform.go @@ -26,6 +26,7 @@ func httpInfoToSpan(info *HTTPInfo) request.Span { TraceID: trace.TraceID(info.Tp.TraceId), SpanID: trace.SpanID(info.Tp.SpanId), ParentSpanID: trace.SpanID(info.Tp.ParentId), + Flags: info.Tp.Flags, Pid: request.PidInfo{ HostPID: info.Pid.HostPid, UserPID: info.Pid.UserPid, diff --git a/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.go b/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.go index 346bb411b..271be2c0d 100644 --- a/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.go @@ -72,6 +72,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.o b/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.o index bce1773aa..35e4dd872 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/httpssl/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.go b/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.go index ee855b1ab..8b2bde921 100644 --- a/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.go +++ b/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.go @@ -72,6 +72,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. diff --git a/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.o b/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.o index 7e23ad232..588ba4085 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.o and b/pkg/internal/ebpf/httpssl/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.go b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.go index e399a32eb..5482d67d2 100644 --- a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.go @@ -72,6 +72,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.o index fa10b1633..d81404ea4 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.go b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.go index 67448ed6e..1dcd4d493 100644 --- a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.go @@ -72,6 +72,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. diff --git a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.o index 84fd592b8..f781f0d05 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/httpssl/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.go b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.go index 2527b3411..f26bb248a 100644 --- a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.go @@ -72,6 +72,8 @@ type bpf_tpTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.o b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.o index 0e0416010..9113f6db7 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.o and b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.go b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.go index b5135d592..badec0e70 100644 --- a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.go +++ b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.go @@ -72,6 +72,8 @@ type bpf_tpTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp returns the embedded CollectionSpec for bpf_tp. diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.o b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.o index 2dccb8a68..fabc44703 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.o and b/pkg/internal/ebpf/httpssl/bpf_tp_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.go b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.go index 2972a121c..8ed88254a 100644 --- a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.go @@ -72,6 +72,8 @@ type bpf_tp_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.o b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.o index 7dfc4a355..b91d441e7 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.o and b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.go b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.go index 7e6d4557f..9883fb0cf 100644 --- a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.go @@ -72,6 +72,8 @@ type bpf_tp_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. diff --git a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.o b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.o index 6d467124e..f7d4e9090 100644 Binary files a/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.o and b/pkg/internal/ebpf/httpssl/bpf_tp_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.go b/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.go index a3c83c849..efdaedfef 100644 --- a/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.go +++ b/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.go @@ -34,6 +34,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. @@ -82,6 +84,7 @@ type bpfProgramSpecs struct { UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` } // bpfMapSpecs contains maps before they are loaded into the kernel. @@ -149,6 +152,7 @@ type bpfPrograms struct { UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` } func (p *bpfPrograms) Close() error { @@ -158,6 +162,7 @@ func (p *bpfPrograms) Close() error { p.UprobeReadRequestReturns, p.UprobeRoundTrip, p.UprobeRoundTripReturn, + p.UprobeWriteSubset, ) } diff --git a/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.o b/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.o index 3f06d3a56..6f0145c69 100644 Binary files a/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/nethttp/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.go b/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.go index 4ed98e514..5692ee648 100644 --- a/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.go +++ b/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.go @@ -34,6 +34,8 @@ type bpfTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf returns the embedded CollectionSpec for bpf. @@ -82,6 +84,7 @@ type bpfProgramSpecs struct { UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` } // bpfMapSpecs contains maps before they are loaded into the kernel. @@ -149,6 +152,7 @@ type bpfPrograms struct { UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` } func (p *bpfPrograms) Close() error { @@ -158,6 +162,7 @@ func (p *bpfPrograms) Close() error { p.UprobeReadRequestReturns, p.UprobeRoundTrip, p.UprobeRoundTripReturn, + p.UprobeWriteSubset, ) } diff --git a/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.o b/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.o index a1d39691a..3f55ca0df 100644 Binary files a/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.o and b/pkg/internal/ebpf/nethttp/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.go b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.go index 7c4244856..408b59267 100644 --- a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.go +++ b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.go @@ -34,6 +34,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. @@ -82,6 +84,7 @@ type bpf_debugProgramSpecs struct { UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` } // bpf_debugMapSpecs contains maps before they are loaded into the kernel. @@ -149,6 +152,7 @@ type bpf_debugPrograms struct { UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` } func (p *bpf_debugPrograms) Close() error { @@ -158,6 +162,7 @@ func (p *bpf_debugPrograms) Close() error { p.UprobeReadRequestReturns, p.UprobeRoundTrip, p.UprobeRoundTripReturn, + p.UprobeWriteSubset, ) } diff --git a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.o index ac6f48e7c..e49e66f20 100644 Binary files a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.go b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.go index d3748a6d4..0d5cb0e16 100644 --- a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.go +++ b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.go @@ -34,6 +34,8 @@ type bpf_debugTpInfoT struct { SpanId [8]uint8 ParentId [8]uint8 Epoch uint64 + Flags uint8 + _ [7]byte } // loadBpf_debug returns the embedded CollectionSpec for bpf_debug. @@ -82,6 +84,7 @@ type bpf_debugProgramSpecs struct { UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` } // bpf_debugMapSpecs contains maps before they are loaded into the kernel. @@ -149,6 +152,7 @@ type bpf_debugPrograms struct { UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` } func (p *bpf_debugPrograms) Close() error { @@ -158,6 +162,7 @@ func (p *bpf_debugPrograms) Close() error { p.UprobeReadRequestReturns, p.UprobeRoundTrip, p.UprobeRoundTripReturn, + p.UprobeWriteSubset, ) } diff --git a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.o index 8b1846ce5..7c9bbb1e5 100644 Binary files a/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/nethttp/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.go b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.go new file mode 100644 index 000000000..0425c819a --- /dev/null +++ b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.go @@ -0,0 +1,184 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build arm64 +// +build arm64 + +package nethttp + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +type bpf_tpGoroutineMetadata struct { + Parent uint64 + Timestamp uint64 +} + +type bpf_tpHttpFuncInvocationT struct { + StartMonotimeNs uint64 + ReqPtr uint64 + Tp bpf_tpTpInfoT +} + +type bpf_tpPidKeyT struct { + Pid uint32 + Namespace uint32 +} + +type bpf_tpTpInfoT struct { + TraceId [16]uint8 + SpanId [8]uint8 + ParentId [8]uint8 + Epoch uint64 + Flags uint8 + _ [7]byte +} + +// loadBpf_tp returns the embedded CollectionSpec for bpf_tp. +func loadBpf_tp() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_Bpf_tpBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf_tp: %w", err) + } + + return spec, err +} + +// loadBpf_tpObjects loads bpf_tp and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpf_tpObjects +// *bpf_tpPrograms +// *bpf_tpMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpf_tpObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf_tp() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpf_tpSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tpSpecs struct { + bpf_tpProgramSpecs + bpf_tpMapSpecs +} + +// bpf_tpSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tpProgramSpecs struct { + UprobeServeHTTP *ebpf.ProgramSpec `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.ProgramSpec `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` +} + +// bpf_tpMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tpMapSpecs struct { + Events *ebpf.MapSpec `ebpf:"events"` + GoTraceMap *ebpf.MapSpec `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.MapSpec `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.MapSpec `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.MapSpec `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.MapSpec `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.MapSpec `ebpf:"pid_cache"` + ValidPids *ebpf.MapSpec `ebpf:"valid_pids"` +} + +// bpf_tpObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tpObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tpObjects struct { + bpf_tpPrograms + bpf_tpMaps +} + +func (o *bpf_tpObjects) Close() error { + return _Bpf_tpClose( + &o.bpf_tpPrograms, + &o.bpf_tpMaps, + ) +} + +// bpf_tpMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tpObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tpMaps struct { + Events *ebpf.Map `ebpf:"events"` + GoTraceMap *ebpf.Map `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.Map `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.Map `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.Map `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.Map `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.Map `ebpf:"pid_cache"` + ValidPids *ebpf.Map `ebpf:"valid_pids"` +} + +func (m *bpf_tpMaps) Close() error { + return _Bpf_tpClose( + m.Events, + m.GoTraceMap, + m.GolangMapbucketStorageMap, + m.HeaderReqMap, + m.OngoingGoroutines, + m.OngoingHttpClientRequests, + m.OngoingHttpServerRequests, + m.PidCache, + m.ValidPids, + ) +} + +// bpf_tpPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tpObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tpPrograms struct { + UprobeServeHTTP *ebpf.Program `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.Program `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` +} + +func (p *bpf_tpPrograms) Close() error { + return _Bpf_tpClose( + p.UprobeServeHTTP, + p.UprobeWriteHeader, + p.UprobeReadRequestReturns, + p.UprobeRoundTrip, + p.UprobeRoundTripReturn, + p.UprobeWriteSubset, + ) +} + +func _Bpf_tpClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +// +//go:embed bpf_tp_bpfel_arm64.o +var _Bpf_tpBytes []byte diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.o b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.o new file mode 100644 index 000000000..1e12da133 Binary files /dev/null and b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.go b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.go new file mode 100644 index 000000000..f071914ce --- /dev/null +++ b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.go @@ -0,0 +1,184 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build 386 || amd64 +// +build 386 amd64 + +package nethttp + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +type bpf_tpGoroutineMetadata struct { + Parent uint64 + Timestamp uint64 +} + +type bpf_tpHttpFuncInvocationT struct { + StartMonotimeNs uint64 + ReqPtr uint64 + Tp bpf_tpTpInfoT +} + +type bpf_tpPidKeyT struct { + Pid uint32 + Namespace uint32 +} + +type bpf_tpTpInfoT struct { + TraceId [16]uint8 + SpanId [8]uint8 + ParentId [8]uint8 + Epoch uint64 + Flags uint8 + _ [7]byte +} + +// loadBpf_tp returns the embedded CollectionSpec for bpf_tp. +func loadBpf_tp() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_Bpf_tpBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf_tp: %w", err) + } + + return spec, err +} + +// loadBpf_tpObjects loads bpf_tp and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpf_tpObjects +// *bpf_tpPrograms +// *bpf_tpMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpf_tpObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf_tp() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpf_tpSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tpSpecs struct { + bpf_tpProgramSpecs + bpf_tpMapSpecs +} + +// bpf_tpSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tpProgramSpecs struct { + UprobeServeHTTP *ebpf.ProgramSpec `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.ProgramSpec `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` +} + +// bpf_tpMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tpMapSpecs struct { + Events *ebpf.MapSpec `ebpf:"events"` + GoTraceMap *ebpf.MapSpec `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.MapSpec `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.MapSpec `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.MapSpec `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.MapSpec `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.MapSpec `ebpf:"pid_cache"` + ValidPids *ebpf.MapSpec `ebpf:"valid_pids"` +} + +// bpf_tpObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tpObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tpObjects struct { + bpf_tpPrograms + bpf_tpMaps +} + +func (o *bpf_tpObjects) Close() error { + return _Bpf_tpClose( + &o.bpf_tpPrograms, + &o.bpf_tpMaps, + ) +} + +// bpf_tpMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tpObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tpMaps struct { + Events *ebpf.Map `ebpf:"events"` + GoTraceMap *ebpf.Map `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.Map `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.Map `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.Map `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.Map `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.Map `ebpf:"pid_cache"` + ValidPids *ebpf.Map `ebpf:"valid_pids"` +} + +func (m *bpf_tpMaps) Close() error { + return _Bpf_tpClose( + m.Events, + m.GoTraceMap, + m.GolangMapbucketStorageMap, + m.HeaderReqMap, + m.OngoingGoroutines, + m.OngoingHttpClientRequests, + m.OngoingHttpServerRequests, + m.PidCache, + m.ValidPids, + ) +} + +// bpf_tpPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tpObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tpPrograms struct { + UprobeServeHTTP *ebpf.Program `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.Program `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` +} + +func (p *bpf_tpPrograms) Close() error { + return _Bpf_tpClose( + p.UprobeServeHTTP, + p.UprobeWriteHeader, + p.UprobeReadRequestReturns, + p.UprobeRoundTrip, + p.UprobeRoundTripReturn, + p.UprobeWriteSubset, + ) +} + +func _Bpf_tpClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +// +//go:embed bpf_tp_bpfel_x86.o +var _Bpf_tpBytes []byte diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.o b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.o new file mode 100644 index 000000000..2b45792e7 Binary files /dev/null and b/pkg/internal/ebpf/nethttp/bpf_tp_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.go b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.go new file mode 100644 index 000000000..1fd215199 --- /dev/null +++ b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.go @@ -0,0 +1,184 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build arm64 +// +build arm64 + +package nethttp + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +type bpf_tp_debugGoroutineMetadata struct { + Parent uint64 + Timestamp uint64 +} + +type bpf_tp_debugHttpFuncInvocationT struct { + StartMonotimeNs uint64 + ReqPtr uint64 + Tp bpf_tp_debugTpInfoT +} + +type bpf_tp_debugPidKeyT struct { + Pid uint32 + Namespace uint32 +} + +type bpf_tp_debugTpInfoT struct { + TraceId [16]uint8 + SpanId [8]uint8 + ParentId [8]uint8 + Epoch uint64 + Flags uint8 + _ [7]byte +} + +// loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. +func loadBpf_tp_debug() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_Bpf_tp_debugBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf_tp_debug: %w", err) + } + + return spec, err +} + +// loadBpf_tp_debugObjects loads bpf_tp_debug and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpf_tp_debugObjects +// *bpf_tp_debugPrograms +// *bpf_tp_debugMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpf_tp_debugObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf_tp_debug() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpf_tp_debugSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tp_debugSpecs struct { + bpf_tp_debugProgramSpecs + bpf_tp_debugMapSpecs +} + +// bpf_tp_debugSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tp_debugProgramSpecs struct { + UprobeServeHTTP *ebpf.ProgramSpec `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.ProgramSpec `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` +} + +// bpf_tp_debugMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tp_debugMapSpecs struct { + Events *ebpf.MapSpec `ebpf:"events"` + GoTraceMap *ebpf.MapSpec `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.MapSpec `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.MapSpec `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.MapSpec `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.MapSpec `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.MapSpec `ebpf:"pid_cache"` + ValidPids *ebpf.MapSpec `ebpf:"valid_pids"` +} + +// bpf_tp_debugObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tp_debugObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tp_debugObjects struct { + bpf_tp_debugPrograms + bpf_tp_debugMaps +} + +func (o *bpf_tp_debugObjects) Close() error { + return _Bpf_tp_debugClose( + &o.bpf_tp_debugPrograms, + &o.bpf_tp_debugMaps, + ) +} + +// bpf_tp_debugMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tp_debugObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tp_debugMaps struct { + Events *ebpf.Map `ebpf:"events"` + GoTraceMap *ebpf.Map `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.Map `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.Map `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.Map `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.Map `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.Map `ebpf:"pid_cache"` + ValidPids *ebpf.Map `ebpf:"valid_pids"` +} + +func (m *bpf_tp_debugMaps) Close() error { + return _Bpf_tp_debugClose( + m.Events, + m.GoTraceMap, + m.GolangMapbucketStorageMap, + m.HeaderReqMap, + m.OngoingGoroutines, + m.OngoingHttpClientRequests, + m.OngoingHttpServerRequests, + m.PidCache, + m.ValidPids, + ) +} + +// bpf_tp_debugPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tp_debugObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tp_debugPrograms struct { + UprobeServeHTTP *ebpf.Program `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.Program `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` +} + +func (p *bpf_tp_debugPrograms) Close() error { + return _Bpf_tp_debugClose( + p.UprobeServeHTTP, + p.UprobeWriteHeader, + p.UprobeReadRequestReturns, + p.UprobeRoundTrip, + p.UprobeRoundTripReturn, + p.UprobeWriteSubset, + ) +} + +func _Bpf_tp_debugClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +// +//go:embed bpf_tp_debug_bpfel_arm64.o +var _Bpf_tp_debugBytes []byte diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.o b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.o new file mode 100644 index 000000000..9dd95951e Binary files /dev/null and b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.go b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.go new file mode 100644 index 000000000..462d3dfe5 --- /dev/null +++ b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.go @@ -0,0 +1,184 @@ +// Code generated by bpf2go; DO NOT EDIT. +//go:build 386 || amd64 +// +build 386 amd64 + +package nethttp + +import ( + "bytes" + _ "embed" + "fmt" + "io" + + "github.com/cilium/ebpf" +) + +type bpf_tp_debugGoroutineMetadata struct { + Parent uint64 + Timestamp uint64 +} + +type bpf_tp_debugHttpFuncInvocationT struct { + StartMonotimeNs uint64 + ReqPtr uint64 + Tp bpf_tp_debugTpInfoT +} + +type bpf_tp_debugPidKeyT struct { + Pid uint32 + Namespace uint32 +} + +type bpf_tp_debugTpInfoT struct { + TraceId [16]uint8 + SpanId [8]uint8 + ParentId [8]uint8 + Epoch uint64 + Flags uint8 + _ [7]byte +} + +// loadBpf_tp_debug returns the embedded CollectionSpec for bpf_tp_debug. +func loadBpf_tp_debug() (*ebpf.CollectionSpec, error) { + reader := bytes.NewReader(_Bpf_tp_debugBytes) + spec, err := ebpf.LoadCollectionSpecFromReader(reader) + if err != nil { + return nil, fmt.Errorf("can't load bpf_tp_debug: %w", err) + } + + return spec, err +} + +// loadBpf_tp_debugObjects loads bpf_tp_debug and converts it into a struct. +// +// The following types are suitable as obj argument: +// +// *bpf_tp_debugObjects +// *bpf_tp_debugPrograms +// *bpf_tp_debugMaps +// +// See ebpf.CollectionSpec.LoadAndAssign documentation for details. +func loadBpf_tp_debugObjects(obj interface{}, opts *ebpf.CollectionOptions) error { + spec, err := loadBpf_tp_debug() + if err != nil { + return err + } + + return spec.LoadAndAssign(obj, opts) +} + +// bpf_tp_debugSpecs contains maps and programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tp_debugSpecs struct { + bpf_tp_debugProgramSpecs + bpf_tp_debugMapSpecs +} + +// bpf_tp_debugSpecs contains programs before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tp_debugProgramSpecs struct { + UprobeServeHTTP *ebpf.ProgramSpec `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.ProgramSpec `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.ProgramSpec `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.ProgramSpec `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.ProgramSpec `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.ProgramSpec `ebpf:"uprobe_writeSubset"` +} + +// bpf_tp_debugMapSpecs contains maps before they are loaded into the kernel. +// +// It can be passed ebpf.CollectionSpec.Assign. +type bpf_tp_debugMapSpecs struct { + Events *ebpf.MapSpec `ebpf:"events"` + GoTraceMap *ebpf.MapSpec `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.MapSpec `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.MapSpec `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.MapSpec `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.MapSpec `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.MapSpec `ebpf:"pid_cache"` + ValidPids *ebpf.MapSpec `ebpf:"valid_pids"` +} + +// bpf_tp_debugObjects contains all objects after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tp_debugObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tp_debugObjects struct { + bpf_tp_debugPrograms + bpf_tp_debugMaps +} + +func (o *bpf_tp_debugObjects) Close() error { + return _Bpf_tp_debugClose( + &o.bpf_tp_debugPrograms, + &o.bpf_tp_debugMaps, + ) +} + +// bpf_tp_debugMaps contains all maps after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tp_debugObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tp_debugMaps struct { + Events *ebpf.Map `ebpf:"events"` + GoTraceMap *ebpf.Map `ebpf:"go_trace_map"` + GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` + HeaderReqMap *ebpf.Map `ebpf:"header_req_map"` + OngoingGoroutines *ebpf.Map `ebpf:"ongoing_goroutines"` + OngoingHttpClientRequests *ebpf.Map `ebpf:"ongoing_http_client_requests"` + OngoingHttpServerRequests *ebpf.Map `ebpf:"ongoing_http_server_requests"` + PidCache *ebpf.Map `ebpf:"pid_cache"` + ValidPids *ebpf.Map `ebpf:"valid_pids"` +} + +func (m *bpf_tp_debugMaps) Close() error { + return _Bpf_tp_debugClose( + m.Events, + m.GoTraceMap, + m.GolangMapbucketStorageMap, + m.HeaderReqMap, + m.OngoingGoroutines, + m.OngoingHttpClientRequests, + m.OngoingHttpServerRequests, + m.PidCache, + m.ValidPids, + ) +} + +// bpf_tp_debugPrograms contains all programs after they have been loaded into the kernel. +// +// It can be passed to loadBpf_tp_debugObjects or ebpf.CollectionSpec.LoadAndAssign. +type bpf_tp_debugPrograms struct { + UprobeServeHTTP *ebpf.Program `ebpf:"uprobe_ServeHTTP"` + UprobeWriteHeader *ebpf.Program `ebpf:"uprobe_WriteHeader"` + UprobeReadRequestReturns *ebpf.Program `ebpf:"uprobe_readRequestReturns"` + UprobeRoundTrip *ebpf.Program `ebpf:"uprobe_roundTrip"` + UprobeRoundTripReturn *ebpf.Program `ebpf:"uprobe_roundTripReturn"` + UprobeWriteSubset *ebpf.Program `ebpf:"uprobe_writeSubset"` +} + +func (p *bpf_tp_debugPrograms) Close() error { + return _Bpf_tp_debugClose( + p.UprobeServeHTTP, + p.UprobeWriteHeader, + p.UprobeReadRequestReturns, + p.UprobeRoundTrip, + p.UprobeRoundTripReturn, + p.UprobeWriteSubset, + ) +} + +func _Bpf_tp_debugClose(closers ...io.Closer) error { + for _, closer := range closers { + if err := closer.Close(); err != nil { + return err + } + } + return nil +} + +// Do not access this directly. +// +//go:embed bpf_tp_debug_bpfel_x86.o +var _Bpf_tp_debugBytes []byte diff --git a/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.o b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.o new file mode 100644 index 000000000..03e0db6cd Binary files /dev/null and b/pkg/internal/ebpf/nethttp/bpf_tp_debug_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/nethttp/nethttp.go b/pkg/internal/ebpf/nethttp/nethttp.go index 9aeee88d0..3be273b21 100644 --- a/pkg/internal/ebpf/nethttp/nethttp.go +++ b/pkg/internal/ebpf/nethttp/nethttp.go @@ -22,6 +22,7 @@ import ( "github.com/cilium/ebpf" + ebpf2 "github.com/grafana/beyla/pkg/internal/ebpf" ebpfcommon "github.com/grafana/beyla/pkg/internal/ebpf/common" "github.com/grafana/beyla/pkg/internal/exec" "github.com/grafana/beyla/pkg/internal/goexec" @@ -30,8 +31,10 @@ import ( "github.com/grafana/beyla/pkg/internal/svc" ) -//go:generate $BPF2GO -cc $BPF_CLANG -cflags $BPF_CFLAGS -target amd64,arm64 bpf ../../../../bpf/go_nethttp.c -- -I../../../../bpf/headers -//go:generate $BPF2GO -cc $BPF_CLANG -cflags $BPF_CFLAGS -target amd64,arm64 bpf_debug ../../../../bpf/go_nethttp.c -- -I../../../../bpf/headers -DBPF_DEBUG +//go:generate $BPF2GO -cc $BPF_CLANG -cflags $BPF_CFLAGS -target amd64,arm64 bpf ../../../../bpf/go_nethttp.c -- -I../../../../bpf/headers -DNO_HEADER_PROPAGATION +//go:generate $BPF2GO -cc $BPF_CLANG -cflags $BPF_CFLAGS -target amd64,arm64 bpf_debug ../../../../bpf/go_nethttp.c -- -I../../../../bpf/headers -DBPF_DEBUG -DNO_HEADER_PROPAGATION +//go:generate $BPF2GO -cc $BPF_CLANG -cflags $BPF_CFLAGS -target amd64,arm64 bpf_tp ../../../../bpf/go_nethttp.c -- -I../../../../bpf/headers +//go:generate $BPF2GO -cc $BPF_CLANG -cflags $BPF_CFLAGS -target amd64,arm64 bpf_tp_debug ../../../../bpf/go_nethttp.c -- -I../../../../bpf/headers -DBPF_DEBUG type Tracer struct { log *slog.Logger @@ -60,11 +63,37 @@ func (p *Tracer) BlockPID(pid uint32) { p.pidsFilter.BlockPID(pid) } +func (p *Tracer) supportsContextPropagation() bool { + kernelMajor, kernelMinor := ebpf2.KernelVersion() + if kernelMajor < 5 || (kernelMajor == 5 && kernelMinor < 14) { + p.log.Debug("Found Linux kernel earlier than 5.14, trace context propagation is supported", "major", kernelMajor, "minor", kernelMinor) + return true + } + + lockdown := ebpfcommon.KernelLockdownMode() + + if lockdown == ebpfcommon.KernelLockdownNone { + p.log.Debug("Kernel not in lockdown mode, trace context propagation is supported.") + return true + } + + return false +} + func (p *Tracer) Load() (*ebpf.CollectionSpec, error) { loader := loadBpf if p.cfg.BpfDebug { loader = loadBpf_debug } + + if p.supportsContextPropagation() { + loader = loadBpf_tp + if p.cfg.BpfDebug { + loader = loadBpf_tp_debug + } + } else { + p.log.Info("Kernel in lockdown mode, trace info propagation in HTTP headers is disabled.") + } return loader() } @@ -85,6 +114,8 @@ func (p *Tracer) Constants(_ *exec.FileInfo, offsets *goexec.Offsets) map[string "content_length_ptr_pos", "resp_req_pos", "req_header_ptr_pos", + "io_writer_buf_ptr_pos", + "io_writer_n_pos", } { constants[s] = offsets.Field[s] } @@ -100,7 +131,7 @@ func (p *Tracer) AddCloser(c ...io.Closer) { } func (p *Tracer) GoProbes() map[string]ebpfcommon.FunctionPrograms { - return map[string]ebpfcommon.FunctionPrograms{ + m := map[string]ebpfcommon.FunctionPrograms{ "net/http.serverHandler.ServeHTTP": { Start: p.bpfObjects.UprobeServeHTTP, }, @@ -115,6 +146,14 @@ func (p *Tracer) GoProbes() map[string]ebpfcommon.FunctionPrograms { End: p.bpfObjects.UprobeRoundTripReturn, }, } + + if p.supportsContextPropagation() { + m["net/http.Header.writeSubset"] = ebpfcommon.FunctionPrograms{ + Start: p.bpfObjects.UprobeWriteSubset, + } + } + + return m } func (p *Tracer) KProbes() map[string]ebpfcommon.FunctionPrograms { diff --git a/pkg/internal/ebpf/watcher/bpf_bpfel_arm64.o b/pkg/internal/ebpf/watcher/bpf_bpfel_arm64.o index cc320bb17..df234dea1 100644 Binary files a/pkg/internal/ebpf/watcher/bpf_bpfel_arm64.o and b/pkg/internal/ebpf/watcher/bpf_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/watcher/bpf_bpfel_x86.o b/pkg/internal/ebpf/watcher/bpf_bpfel_x86.o index 608349940..32152262f 100644 Binary files a/pkg/internal/ebpf/watcher/bpf_bpfel_x86.o and b/pkg/internal/ebpf/watcher/bpf_bpfel_x86.o differ diff --git a/pkg/internal/ebpf/watcher/bpf_debug_bpfel_arm64.o b/pkg/internal/ebpf/watcher/bpf_debug_bpfel_arm64.o index 1a0297478..9e031f336 100644 Binary files a/pkg/internal/ebpf/watcher/bpf_debug_bpfel_arm64.o and b/pkg/internal/ebpf/watcher/bpf_debug_bpfel_arm64.o differ diff --git a/pkg/internal/ebpf/watcher/bpf_debug_bpfel_x86.o b/pkg/internal/ebpf/watcher/bpf_debug_bpfel_x86.o index 6c5334176..976f0a26e 100644 Binary files a/pkg/internal/ebpf/watcher/bpf_debug_bpfel_x86.o and b/pkg/internal/ebpf/watcher/bpf_debug_bpfel_x86.o differ diff --git a/pkg/internal/export/debug/debug.go b/pkg/internal/export/debug/debug.go index 07a9bb998..8cdce40f2 100644 --- a/pkg/internal/export/debug/debug.go +++ b/pkg/internal/export/debug/debug.go @@ -44,7 +44,7 @@ func traceparent(span *request.Span) string { if !trace.TraceID(span.TraceID).IsValid() { return "" } - return fmt.Sprintf("00-%s-%s-01", trace.TraceID(span.TraceID).String(), trace.SpanID(span.ParentSpanID).String()) + return fmt.Sprintf("00-%s-%s-%02x", trace.TraceID(span.TraceID).String(), trace.SpanID(span.ParentSpanID).String(), span.Flags) } type NoopEnabled bool diff --git a/pkg/internal/export/otel/traces.go b/pkg/internal/export/otel/traces.go index 4a86704e9..5bb7641fe 100644 --- a/pkg/internal/export/otel/traces.go +++ b/pkg/internal/export/otel/traces.go @@ -385,7 +385,7 @@ func spanKind(span *request.Span) trace2.SpanKind { func handleTraceparent(parentCtx context.Context, span *request.Span) context.Context { if span.ParentSpanID.IsValid() { - parentCtx = trace2.ContextWithSpanContext(parentCtx, trace2.SpanContext{}.WithTraceID(span.TraceID).WithSpanID(span.ParentSpanID).WithTraceFlags(trace2.FlagsSampled)) + parentCtx = trace2.ContextWithSpanContext(parentCtx, trace2.SpanContext{}.WithTraceID(span.TraceID).WithSpanID(span.ParentSpanID).WithTraceFlags(trace2.TraceFlags(span.Flags))) } else if span.TraceID.IsValid() { parentCtx = ContextWithTrace(parentCtx, span.TraceID) } diff --git a/pkg/internal/goexec/offsets.json b/pkg/internal/goexec/offsets.json index e9c542e7d..0fb5fa015 100755 --- a/pkg/internal/goexec/offsets.json +++ b/pkg/internal/goexec/offsets.json @@ -1,10 +1,36 @@ { "data": { + "bufio.Writer": { + "buf": { + "versions": { + "oldest": "1.17.0", + "newest": "1.21.5" + }, + "offsets": [ + { + "offset": 16, + "since": "1.17.0" + } + ] + }, + "n": { + "versions": { + "oldest": "1.17.0", + "newest": "1.21.5" + }, + "offsets": [ + { + "offset": 40, + "since": "1.17.0" + } + ] + } + }, "context.valueCtx": { "val": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -124,7 +150,7 @@ "IP": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -136,7 +162,7 @@ "Port": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -150,7 +176,7 @@ "ContentLength": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -162,7 +188,7 @@ "Header": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -174,7 +200,7 @@ "Host": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -186,7 +212,7 @@ "Method": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -198,7 +224,7 @@ "RemoteAddr": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -210,7 +236,7 @@ "URL": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -224,7 +250,7 @@ "StatusCode": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -238,7 +264,7 @@ "req": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -250,7 +276,7 @@ "status": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { @@ -264,7 +290,7 @@ "Path": { "versions": { "oldest": "1.17.0", - "newest": "1.21.4" + "newest": "1.21.5" }, "offsets": [ { diff --git a/pkg/internal/goexec/structmembers.go b/pkg/internal/goexec/structmembers.go index e3e0d7bdb..a2e106dbf 100644 --- a/pkg/internal/goexec/structmembers.go +++ b/pkg/internal/goexec/structmembers.go @@ -101,6 +101,13 @@ var structMembers = map[string]structInfo{ "target": "grpc_client_target_ptr_pos", }, }, + "bufio.Writer": { + lib: "go", + fields: map[string]string{ + "buf": "io_writer_buf_ptr_pos", + "n": "io_writer_n_pos", + }, + }, "context.valueCtx": { lib: "go", fields: map[string]string{ diff --git a/pkg/internal/request/span.go b/pkg/internal/request/span.go index 8ca31a7e6..4825511e3 100644 --- a/pkg/internal/request/span.go +++ b/pkg/internal/request/span.go @@ -68,6 +68,7 @@ type Span struct { TraceID trace2.TraceID SpanID trace2.SpanID ParentSpanID trace2.SpanID + Flags uint8 Pid PidInfo } diff --git a/test/integration/docker-compose-client.yml b/test/integration/docker-compose-client.yml index e314ec53e..20d0cec50 100644 --- a/test/integration/docker-compose-client.yml +++ b/test/integration/docker-compose-client.yml @@ -18,6 +18,7 @@ services: - --config=/configs/instrumenter-config${INSTRUMENTER_CONFIG_SUFFIX}.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-dotnet.yml b/test/integration/docker-compose-dotnet.yml index 65a96e8b3..5e6adcdba 100644 --- a/test/integration/docker-compose-dotnet.yml +++ b/test/integration/docker-compose-dotnet.yml @@ -22,6 +22,7 @@ services: - --config=/configs/instrumenter-config-java.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-java-host.yml b/test/integration/docker-compose-java-host.yml index b235c2476..ddff9a4b5 100644 --- a/test/integration/docker-compose-java-host.yml +++ b/test/integration/docker-compose-java-host.yml @@ -17,6 +17,7 @@ services: - --config=/configs/instrumenter-config-java-host.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-javaautoinstrumenter diff --git a/test/integration/docker-compose-java-pid.yml b/test/integration/docker-compose-java-pid.yml index 815fdca4b..28800bdd7 100644 --- a/test/integration/docker-compose-java-pid.yml +++ b/test/integration/docker-compose-java-pid.yml @@ -17,6 +17,7 @@ services: - --config=/configs/instrumenter-config-java.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-javaautoinstrumenter diff --git a/test/integration/docker-compose-java.yml b/test/integration/docker-compose-java.yml index 2ea51a5c5..8eccb8a18 100644 --- a/test/integration/docker-compose-java.yml +++ b/test/integration/docker-compose-java.yml @@ -20,6 +20,7 @@ services: - --config=/configs/instrumenter-config-java.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-javaautoinstrumenter diff --git a/test/integration/docker-compose-multiexec.yml b/test/integration/docker-compose-multiexec.yml index 8c2303657..a65fbc333 100644 --- a/test/integration/docker-compose-multiexec.yml +++ b/test/integration/docker-compose-multiexec.yml @@ -89,6 +89,7 @@ services: - --config=/configs/instrumenter-config-multiexec.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-nodeclient.yml b/test/integration/docker-compose-nodeclient.yml index 39ad1fd51..93fffee2c 100644 --- a/test/integration/docker-compose-nodeclient.yml +++ b/test/integration/docker-compose-nodeclient.yml @@ -24,6 +24,7 @@ services: - --config=/configs/instrumenter-config${INSTRUMENTER_CONFIG_SUFFIX}.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-nodejs.yml b/test/integration/docker-compose-nodejs.yml index 19607eb7d..7569f5460 100644 --- a/test/integration/docker-compose-nodejs.yml +++ b/test/integration/docker-compose-nodejs.yml @@ -25,6 +25,7 @@ services: - --config=/configs/instrumenter-config-node.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-python.yml b/test/integration/docker-compose-python.yml index 9338348be..c031f8a1d 100644 --- a/test/integration/docker-compose-python.yml +++ b/test/integration/docker-compose-python.yml @@ -21,6 +21,7 @@ services: - --config=/configs/instrumenter-config-java.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-ruby.yml b/test/integration/docker-compose-ruby.yml index 63eb4728a..188ca7ddd 100644 --- a/test/integration/docker-compose-ruby.yml +++ b/test/integration/docker-compose-ruby.yml @@ -18,6 +18,7 @@ services: - --config=/configs/instrumenter-config-ruby.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose-rust.yml b/test/integration/docker-compose-rust.yml index 4e33a43e9..a1eb481d8 100644 --- a/test/integration/docker-compose-rust.yml +++ b/test/integration/docker-compose-rust.yml @@ -21,6 +21,7 @@ services: - --config=/configs/instrumenter-config.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/docker-compose.yml b/test/integration/docker-compose.yml index 51d13a9f3..7c8b63430 100644 --- a/test/integration/docker-compose.yml +++ b/test/integration/docker-compose.yml @@ -25,6 +25,7 @@ services: - --config=/configs/instrumenter-config${INSTRUMENTER_CONFIG_SUFFIX}.yml volumes: - ./configs/:/configs + - ./system/sys/kernel/security${SECURITY_CONFIG_SUFFIX}:/sys/kernel/security - ../../testoutput:/coverage - ../../testoutput/run:/var/run/beyla image: hatest-autoinstrumenter diff --git a/test/integration/suites_test.go b/test/integration/suites_test.go index 7cf2aae4c..0efbec99d 100644 --- a/test/integration/suites_test.go +++ b/test/integration/suites_test.go @@ -3,7 +3,10 @@ package integration import ( + "bufio" + "os" "path" + "strings" "testing" "github.com/stretchr/testify/require" @@ -28,10 +31,23 @@ func TestSuite(t *testing.T) { } func TestSuiteNestedTraces(t *testing.T) { + // We run the test depending on what the host environment is. If the host is in lockdown mode integrity + // the nesting of spans will be limited. If we are in none (which should be in any non secure boot environment, e.g. Virtual Machines or CI) + // then we expect full nesting of trace spans in this test. + + // Echo (server) -> echo (client) -> EchoBack (server) + lockdown := KernelLockdownMode() compose, err := docker.ComposeSuite("docker-compose.yml", path.Join(pathOutput, "test-suite-nested.log")) + if !lockdown { + compose.Env = append(compose.Env, `SECURITY_CONFIG_SUFFIX=_none`) + } require.NoError(t, err) require.NoError(t, compose.Up()) - t.Run("HTTP traces (nested client span)", testHTTPTracesNestedClient) + if !lockdown { + t.Run("HTTP traces (all spans nested)", testHTTPTracesNestedClientWithContextPropagation) + } else { + t.Run("HTTP traces (nested client span)", testHTTPTracesNestedClient) + } t.Run("BPF pinning folder mounted", testBPFPinningMounted) require.NoError(t, compose.Close()) t.Run("BPF pinning folder unmounted", testBPFPinningUnmounted) @@ -412,3 +428,36 @@ func TestSuiteNoRoutes(t *testing.T) { require.NoError(t, compose.Close()) t.Run("BPF pinning folder unmounted", testBPFPinningUnmounted) } + +// Helpers + +var lockdownPath = "/sys/kernel/security/lockdown" + +func KernelLockdownMode() bool { + // If we can't find the file, assume no lockdown + if _, err := os.Stat(lockdownPath); err == nil { + f, err := os.Open(lockdownPath) + + if err != nil { + return true + } + + defer f.Close() + scanner := bufio.NewScanner(f) + if scanner.Scan() { + lockdown := scanner.Text() + if strings.Contains(lockdown, "[none]") { + return false + } else if strings.Contains(lockdown, "[integrity]") { + return true + } else if strings.Contains(lockdown, "[confidentiality]") { + return true + } + return true + } + + return true + } + + return false +} diff --git a/test/integration/system/sys/kernel/security/lockdown b/test/integration/system/sys/kernel/security/lockdown new file mode 100644 index 000000000..2473d0d89 --- /dev/null +++ b/test/integration/system/sys/kernel/security/lockdown @@ -0,0 +1 @@ +none [integrity] confidentiality \ No newline at end of file diff --git a/test/integration/system/sys/kernel/security_none/lockdown b/test/integration/system/sys/kernel/security_none/lockdown new file mode 100644 index 000000000..499a8dcde --- /dev/null +++ b/test/integration/system/sys/kernel/security_none/lockdown @@ -0,0 +1 @@ +[none] integrity confidentiality \ No newline at end of file diff --git a/test/integration/traces_test.go b/test/integration/traces_test.go index e4d7df4b6..8621841ff 100644 --- a/test/integration/traces_test.go +++ b/test/integration/traces_test.go @@ -367,7 +367,7 @@ func testHTTPTracesKProbes(t *testing.T) { assert.Empty(t, sd, sd.String()) } -func testHTTPTracesNestedClient(t *testing.T) { +func testHTTPTracesNestedCalls(t *testing.T, contextPropagation bool) { var traceID string var parentID string @@ -420,15 +420,31 @@ func testHTTPTracesNestedClient(t *testing.T) { ) assert.Empty(t, sd, sd.String()) + numNested := 1 + + if contextPropagation { + numNested = 2 + } + // Check the information of the "in queue" span res = trace.FindByOperationName("in queue") - require.Len(t, res, 1) - queue := res[0] - // Check parenthood - p, ok := trace.ParentOf(&queue) - require.True(t, ok) - assert.Equal(t, server.TraceID, p.TraceID) - assert.Equal(t, server.SpanID, p.SpanID) + require.Equal(t, len(res), numNested) + + var queue *jaeger.Span + + for i := range res { + r := &res[i] + // Check parenthood + p, ok := trace.ParentOf(r) + + if ok { + if p.TraceID == server.TraceID && p.SpanID == server.SpanID { + queue = r + break + } + } + } + require.NotNil(t, queue) // check span attributes sd = queue.Diff( jaeger.Tag{Key: "span.kind", Type: "string", Value: "internal"}, @@ -437,13 +453,24 @@ func testHTTPTracesNestedClient(t *testing.T) { // Check the information of the "processing" span res = trace.FindByOperationName("processing") - require.Len(t, res, 1) - processing := res[0] - // Check parenthood - p, ok = trace.ParentOf(&processing) - require.True(t, ok) - assert.Equal(t, server.TraceID, p.TraceID) - assert.Equal(t, server.SpanID, p.SpanID) + require.Equal(t, len(res), numNested) + + var processing *jaeger.Span + + for i := range res { + r := &res[i] + // Check parenthood + p, ok := trace.ParentOf(r) + + if ok { + if p.TraceID == server.TraceID && p.SpanID == server.SpanID { + processing = r + break + } + } + } + + require.NotNil(t, processing) sd = queue.Diff( jaeger.Tag{Key: "span.kind", Type: "string", Value: "internal"}, ) @@ -454,7 +481,7 @@ func testHTTPTracesNestedClient(t *testing.T) { require.Len(t, res, 1) client := res[0] // Check parenthood - p, ok = trace.ParentOf(&client) + p, ok := trace.ParentOf(&client) require.True(t, ok) assert.Equal(t, processing.TraceID, p.TraceID) assert.Equal(t, processing.SpanID, p.SpanID) @@ -467,3 +494,11 @@ func testHTTPTracesNestedClient(t *testing.T) { ) assert.Empty(t, sd, sd.String()) } + +func testHTTPTracesNestedClient(t *testing.T) { + testHTTPTracesNestedCalls(t, false) +} + +func testHTTPTracesNestedClientWithContextPropagation(t *testing.T) { + testHTTPTracesNestedCalls(t, true) +}