linux/tools/testing/selftests/bpf/test_progs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/* Copyright (c) 2017 Facebook
   3 */
   4#include "test_progs.h"
   5#include "bpf_rlimit.h"
   6
   7int error_cnt, pass_cnt;
   8bool jit_enabled;
   9bool verifier_stats = false;
  10
  11struct ipv4_packet pkt_v4 = {
  12        .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
  13        .iph.ihl = 5,
  14        .iph.protocol = IPPROTO_TCP,
  15        .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
  16        .tcp.urg_ptr = 123,
  17        .tcp.doff = 5,
  18};
  19
  20struct ipv6_packet pkt_v6 = {
  21        .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
  22        .iph.nexthdr = IPPROTO_TCP,
  23        .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
  24        .tcp.urg_ptr = 123,
  25        .tcp.doff = 5,
  26};
  27
  28int bpf_find_map(const char *test, struct bpf_object *obj, const char *name)
  29{
  30        struct bpf_map *map;
  31
  32        map = bpf_object__find_map_by_name(obj, name);
  33        if (!map) {
  34                printf("%s:FAIL:map '%s' not found\n", test, name);
  35                error_cnt++;
  36                return -1;
  37        }
  38        return bpf_map__fd(map);
  39}
  40
  41static bool is_jit_enabled(void)
  42{
  43        const char *jit_sysctl = "/proc/sys/net/core/bpf_jit_enable";
  44        bool enabled = false;
  45        int sysctl_fd;
  46
  47        sysctl_fd = open(jit_sysctl, 0, O_RDONLY);
  48        if (sysctl_fd != -1) {
  49                char tmpc;
  50
  51                if (read(sysctl_fd, &tmpc, sizeof(tmpc)) == 1)
  52                        enabled = (tmpc != '0');
  53                close(sysctl_fd);
  54        }
  55
  56        return enabled;
  57}
  58
  59int compare_map_keys(int map1_fd, int map2_fd)
  60{
  61        __u32 key, next_key;
  62        char val_buf[PERF_MAX_STACK_DEPTH *
  63                     sizeof(struct bpf_stack_build_id)];
  64        int err;
  65
  66        err = bpf_map_get_next_key(map1_fd, NULL, &key);
  67        if (err)
  68                return err;
  69        err = bpf_map_lookup_elem(map2_fd, &key, val_buf);
  70        if (err)
  71                return err;
  72
  73        while (bpf_map_get_next_key(map1_fd, &key, &next_key) == 0) {
  74                err = bpf_map_lookup_elem(map2_fd, &next_key, val_buf);
  75                if (err)
  76                        return err;
  77
  78                key = next_key;
  79        }
  80        if (errno != ENOENT)
  81                return -1;
  82
  83        return 0;
  84}
  85
  86int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len)
  87{
  88        __u32 key, next_key, *cur_key_p, *next_key_p;
  89        char *val_buf1, *val_buf2;
  90        int i, err = 0;
  91
  92        val_buf1 = malloc(stack_trace_len);
  93        val_buf2 = malloc(stack_trace_len);
  94        cur_key_p = NULL;
  95        next_key_p = &key;
  96        while (bpf_map_get_next_key(smap_fd, cur_key_p, next_key_p) == 0) {
  97                err = bpf_map_lookup_elem(smap_fd, next_key_p, val_buf1);
  98                if (err)
  99                        goto out;
 100                err = bpf_map_lookup_elem(amap_fd, next_key_p, val_buf2);
 101                if (err)
 102                        goto out;
 103                for (i = 0; i < stack_trace_len; i++) {
 104                        if (val_buf1[i] != val_buf2[i]) {
 105                                err = -1;
 106                                goto out;
 107                        }
 108                }
 109                key = *next_key_p;
 110                cur_key_p = &key;
 111                next_key_p = &next_key;
 112        }
 113        if (errno != ENOENT)
 114                err = -1;
 115
 116out:
 117        free(val_buf1);
 118        free(val_buf2);
 119        return err;
 120}
 121
 122int extract_build_id(char *build_id, size_t size)
 123{
 124        FILE *fp;
 125        char *line = NULL;
 126        size_t len = 0;
 127
 128        fp = popen("readelf -n ./urandom_read | grep 'Build ID'", "r");
 129        if (fp == NULL)
 130                return -1;
 131
 132        if (getline(&line, &len, fp) == -1)
 133                goto err;
 134        fclose(fp);
 135
 136        if (len > size)
 137                len = size;
 138        memcpy(build_id, line, len);
 139        build_id[len] = '\0';
 140        return 0;
 141err:
 142        fclose(fp);
 143        return -1;
 144}
 145
 146void *spin_lock_thread(void *arg)
 147{
 148        __u32 duration, retval;
 149        int err, prog_fd = *(u32 *) arg;
 150
 151        err = bpf_prog_test_run(prog_fd, 10000, &pkt_v4, sizeof(pkt_v4),
 152                                NULL, NULL, &retval, &duration);
 153        CHECK(err || retval, "",
 154              "err %d errno %d retval %d duration %d\n",
 155              err, errno, retval, duration);
 156        pthread_exit(arg);
 157}
 158
 159#define DECLARE
 160#include <prog_tests/tests.h>
 161#undef DECLARE
 162
 163int main(int ac, char **av)
 164{
 165        srand(time(NULL));
 166
 167        jit_enabled = is_jit_enabled();
 168
 169        if (ac == 2 && strcmp(av[1], "-s") == 0)
 170                verifier_stats = true;
 171
 172#define CALL
 173#include <prog_tests/tests.h>
 174#undef CALL
 175
 176        printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt);
 177        return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
 178}
 179