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