Skip to content

Commit 5c214d4

Browse files
Extend packet at the sock msg level (#1740)
1 parent 7dbd664 commit 5c214d4

File tree

12 files changed

+639
-886
lines changed

12 files changed

+639
-886
lines changed

bpf/go_nethttp.h

+1
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,7 @@ int beyla_uprobe_persistConnRoundTrip(struct pt_regs *ctx) {
11531153
tp_info_pid_t tp_p = {
11541154
.pid = pid,
11551155
.valid = 1,
1156+
.written = 0,
11561157
};
11571158

11581159
tp_clone(&tp_p.tp, &invocation->tp);

bpf/http_ssl_defs.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,12 @@ handle_ssl_buf(void *ctx, u64 id, ssl_args_t *args, int bytes_len, u8 direction)
198198
}
199199
}
200200

201-
static __always_inline void set_active_ssl_connection(pid_connection_info_t *conn, void *ssl) {
201+
static __always_inline void set_active_ssl_connection(const pid_connection_info_t *conn,
202+
void *ssl) {
202203
bpf_map_update_elem(&active_ssl_connections, conn, &ssl, BPF_ANY);
203204
}
204205

205-
static __always_inline void *is_ssl_connection(u64 id, pid_connection_info_t *conn) {
206+
static __always_inline void *is_ssl_connection(u64 id, const pid_connection_info_t *conn) {
206207
void *ssl = 0;
207208
// Checks if it's sandwitched between active SSL handshake, read or write uprobe/uretprobe
208209
ssl_args_t *ssl_args = bpf_map_lookup_elem(&active_ssl_read_args, &id);

bpf/http_types.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct tp_info_pid {
9999
tp_info_t tp;
100100
u32 pid;
101101
u8 valid;
102+
u8 written;
102103
u8 req_type;
103104
} tp_info_pid_t;
104105

@@ -312,4 +313,4 @@ static __always_inline u8 is_http_request_buf(const unsigned char *p) {
312313
);
313314
}
314315

315-
#endif
316+
#endif

bpf/k_tracer.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ int BPF_KPROBE(beyla_kprobe_tcp_sendmsg, struct sock *sk, struct msghdr *msg, si
276276
dbg_print_http_connection_info(
277277
&s_args.p_conn.conn); // commented out since GitHub CI doesn't like this call
278278
// Create the egress key before we sort the connection info.
279-
egress_key_t e_key = {
279+
const egress_key_t e_key = {
280280
.d_port = s_args.p_conn.conn.d_port,
281281
.s_port = s_args.p_conn.conn.s_port,
282282
};
@@ -360,7 +360,7 @@ int BPF_KPROBE(beyla_kprobe_tcp_rate_check_app_limited, struct sock *sk) {
360360
if (parse_sock_info(sk, &s_args.p_conn.conn)) {
361361
u16 orig_dport = s_args.p_conn.conn.d_port;
362362
dbg_print_http_connection_info(&s_args.p_conn.conn);
363-
egress_key_t e_key = {
363+
const egress_key_t e_key = {
364364
.d_port = s_args.p_conn.conn.d_port,
365365
.s_port = s_args.p_conn.conn.s_port,
366366
};
@@ -593,7 +593,7 @@ static __always_inline int return_recvmsg(void *ctx, u64 id, int copied_len) {
593593
bpf_map_delete_elem(&active_recv_args, &id);
594594

595595
if (parse_sock_info((struct sock *)sock_ptr, &info.conn)) {
596-
u16 orig_dport = info.conn.d_port;
596+
const u16 orig_dport = info.conn.d_port;
597597
//dbg_print_http_connection_info(&info.conn);
598598
sort_connection_info(&info.conn);
599599
info.pid = pid_from_pid_tgid(id);

bpf/protocol_http.h

+26-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,30 @@ static __always_inline void http_get_or_create_trace_info(http_connection_metada
4949
int bytes_len,
5050
s32 capture_header_buffer,
5151
u8 ssl) {
52-
tp_info_pid_t *tp_p = tp_buf();
52+
//TODO use make_key
53+
egress_key_t e_key = {
54+
.d_port = conn->d_port,
55+
.s_port = conn->s_port,
56+
};
57+
58+
sort_egress_key(&e_key);
59+
60+
tp_info_pid_t *tp_p = bpf_map_lookup_elem(&outgoing_trace_map, &e_key);
61+
62+
// TODO move this to sock msg
63+
if (tp_p && tp_p->req_type == EVENT_HTTP_CLIENT && tp_p->written && tp_p->pid == pid) {
64+
bpf_dbg_printk("found tp info previously set by sock msg");
65+
// we've already got a tp_info_pid_t setup by the sockmsg program, use
66+
// that instead
67+
68+
set_trace_info_for_connection(conn, TRACE_TYPE_CLIENT, tp_p);
69+
70+
// clean up so that TC does not pick it up
71+
bpf_map_delete_elem(&outgoing_trace_map, &e_key);
72+
return;
73+
}
74+
75+
tp_p = tp_buf();
5376

5477
if (!tp_p) {
5578
return;
@@ -58,6 +81,7 @@ static __always_inline void http_get_or_create_trace_info(http_connection_metada
5881
tp_p->tp.ts = bpf_ktime_get_ns();
5982
tp_p->tp.flags = 1;
6083
tp_p->valid = 1;
84+
tp_p->written = 0;
6185
tp_p->pid = pid; // used for avoiding finding stale server requests with client port reuse
6286
tp_p->req_type = (meta) ? meta->type : 0;
6387

@@ -82,7 +106,7 @@ static __always_inline void http_get_or_create_trace_info(http_connection_metada
82106
if (!found_tp) {
83107
bpf_dbg_printk("Generating new traceparent id");
84108
new_trace_id(&tp_p->tp);
85-
__builtin_memset(tp_p->tp.parent_id, 0, sizeof(tp_p->tp.span_id));
109+
__builtin_memset(tp_p->tp.parent_id, 0, sizeof(tp_p->tp.parent_id));
86110
} else {
87111
bpf_dbg_printk("Using old traceparent id");
88112
}

bpf/tc_common.h

+31-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const char INV_TP[] = "W3C-BeylaID: 00-00000000000000000000000000000000-00000000
1111
const u32 EXTEND_SIZE = sizeof(TP) - 1;
1212
const char TP_PREFIX[] = "Traceparent: ";
1313
const u32 TP_PREFIX_SIZE = sizeof(TP_PREFIX) - 1;
14+
const u32 INVALID_POS = 0xffffffff;
1415

1516
static __always_inline unsigned char *
1617
memchar(unsigned char *haystack, char needle, const unsigned char *end, u32 size) {
@@ -32,22 +33,24 @@ find_first_of(unsigned char *begin, unsigned char *end, char ch) {
3233
return memchar(begin, ch, end, MAX_INLINE_LEN);
3334
}
3435

35-
static __always_inline int
36-
memchar_pos(unsigned const char *haystack, char needle, const unsigned char *end, u32 size) {
36+
static __always_inline u32 memchar_pos(unsigned char *haystack,
37+
char needle,
38+
const unsigned char *end,
39+
u32 size) {
3740
for (u32 i = 0; i < size; ++i) {
38-
if (&haystack[i] >= end) {
39-
break;
40-
}
41+
unsigned char *ptr = haystack + i;
4142

42-
if (haystack[i] == needle) {
43+
if (ptr + 1 >= end) {
44+
break;
45+
} else if (ptr && *ptr == needle) {
4346
return i;
4447
}
4548
}
4649

47-
return -1;
50+
return INVALID_POS;
4851
}
4952

50-
static __always_inline int find_first_pos_of(unsigned char *begin, unsigned char *end, char ch) {
53+
static __always_inline u32 find_first_pos_of(unsigned char *begin, unsigned char *end, char ch) {
5154
return memchar_pos(begin, ch, end, MAX_INLINE_LEN);
5255
}
5356

@@ -71,6 +74,26 @@ static __always_inline void *ctx_data_end(struct __sk_buff *ctx) {
7174
return data_end;
7275
}
7376

77+
static __always_inline void *ctx_msg_data(struct sk_msg_md *ctx) {
78+
void *data;
79+
80+
asm("%[res] = *(u64 *)(%[base] + %[offset])"
81+
: [res] "=r"(data)
82+
: [base] "r"(ctx), [offset] "i"(offsetof(struct sk_msg_md, data)), "m"(*ctx));
83+
84+
return data;
85+
}
86+
87+
static __always_inline void *ctx_msg_data_end(struct sk_msg_md *ctx) {
88+
void *data_end;
89+
90+
asm("%[res] = *(u64 *)(%[base] + %[offset])"
91+
: [res] "=r"(data_end)
92+
: [base] "r"(ctx), [offset] "i"(offsetof(struct sk_msg_md, data_end)), "m"(*ctx));
93+
94+
return data_end;
95+
}
96+
7497
static __always_inline void
7598
sk_msg_read_remote_ip6(struct sk_msg_md *ctx, u32 *res) { //NOLINT(readability-non-const-parameter)
7699
asm("%[res0] = *(u32 *)(%[base] + %[offset] + 0)\n"

0 commit comments

Comments
 (0)