mbox series

[v6,bpf-next,0/4] BPF iterator for UNIX domain socket.

Message ID 20210814015718.42704-1-kuniyu@amazon.co.jp
Headers show
Series BPF iterator for UNIX domain socket. | expand

Message

Kuniyuki Iwashima Aug. 14, 2021, 1:57 a.m. UTC
This patch set adds BPF iterator support for UNIX domain socket.  The first
patch implements it, and the second adds "%c" support for BPF_SEQ_PRINTF().

Thanks to Yonghong Song for the fix [0] for the LLVM code gen.  The fix
prevents the LLVM compiler from transforming the loop exit condition '<' to
'!=', where the upper bound is not a constant.  The transformation leads
the verifier to interpret it as an infinite loop.

And thanks to Andrii Nakryiko for its workaround [1].

[0] https://reviews.llvm.org/D107483
[1] https://lore.kernel.org/netdev/CAEf4BzZ3sVx1m1mOCcPcuVPiY6cWEAO=6VGHDiXEs9ZVD-RoLg@mail.gmail.com/


Changelog:
  v6:
  - Align the header "Inde" column
  - Change int vars to __u64 not to break test_progs-no_alu32
  - Move the if statement into the for loop not to depend on the fix [0]
  - Drop the README change
  - Modify "%c" positive test patterns

  v5:
  https://lore.kernel.org/netdev/20210812164557.79046-1-kuniyu@amazon.co.jp/
  - Align header line of bpf_iter_unix.c
  - Add test for "%c"

  v4:
  https://lore.kernel.org/netdev/20210810092807.13190-1-kuniyu@amazon.co.jp/
  - Check IS_BUILTIN(CONFIG_UNIX)
  - Support "%c" in BPF_SEQ_PRINTF()
  - Uncomment the code to print the name of the abstract socket
  - Mention the LLVM fix in README.rst
  - Remove the 'aligned' attribute in bpf_iter.h
  - Keep the format string on a single line

  v3:
  https://lore.kernel.org/netdev/20210804070851.97834-1-kuniyu@amazon.co.jp/
  - Export some functions for CONFIG_UNIX=m

  v2:
  https://lore.kernel.org/netdev/20210803011110.21205-1-kuniyu@amazon.co.jp/
  - Implement bpf_iter specific seq_ops->stop()
  - Add bpf_iter__unix in bpf_iter.h
  - Move common definitions in selftest to bpf_tracing_net.h
  - Include the code for abstract UNIX domain socket as comment in selftest
  - Use ASSERT_OK_PTR() instead of CHECK()
  - Make ternary operators on single line

  v1:
  https://lore.kernel.org/netdev/20210729233645.4869-1-kuniyu@amazon.co.jp/


Kuniyuki Iwashima (4):
  bpf: af_unix: Implement BPF iterator for UNIX domain socket.
  bpf: Support "%c" in bpf_bprintf_prepare().
  selftest/bpf: Implement sample UNIX domain socket iterator program.
  selftest/bpf: Extend the bpf_snprintf() test for "%c".

 include/linux/btf_ids.h                       |  3 +-
 kernel/bpf/helpers.c                          | 14 +++
 net/unix/af_unix.c                            | 93 +++++++++++++++++++
 .../selftests/bpf/prog_tests/bpf_iter.c       | 16 ++++
 .../selftests/bpf/prog_tests/snprintf.c       |  4 +-
 tools/testing/selftests/bpf/progs/bpf_iter.h  |  8 ++
 .../selftests/bpf/progs/bpf_iter_unix.c       | 80 ++++++++++++++++
 .../selftests/bpf/progs/bpf_tracing_net.h     |  4 +
 .../selftests/bpf/progs/test_snprintf.c       |  6 +-
 9 files changed, 223 insertions(+), 5 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_unix.c

Comments

