1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2020 Facebook */ 3 #include "bpf_iter.h" 4 #include "bpf_tracing_net.h" 5 #include <bpf/bpf_helpers.h> 6 7 char _license[] SEC("license") = "GPL"; 8 9 static __attribute__((noinline)) struct inode *SOCK_INODE(struct socket *socket) 10 { 11 return &container_of(socket, struct socket_alloc, socket)->vfs_inode; 12 } 13 14 SEC("iter/netlink") 15 int dump_netlink(struct bpf_iter__netlink *ctx) 16 { 17 struct seq_file *seq = ctx->meta->seq; 18 struct netlink_sock *nlk = ctx->sk; 19 unsigned long group, ino; 20 struct inode *inode; 21 struct socket *sk; 22 struct sock *s; 23 24 if (nlk == (void *)0) 25 return 0; 26 27 if (ctx->meta->seq_num == 0) 28 BPF_SEQ_PRINTF(seq, "sk Eth Pid Groups " 29 "Rmem Wmem Dump Locks Drops " 30 "Inode\n"); 31 32 s = &nlk->sk; 33 BPF_SEQ_PRINTF(seq, "%pK %-3d ", s, s->sk_protocol); 34 35 if (!nlk->groups) { 36 group = 0; 37 } else { 38 /* FIXME: temporary use bpf_probe_read_kernel here, needs 39 * verifier support to do direct access. 40 */ 41 bpf_probe_read_kernel(&group, sizeof(group), &nlk->groups[0]); 42 } 43 BPF_SEQ_PRINTF(seq, "%-10u %08x %-8d %-8d %-5d %-8d ", 44 nlk->portid, (u32)group, 45 s->sk_rmem_alloc.counter, 46 s->sk_wmem_alloc.refs.counter - 1, 47 nlk->cb_running, s->sk_refcnt.refs.counter); 48 49 sk = s->sk_socket; 50 if (!sk) { 51 ino = 0; 52 } else { 53 /* FIXME: container_of inside SOCK_INODE has a forced 54 * type conversion, and direct access cannot be used 55 * with current verifier. 56 */ 57 inode = SOCK_INODE(sk); 58 bpf_probe_read_kernel(&ino, sizeof(ino), &inode->i_ino); 59 } 60 BPF_SEQ_PRINTF(seq, "%-8u %-8lu\n", s->sk_drops.counter, ino); 61 62 return 0; 63 } 64