linux/tools/testing/selftests/bpf/progs/bpf_iter_netlink.c
<<
>>
Prefs
   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
   8char _license[] SEC("license") = "GPL";
   9
  10static __attribute__((noinline)) struct inode *SOCK_INODE(struct socket *socket)
  11{
  12        return &container_of(socket, struct socket_alloc, socket)->vfs_inode;
  13}
  14
  15SEC("iter/netlink")
  16int 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