Andrii Nakryiko Aug. 15, 2021, 7:21 a.m. UTC | #1
On Fri, Aug 13, 2021 at 6:58 PM Kuniyuki Iwashima <kuniyu@amazon.co.jp> wrote:
>

> The iterator can output almost the same result compared to /proc/net/unix.

> The header line is aligned, and the Inode column uses "%8lu" because "%5lu"

> can be easily overflown.

>

>   # cat /sys/fs/bpf/unix

>   Num               RefCount Protocol Flags    Type St    Inode Path

>   ffff963c06689800: 00000002 00000000 00010000 0001 01    18697 private/defer

>   ffff963c7c979c00: 00000002 00000000 00000000 0001 01   598245 @Hello@World@

>

>   # cat /proc/net/unix

>   Num       RefCount Protocol Flags    Type St Inode Path

>   ffff963c06689800: 00000002 00000000 00010000 0001 01 18697 private/defer

>   ffff963c7c979c00: 00000002 00000000 00000000 0001 01 598245 @Hello@World@

>

> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.co.jp>

> Acked-by: Yonghong Song <yhs@fb.com>

> ---

>  .../selftests/bpf/prog_tests/bpf_iter.c       | 16 ++++

>  tools/testing/selftests/bpf/progs/bpf_iter.h  |  8 ++

>  .../selftests/bpf/progs/bpf_iter_unix.c       | 80 +++++++++++++++++++

>  .../selftests/bpf/progs/bpf_tracing_net.h     |  4 +

>  4 files changed, 108 insertions(+)

>  create mode 100644 tools/testing/selftests/bpf/progs/bpf_iter_unix.c


[...]

> +       if (unix_sk->addr) {

> +               if (!UNIX_ABSTRACT(unix_sk)) {

> +                       BPF_SEQ_PRINTF(seq, " %s", unix_sk->addr->name->sun_path);

> +               } else {

> +                       /* The name of the abstract UNIX domain socket starts

> +                        * with '\0' and can contain '\0'.  The null bytes

> +                        * should be escaped as done in unix_seq_show().

> +                        */

> +                       __u64 i, len;

> +

> +                       len = unix_sk->addr->len - sizeof(short);

> +

> +                       BPF_SEQ_PRINTF(seq, " @");

> +

> +                       for (i = 1; i < len; i++) {

> +                               /* unix_mkname() tests this upper bound. */

> +                               if (len >= sizeof(struct sockaddr_un))


I've changed this to (i >= sizeof(...)) which made more sense to me
than checking len multiple times. Both test_progs and
test_progs-no_alu32 passed on my local slightly older clang which
doesn't yet have Yonghong's fix, so I hope I didn't regress anything.

Applied to bpf-next.

> +                                       break;

> +

> +                               BPF_SEQ_PRINTF(seq, "%c",

> +                                              unix_sk->addr->name->sun_path[i] ?:

> +                                              '@');

> +                       }

> +               }

> +       }

> +

> +       BPF_SEQ_PRINTF(seq, "\n");

> +

> +       return 0;

> +}

> diff --git a/tools/testing/selftests/bpf/progs/bpf_tracing_net.h b/tools/testing/selftests/bpf/progs/bpf_tracing_net.h

> index 3af0998a0623..eef5646ddb19 100644

> --- a/tools/testing/selftests/bpf/progs/bpf_tracing_net.h

> +++ b/tools/testing/selftests/bpf/progs/bpf_tracing_net.h

> @@ -5,6 +5,10 @@

>  #define AF_INET                        2

>  #define AF_INET6               10

>

> +#define __SO_ACCEPTCON         (1 << 16)

> +#define UNIX_HASH_SIZE         256

> +#define UNIX_ABSTRACT(unix_sk) (unix_sk->addr->hash < UNIX_HASH_SIZE)

> +

>  #define SOL_TCP                        6

>  #define TCP_CONGESTION         13

>  #define TCP_CA_NAME_MAX                16

> --

> 2.30.2

>