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