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