0001
0002
0003 #include "bpf_iter.h"
0004 #include "bpf_tracing_net.h"
0005 #include <bpf/bpf_helpers.h>
0006 #include <bpf/bpf_endian.h>
0007
0008 char _license[] SEC("license") = "GPL";
0009
0010 #define IPV6_SEQ_DGRAM_HEADER \
0011 " sl " \
0012 "local_address " \
0013 "remote_address " \
0014 "st tx_queue rx_queue tr tm->when retrnsmt" \
0015 " uid timeout inode ref pointer drops\n"
0016
0017 static long sock_i_ino(const struct sock *sk)
0018 {
0019 const struct socket *sk_socket = sk->sk_socket;
0020 const struct inode *inode;
0021 unsigned long ino;
0022
0023 if (!sk_socket)
0024 return 0;
0025
0026 inode = &container_of(sk_socket, struct socket_alloc, socket)->vfs_inode;
0027 bpf_probe_read_kernel(&ino, sizeof(ino), &inode->i_ino);
0028 return ino;
0029 }
0030
0031 SEC("iter/udp")
0032 int dump_udp6(struct bpf_iter__udp *ctx)
0033 {
0034 struct seq_file *seq = ctx->meta->seq;
0035 struct udp_sock *udp_sk = ctx->udp_sk;
0036 const struct in6_addr *dest, *src;
0037 struct udp6_sock *udp6_sk;
0038 struct inet_sock *inet;
0039 __u16 srcp, destp;
0040 __u32 seq_num;
0041 int rqueue;
0042
0043 if (udp_sk == (void *)0)
0044 return 0;
0045
0046 seq_num = ctx->meta->seq_num;
0047 if (seq_num == 0)
0048 BPF_SEQ_PRINTF(seq, IPV6_SEQ_DGRAM_HEADER);
0049
0050 udp6_sk = bpf_skc_to_udp6_sock(udp_sk);
0051 if (udp6_sk == (void *)0)
0052 return 0;
0053
0054 inet = &udp_sk->inet;
0055 srcp = bpf_ntohs(inet->inet_sport);
0056 destp = bpf_ntohs(inet->inet_dport);
0057 rqueue = inet->sk.sk_rmem_alloc.counter - udp_sk->forward_deficit;
0058 dest = &inet->sk.sk_v6_daddr;
0059 src = &inet->sk.sk_v6_rcv_saddr;
0060
0061 BPF_SEQ_PRINTF(seq, "%5d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X ",
0062 ctx->bucket,
0063 src->s6_addr32[0], src->s6_addr32[1],
0064 src->s6_addr32[2], src->s6_addr32[3], srcp,
0065 dest->s6_addr32[0], dest->s6_addr32[1],
0066 dest->s6_addr32[2], dest->s6_addr32[3], destp);
0067
0068 BPF_SEQ_PRINTF(seq, "%02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u\n",
0069 inet->sk.sk_state,
0070 inet->sk.sk_wmem_alloc.refs.counter - 1,
0071 rqueue,
0072 0, 0L, 0, ctx->uid, 0,
0073 sock_i_ino(&inet->sk),
0074 inet->sk.sk_refcnt.refs.counter, udp_sk,
0075 inet->sk.sk_drops.counter);
0076
0077 return 0;
0078 }