linux/tools/testing/selftests/bpf/prog_tests/for_each.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2021 Facebook */
   3#include <test_progs.h>
   4#include <network_helpers.h>
   5#include "for_each_hash_map_elem.skel.h"
   6#include "for_each_array_map_elem.skel.h"
   7
   8static unsigned int duration;
   9
  10static void test_hash_map(void)
  11{
  12        int i, err, hashmap_fd, max_entries, percpu_map_fd;
  13        struct for_each_hash_map_elem *skel;
  14        __u64 *percpu_valbuf = NULL;
  15        __u32 key, num_cpus, retval;
  16        __u64 val;
  17
  18        skel = for_each_hash_map_elem__open_and_load();
  19        if (!ASSERT_OK_PTR(skel, "for_each_hash_map_elem__open_and_load"))
  20                return;
  21
  22        hashmap_fd = bpf_map__fd(skel->maps.hashmap);
  23        max_entries = bpf_map__max_entries(skel->maps.hashmap);
  24        for (i = 0; i < max_entries; i++) {
  25                key = i;
  26                val = i + 1;
  27                err = bpf_map_update_elem(hashmap_fd, &key, &val, BPF_ANY);
  28                if (!ASSERT_OK(err, "map_update"))
  29                        goto out;
  30        }
  31
  32        num_cpus = bpf_num_possible_cpus();
  33        percpu_map_fd = bpf_map__fd(skel->maps.percpu_map);
  34        percpu_valbuf = malloc(sizeof(__u64) * num_cpus);
  35        if (!ASSERT_OK_PTR(percpu_valbuf, "percpu_valbuf"))
  36                goto out;
  37
  38        key = 1;
  39        for (i = 0; i < num_cpus; i++)
  40                percpu_valbuf[i] = i + 1;
  41        err = bpf_map_update_elem(percpu_map_fd, &key, percpu_valbuf, BPF_ANY);
  42        if (!ASSERT_OK(err, "percpu_map_update"))
  43                goto out;
  44
  45        err = bpf_prog_test_run(bpf_program__fd(skel->progs.test_pkt_access),
  46                                1, &pkt_v4, sizeof(pkt_v4), NULL, NULL,
  47                                &retval, &duration);
  48        if (CHECK(err || retval, "ipv4", "err %d errno %d retval %d\n",
  49                  err, errno, retval))
  50                goto out;
  51
  52        ASSERT_EQ(skel->bss->hashmap_output, 4, "hashmap_output");
  53        ASSERT_EQ(skel->bss->hashmap_elems, max_entries, "hashmap_elems");
  54
  55        key = 1;
  56        err = bpf_map_lookup_elem(hashmap_fd, &key, &val);
  57        ASSERT_ERR(err, "hashmap_lookup");
  58
  59        ASSERT_EQ(skel->bss->percpu_called, 1, "percpu_called");
  60        ASSERT_LT(skel->bss->cpu, num_cpus, "num_cpus");
  61        ASSERT_EQ(skel->bss->percpu_map_elems, 1, "percpu_map_elems");
  62        ASSERT_EQ(skel->bss->percpu_key, 1, "percpu_key");
  63        ASSERT_EQ(skel->bss->percpu_val, skel->bss->cpu + 1, "percpu_val");
  64        ASSERT_EQ(skel->bss->percpu_output, 100, "percpu_output");
  65out:
  66        free(percpu_valbuf);
  67        for_each_hash_map_elem__destroy(skel);
  68}
  69
  70static void test_array_map(void)
  71{
  72        __u32 key, num_cpus, max_entries, retval;
  73        int i, arraymap_fd, percpu_map_fd, err;
  74        struct for_each_array_map_elem *skel;
  75        __u64 *percpu_valbuf = NULL;
  76        __u64 val, expected_total;
  77
  78        skel = for_each_array_map_elem__open_and_load();
  79        if (!ASSERT_OK_PTR(skel, "for_each_array_map_elem__open_and_load"))
  80                return;
  81
  82        arraymap_fd = bpf_map__fd(skel->maps.arraymap);
  83        expected_total = 0;
  84        max_entries = bpf_map__max_entries(skel->maps.arraymap);
  85        for (i = 0; i < max_entries; i++) {
  86                key = i;
  87                val = i + 1;
  88                /* skip the last iteration for expected total */
  89                if (i != max_entries - 1)
  90                        expected_total += val;
  91                err = bpf_map_update_elem(arraymap_fd, &key, &val, BPF_ANY);
  92                if (!ASSERT_OK(err, "map_update"))
  93                        goto out;
  94        }
  95
  96        num_cpus = bpf_num_possible_cpus();
  97        percpu_map_fd = bpf_map__fd(skel->maps.percpu_map);
  98        percpu_valbuf = malloc(sizeof(__u64) * num_cpus);
  99        if (!ASSERT_OK_PTR(percpu_valbuf, "percpu_valbuf"))
 100                goto out;
 101
 102        key = 0;
 103        for (i = 0; i < num_cpus; i++)
 104                percpu_valbuf[i] = i + 1;
 105        err = bpf_map_update_elem(percpu_map_fd, &key, percpu_valbuf, BPF_ANY);
 106        if (!ASSERT_OK(err, "percpu_map_update"))
 107                goto out;
 108
 109        err = bpf_prog_test_run(bpf_program__fd(skel->progs.test_pkt_access),
 110                                1, &pkt_v4, sizeof(pkt_v4), NULL, NULL,
 111                                &retval, &duration);
 112        if (CHECK(err || retval, "ipv4", "err %d errno %d retval %d\n",
 113                  err, errno, retval))
 114                goto out;
 115
 116        ASSERT_EQ(skel->bss->arraymap_output, expected_total, "array_output");
 117        ASSERT_EQ(skel->bss->cpu + 1, skel->bss->percpu_val, "percpu_val");
 118
 119out:
 120        free(percpu_valbuf);
 121        for_each_array_map_elem__destroy(skel);
 122}
 123
 124void test_for_each(void)
 125{
 126        if (test__start_subtest("hash_map"))
 127                test_hash_map();
 128        if (test__start_subtest("array_map"))
 129                test_array_map();
 130}
 131