On 8/17/24 7:13 PM, Geliang Tang wrote:
Take a look at a recent example [0]. The mptcp test is under a cgroup already and has the cgroup setup. An extra "cgroup/getsockopt" prog should be enough. That prog can walk the msk->conn_list and use bpf_rdonly_cast (or the bpf_core_cast macro in libbpf) to cast a pointer to tcp_sock for
[ ... ]
SEC("cgroup/getsockopt") int _getsockopt(struct bpf_sockopt *ctx) { struct mptcp_sock *msk = bpf_core_cast(ctx->sk, struct mptcp_sock); struct mptcp_subflow_context *subflow; __u32 token = 0;
if (!msk || ctx->level != SOL_TCP || ctx->optname != TCP_CONGESTION) return 1; subflow = list_first_entry(&msk->conn_list, struct mptcp_subflow_context, node); token = subflow->token; bpf_trace_printk(fmt, sizeof(fmt), msk, token); return 1;
}
And got some access errors:
; token = subflow->token; @ mptcp_subflow.c:92 13: (61) r4 = *(u32 *)(r1 +524) access beyond struct list_head at off 524 size 4
Similar to your bpf_core_cast() usage earlier that casts a sock ptr to mptcp_sock ptr. r1 is in list_head ptr type. It needs to cast to mptcp_subflow_context ptr.
The same cast to tcp_sock is needed when you try to get the tcp_sock ptr from subflow->tcp_sock which is in "struct sock *" type in the kernel instead of "struct tcp_sock *".