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 #include <bpf/bpf_endian.h> 8 9 char _license[] SEC("license") = "GPL"; 10 11 static long sock_i_ino(const struct sock *sk) 12 { 13 const struct socket *sk_socket = sk->sk_socket; 14 const struct inode *inode; 15 unsigned long ino; 16 17 if (!sk_socket) 18 return 0; 19 20 inode = &container_of(sk_socket, struct socket_alloc, socket)->vfs_inode; 21 bpf_probe_read_kernel(&ino, sizeof(ino), &inode->i_ino); 22 return ino; 23 } 24 25 SEC("iter/udp") 26 int dump_udp4(struct bpf_iter__udp *ctx) 27 { 28 struct seq_file *seq = ctx->meta->seq; 29 struct udp_sock *udp_sk = ctx->udp_sk; 30 struct inet_sock *inet; 31 __u16 srcp, destp; 32 __be32 dest, src; 33 __u32 seq_num; 34 int rqueue; 35 36 if (udp_sk == (void *)0) 37 return 0; 38 39 seq_num = ctx->meta->seq_num; 40 if (seq_num == 0) 41 BPF_SEQ_PRINTF(seq, 42 " sl local_address rem_address st tx_queue " 43 "rx_queue tr tm->when retrnsmt uid timeout " 44 "inode ref pointer drops\n"); 45 46 /* filter out udp6 sockets */ 47 inet = &udp_sk->inet; 48 if (inet->sk.sk_family == AF_INET6) 49 return 0; 50 51 inet = &udp_sk->inet; 52 dest = inet->inet_daddr; 53 src = inet->inet_rcv_saddr; 54 srcp = bpf_ntohs(inet->inet_sport); 55 destp = bpf_ntohs(inet->inet_dport); 56 rqueue = inet->sk.sk_rmem_alloc.counter - udp_sk->forward_deficit; 57 58 BPF_SEQ_PRINTF(seq, "%5d: %08X:%04X %08X:%04X ", 59 ctx->bucket, src, srcp, dest, destp); 60 61 BPF_SEQ_PRINTF(seq, "%02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u\n", 62 inet->sk.sk_state, 63 inet->sk.sk_wmem_alloc.refs.counter - 1, 64 rqueue, 65 0, 0L, 0, ctx->uid, 0, 66 sock_i_ino(&inet->sk), 67 inet->sk.sk_refcnt.refs.counter, udp_sk, 68 inet->sk.sk_drops.counter); 69 70 return 0; 71 } 72