17c128a6bSYonghong Song // SPDX-License-Identifier: GPL-2.0
27c128a6bSYonghong Song /* Copyright (c) 2020 Facebook */
384544f56SYonghong Song #include "bpf_iter.h"
4647b502eSYonghong Song #include "bpf_tracing_net.h"
57c128a6bSYonghong Song #include <bpf/bpf_helpers.h>
67c128a6bSYonghong Song
77c128a6bSYonghong Song char _license[] SEC("license") = "GPL";
87c128a6bSYonghong Song
SOCK_INODE(struct socket * socket)99c82a63cSAndrii Nakryiko static __attribute__((noinline)) struct inode *SOCK_INODE(struct socket *socket)
107c128a6bSYonghong Song {
117c128a6bSYonghong Song return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
127c128a6bSYonghong Song }
137c128a6bSYonghong Song
147c128a6bSYonghong Song SEC("iter/netlink")
dump_netlink(struct bpf_iter__netlink * ctx)157c128a6bSYonghong Song int dump_netlink(struct bpf_iter__netlink *ctx)
167c128a6bSYonghong Song {
177c128a6bSYonghong Song struct seq_file *seq = ctx->meta->seq;
187c128a6bSYonghong Song struct netlink_sock *nlk = ctx->sk;
197c128a6bSYonghong Song unsigned long group, ino;
207c128a6bSYonghong Song struct inode *inode;
217c128a6bSYonghong Song struct socket *sk;
227c128a6bSYonghong Song struct sock *s;
237c128a6bSYonghong Song
247c128a6bSYonghong Song if (nlk == (void *)0)
257c128a6bSYonghong Song return 0;
267c128a6bSYonghong Song
277c128a6bSYonghong Song if (ctx->meta->seq_num == 0)
287c128a6bSYonghong Song BPF_SEQ_PRINTF(seq, "sk Eth Pid Groups "
297c128a6bSYonghong Song "Rmem Wmem Dump Locks Drops "
307c128a6bSYonghong Song "Inode\n");
317c128a6bSYonghong Song
327c128a6bSYonghong Song s = &nlk->sk;
337c128a6bSYonghong Song BPF_SEQ_PRINTF(seq, "%pK %-3d ", s, s->sk_protocol);
347c128a6bSYonghong Song
357c128a6bSYonghong Song if (!nlk->groups) {
367c128a6bSYonghong Song group = 0;
377c128a6bSYonghong Song } else {
38*e4d9c232SIlya Leoshkevich /* FIXME: temporary use bpf_probe_read_kernel here, needs
397c128a6bSYonghong Song * verifier support to do direct access.
407c128a6bSYonghong Song */
41*e4d9c232SIlya Leoshkevich bpf_probe_read_kernel(&group, sizeof(group), &nlk->groups[0]);
427c128a6bSYonghong Song }
437c128a6bSYonghong Song BPF_SEQ_PRINTF(seq, "%-10u %08x %-8d %-8d %-5d %-8d ",
447c128a6bSYonghong Song nlk->portid, (u32)group,
457c128a6bSYonghong Song s->sk_rmem_alloc.counter,
467c128a6bSYonghong Song s->sk_wmem_alloc.refs.counter - 1,
477c128a6bSYonghong Song nlk->cb_running, s->sk_refcnt.refs.counter);
487c128a6bSYonghong Song
497c128a6bSYonghong Song sk = s->sk_socket;
507c128a6bSYonghong Song if (!sk) {
517c128a6bSYonghong Song ino = 0;
527c128a6bSYonghong Song } else {
537c128a6bSYonghong Song /* FIXME: container_of inside SOCK_INODE has a forced
547c128a6bSYonghong Song * type conversion, and direct access cannot be used
557c128a6bSYonghong Song * with current verifier.
567c128a6bSYonghong Song */
577c128a6bSYonghong Song inode = SOCK_INODE(sk);
58*e4d9c232SIlya Leoshkevich bpf_probe_read_kernel(&ino, sizeof(ino), &inode->i_ino);
597c128a6bSYonghong Song }
607c128a6bSYonghong Song BPF_SEQ_PRINTF(seq, "%-8u %-8lu\n", s->sk_drops.counter, ino);
617c128a6bSYonghong Song
627c128a6bSYonghong Song return 0;
637c128a6bSYonghong Song }
64