linux/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2019 Facebook */
   3#include <test_progs.h>
   4
   5static void test_fexit_bpf2bpf_common(const char *obj_file,
   6                                      const char *target_obj_file,
   7                                      int prog_cnt,
   8                                      const char **prog_name)
   9{
  10        struct bpf_object *obj = NULL, *pkt_obj;
  11        int err, pkt_fd, i;
  12        struct bpf_link **link = NULL;
  13        struct bpf_program **prog = NULL;
  14        __u32 duration = 0, retval;
  15        struct bpf_map *data_map;
  16        const int zero = 0;
  17        u64 *result = NULL;
  18
  19        err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
  20                            &pkt_obj, &pkt_fd);
  21        if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
  22                return;
  23        DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
  24                            .attach_prog_fd = pkt_fd,
  25                           );
  26
  27        link = calloc(sizeof(struct bpf_link *), prog_cnt);
  28        prog = calloc(sizeof(struct bpf_program *), prog_cnt);
  29        result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64));
  30        if (CHECK(!link || !prog || !result, "alloc_memory",
  31                  "failed to alloc memory"))
  32                goto close_prog;
  33
  34        obj = bpf_object__open_file(obj_file, &opts);
  35        if (CHECK(IS_ERR_OR_NULL(obj), "obj_open",
  36                  "failed to open fexit_bpf2bpf: %ld\n",
  37                  PTR_ERR(obj)))
  38                goto close_prog;
  39
  40        err = bpf_object__load(obj);
  41        if (CHECK(err, "obj_load", "err %d\n", err))
  42                goto close_prog;
  43
  44        for (i = 0; i < prog_cnt; i++) {
  45                prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]);
  46                if (CHECK(!prog[i], "find_prog", "prog %s not found\n", prog_name[i]))
  47                        goto close_prog;
  48                link[i] = bpf_program__attach_trace(prog[i]);
  49                if (CHECK(IS_ERR(link[i]), "attach_trace", "failed to link\n"))
  50                        goto close_prog;
  51        }
  52        data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss");
  53        if (CHECK(!data_map, "find_data_map", "data map not found\n"))
  54                goto close_prog;
  55
  56        err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6),
  57                                NULL, NULL, &retval, &duration);
  58        CHECK(err || retval, "ipv6",
  59              "err %d errno %d retval %d duration %d\n",
  60              err, errno, retval, duration);
  61
  62        err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result);
  63        if (CHECK(err, "get_result",
  64                  "failed to get output data: %d\n", err))
  65                goto close_prog;
  66
  67        for (i = 0; i < prog_cnt; i++)
  68                if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n",
  69                          result[i]))
  70                        goto close_prog;
  71
  72close_prog:
  73        for (i = 0; i < prog_cnt; i++)
  74                if (!IS_ERR_OR_NULL(link[i]))
  75                        bpf_link__destroy(link[i]);
  76        if (!IS_ERR_OR_NULL(obj))
  77                bpf_object__close(obj);
  78        bpf_object__close(pkt_obj);
  79        free(link);
  80        free(prog);
  81        free(result);
  82}
  83
  84static void test_target_no_callees(void)
  85{
  86        const char *prog_name[] = {
  87                "fexit/test_pkt_md_access",
  88        };
  89        test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o",
  90                                  "./test_pkt_md_access.o",
  91                                  ARRAY_SIZE(prog_name),
  92                                  prog_name);
  93}
  94
  95static void test_target_yes_callees(void)
  96{
  97        const char *prog_name[] = {
  98                "fexit/test_pkt_access",
  99                "fexit/test_pkt_access_subprog1",
 100                "fexit/test_pkt_access_subprog2",
 101                "fexit/test_pkt_access_subprog3",
 102        };
 103        test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
 104                                  "./test_pkt_access.o",
 105                                  ARRAY_SIZE(prog_name),
 106                                  prog_name);
 107}
 108
 109static void test_func_replace(void)
 110{
 111        const char *prog_name[] = {
 112                "fexit/test_pkt_access",
 113                "fexit/test_pkt_access_subprog1",
 114                "fexit/test_pkt_access_subprog2",
 115                "fexit/test_pkt_access_subprog3",
 116                "freplace/get_skb_len",
 117                "freplace/get_skb_ifindex",
 118                "freplace/get_constant",
 119        };
 120        test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o",
 121                                  "./test_pkt_access.o",
 122                                  ARRAY_SIZE(prog_name),
 123                                  prog_name);
 124}
 125
 126void test_fexit_bpf2bpf(void)
 127{
 128        test_target_no_callees();
 129        test_target_yes_callees();
 130        test_func_replace();
 131}
 132