linux/tools/testing/selftests/bpf/test_maps.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Testsuite for eBPF maps
   4 *
   5 * Copyright (c) 2014 PLUMgrid, http://plumgrid.com
   6 * Copyright (c) 2016 Facebook
   7 */
   8
   9#include <stdio.h>
  10#include <unistd.h>
  11#include <errno.h>
  12#include <string.h>
  13#include <assert.h>
  14#include <stdlib.h>
  15#include <time.h>
  16
  17#include <sys/wait.h>
  18#include <sys/socket.h>
  19#include <netinet/in.h>
  20#include <linux/bpf.h>
  21
  22#include <bpf/bpf.h>
  23#include <bpf/libbpf.h>
  24
  25#include "bpf_util.h"
  26#include "test_maps.h"
  27#include "testing_helpers.h"
  28
  29#ifndef ENOTSUPP
  30#define ENOTSUPP 524
  31#endif
  32
  33static int skips;
  34
  35static struct bpf_map_create_opts map_opts = { .sz = sizeof(map_opts) };
  36
  37static void test_hashmap(unsigned int task, void *data)
  38{
  39        long long key, next_key, first_key, value;
  40        int fd;
  41
  42        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(key), sizeof(value), 2, &map_opts);
  43        if (fd < 0) {
  44                printf("Failed to create hashmap '%s'!\n", strerror(errno));
  45                exit(1);
  46        }
  47
  48        key = 1;
  49        value = 1234;
  50        /* Insert key=1 element. */
  51        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
  52
  53        value = 0;
  54        /* BPF_NOEXIST means add new element if it doesn't exist. */
  55        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
  56               /* key=1 already exists. */
  57               errno == EEXIST);
  58
  59        /* -1 is an invalid flag. */
  60        assert(bpf_map_update_elem(fd, &key, &value, -1) < 0 &&
  61               errno == EINVAL);
  62
  63        /* Check that key=1 can be found. */
  64        assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
  65
  66        key = 2;
  67        value = 1234;
  68        /* Insert key=2 element. */
  69        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
  70
  71        /* Check that key=2 matches the value and delete it */
  72        assert(bpf_map_lookup_and_delete_elem(fd, &key, &value) == 0 && value == 1234);
  73
  74        /* Check that key=2 is not found. */
  75        assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
  76
  77        /* BPF_EXIST means update existing element. */
  78        assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) < 0 &&
  79               /* key=2 is not there. */
  80               errno == ENOENT);
  81
  82        /* Insert key=2 element. */
  83        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
  84
  85        /* key=1 and key=2 were inserted, check that key=0 cannot be
  86         * inserted due to max_entries limit.
  87         */
  88        key = 0;
  89        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
  90               errno == E2BIG);
  91
  92        /* Update existing element, though the map is full. */
  93        key = 1;
  94        assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
  95        key = 2;
  96        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
  97        key = 3;
  98        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
  99               errno == E2BIG);
 100
 101        /* Check that key = 0 doesn't exist. */
 102        key = 0;
 103        assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
 104
 105        /* Iterate over two elements. */
 106        assert(bpf_map_get_next_key(fd, NULL, &first_key) == 0 &&
 107               (first_key == 1 || first_key == 2));
 108        assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
 109               (next_key == first_key));
 110        assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
 111               (next_key == 1 || next_key == 2) &&
 112               (next_key != first_key));
 113        assert(bpf_map_get_next_key(fd, &next_key, &next_key) < 0 &&
 114               errno == ENOENT);
 115
 116        /* Delete both elements. */
 117        key = 1;
 118        assert(bpf_map_delete_elem(fd, &key) == 0);
 119        key = 2;
 120        assert(bpf_map_delete_elem(fd, &key) == 0);
 121        assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
 122
 123        key = 0;
 124        /* Check that map is empty. */
 125        assert(bpf_map_get_next_key(fd, NULL, &next_key) < 0 &&
 126               errno == ENOENT);
 127        assert(bpf_map_get_next_key(fd, &key, &next_key) < 0 &&
 128               errno == ENOENT);
 129
 130        close(fd);
 131}
 132
 133static void test_hashmap_sizes(unsigned int task, void *data)
 134{
 135        int fd, i, j;
 136
 137        for (i = 1; i <= 512; i <<= 1)
 138                for (j = 1; j <= 1 << 18; j <<= 1) {
 139                        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, i, j, 2, &map_opts);
 140                        if (fd < 0) {
 141                                if (errno == ENOMEM)
 142                                        return;
 143                                printf("Failed to create hashmap key=%d value=%d '%s'\n",
 144                                       i, j, strerror(errno));
 145                                exit(1);
 146                        }
 147                        close(fd);
 148                        usleep(10); /* give kernel time to destroy */
 149                }
 150}
 151
 152static void test_hashmap_percpu(unsigned int task, void *data)
 153{
 154        unsigned int nr_cpus = bpf_num_possible_cpus();
 155        BPF_DECLARE_PERCPU(long, value);
 156        long long key, next_key, first_key;
 157        int expected_key_mask = 0;
 158        int fd, i;
 159
 160        fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_HASH, NULL, sizeof(key),
 161                            sizeof(bpf_percpu(value, 0)), 2, &map_opts);
 162        if (fd < 0) {
 163                printf("Failed to create hashmap '%s'!\n", strerror(errno));
 164                exit(1);
 165        }
 166
 167        for (i = 0; i < nr_cpus; i++)
 168                bpf_percpu(value, i) = i + 100;
 169
 170        key = 1;
 171        /* Insert key=1 element. */
 172        assert(!(expected_key_mask & key));
 173        assert(bpf_map_update_elem(fd, &key, value, BPF_ANY) == 0);
 174
 175        /* Lookup and delete elem key=1 and check value. */
 176        assert(bpf_map_lookup_and_delete_elem(fd, &key, value) == 0 &&
 177               bpf_percpu(value,0) == 100);
 178
 179        for (i = 0; i < nr_cpus; i++)
 180                bpf_percpu(value,i) = i + 100;
 181
 182        /* Insert key=1 element which should not exist. */
 183        assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
 184        expected_key_mask |= key;
 185
 186        /* BPF_NOEXIST means add new element if it doesn't exist. */
 187        assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) < 0 &&
 188               /* key=1 already exists. */
 189               errno == EEXIST);
 190
 191        /* -1 is an invalid flag. */
 192        assert(bpf_map_update_elem(fd, &key, value, -1) < 0 &&
 193               errno == EINVAL);
 194
 195        /* Check that key=1 can be found. Value could be 0 if the lookup
 196         * was run from a different CPU.
 197         */
 198        bpf_percpu(value, 0) = 1;
 199        assert(bpf_map_lookup_elem(fd, &key, value) == 0 &&
 200               bpf_percpu(value, 0) == 100);
 201
 202        key = 2;
 203        /* Check that key=2 is not found. */
 204        assert(bpf_map_lookup_elem(fd, &key, value) < 0 && errno == ENOENT);
 205
 206        /* BPF_EXIST means update existing element. */
 207        assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) < 0 &&
 208               /* key=2 is not there. */
 209               errno == ENOENT);
 210
 211        /* Insert key=2 element. */
 212        assert(!(expected_key_mask & key));
 213        assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
 214        expected_key_mask |= key;
 215
 216        /* key=1 and key=2 were inserted, check that key=0 cannot be
 217         * inserted due to max_entries limit.
 218         */
 219        key = 0;
 220        assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) < 0 &&
 221               errno == E2BIG);
 222
 223        /* Check that key = 0 doesn't exist. */
 224        assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
 225
 226        /* Iterate over two elements. */
 227        assert(bpf_map_get_next_key(fd, NULL, &first_key) == 0 &&
 228               ((expected_key_mask & first_key) == first_key));
 229        while (!bpf_map_get_next_key(fd, &key, &next_key)) {
 230                if (first_key) {
 231                        assert(next_key == first_key);
 232                        first_key = 0;
 233                }
 234                assert((expected_key_mask & next_key) == next_key);
 235                expected_key_mask &= ~next_key;
 236
 237                assert(bpf_map_lookup_elem(fd, &next_key, value) == 0);
 238
 239                for (i = 0; i < nr_cpus; i++)
 240                        assert(bpf_percpu(value, i) == i + 100);
 241
 242                key = next_key;
 243        }
 244        assert(errno == ENOENT);
 245
 246        /* Update with BPF_EXIST. */
 247        key = 1;
 248        assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == 0);
 249
 250        /* Delete both elements. */
 251        key = 1;
 252        assert(bpf_map_delete_elem(fd, &key) == 0);
 253        key = 2;
 254        assert(bpf_map_delete_elem(fd, &key) == 0);
 255        assert(bpf_map_delete_elem(fd, &key) < 0 && errno == ENOENT);
 256
 257        key = 0;
 258        /* Check that map is empty. */
 259        assert(bpf_map_get_next_key(fd, NULL, &next_key) < 0 &&
 260               errno == ENOENT);
 261        assert(bpf_map_get_next_key(fd, &key, &next_key) < 0 &&
 262               errno == ENOENT);
 263
 264        close(fd);
 265}
 266
 267static int helper_fill_hashmap(int max_entries)
 268{
 269        int i, fd, ret;
 270        long long key, value;
 271
 272        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(key), sizeof(value),
 273                            max_entries, &map_opts);
 274        CHECK(fd < 0,
 275              "failed to create hashmap",
 276              "err: %s, flags: 0x%x\n", strerror(errno), map_opts.map_flags);
 277
 278        for (i = 0; i < max_entries; i++) {
 279                key = i; value = key;
 280                ret = bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST);
 281                CHECK(ret != 0,
 282                      "can't update hashmap",
 283                      "err: %s\n", strerror(ret));
 284        }
 285
 286        return fd;
 287}
 288
 289static void test_hashmap_walk(unsigned int task, void *data)
 290{
 291        int fd, i, max_entries = 1000;
 292        long long key, value, next_key;
 293        bool next_key_valid = true;
 294
 295        fd = helper_fill_hashmap(max_entries);
 296
 297        for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
 298                                         &next_key) == 0; i++) {
 299                key = next_key;
 300                assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
 301        }
 302
 303        assert(i == max_entries);
 304
 305        assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
 306        for (i = 0; next_key_valid; i++) {
 307                next_key_valid = bpf_map_get_next_key(fd, &key, &next_key) == 0;
 308                assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
 309                value++;
 310                assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
 311                key = next_key;
 312        }
 313
 314        assert(i == max_entries);
 315
 316        for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
 317                                         &next_key) == 0; i++) {
 318                key = next_key;
 319                assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
 320                assert(value - 1 == key);
 321        }
 322
 323        assert(i == max_entries);
 324        close(fd);
 325}
 326
 327static void test_hashmap_zero_seed(void)
 328{
 329        int i, first, second, old_flags;
 330        long long key, next_first, next_second;
 331
 332        old_flags = map_opts.map_flags;
 333        map_opts.map_flags |= BPF_F_ZERO_SEED;
 334
 335        first = helper_fill_hashmap(3);
 336        second = helper_fill_hashmap(3);
 337
 338        for (i = 0; ; i++) {
 339                void *key_ptr = !i ? NULL : &key;
 340
 341                if (bpf_map_get_next_key(first, key_ptr, &next_first) != 0)
 342                        break;
 343
 344                CHECK(bpf_map_get_next_key(second, key_ptr, &next_second) != 0,
 345                      "next_key for second map must succeed",
 346                      "key_ptr: %p", key_ptr);
 347                CHECK(next_first != next_second,
 348                      "keys must match",
 349                      "i: %d first: %lld second: %lld\n", i,
 350                      next_first, next_second);
 351
 352                key = next_first;
 353        }
 354
 355        map_opts.map_flags = old_flags;
 356        close(first);
 357        close(second);
 358}
 359
 360static void test_arraymap(unsigned int task, void *data)
 361{
 362        int key, next_key, fd;
 363        long long value;
 364
 365        fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(key), sizeof(value), 2, NULL);
 366        if (fd < 0) {
 367                printf("Failed to create arraymap '%s'!\n", strerror(errno));
 368                exit(1);
 369        }
 370
 371        key = 1;
 372        value = 1234;
 373        /* Insert key=1 element. */
 374        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
 375
 376        value = 0;
 377        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
 378               errno == EEXIST);
 379
 380        /* Check that key=1 can be found. */
 381        assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
 382
 383        key = 0;
 384        /* Check that key=0 is also found and zero initialized. */
 385        assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
 386
 387        /* key=0 and key=1 were inserted, check that key=2 cannot be inserted
 388         * due to max_entries limit.
 389         */
 390        key = 2;
 391        assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) < 0 &&
 392               errno == E2BIG);
 393
 394        /* Check that key = 2 doesn't exist. */
 395        assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
 396
 397        /* Iterate over two elements. */
 398        assert(bpf_map_get_next_key(fd, NULL, &next_key) == 0 &&
 399               next_key == 0);
 400        assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
 401               next_key == 0);
 402        assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
 403               next_key == 1);
 404        assert(bpf_map_get_next_key(fd, &next_key, &next_key) < 0 &&
 405               errno == ENOENT);
 406
 407        /* Delete shouldn't succeed. */
 408        key = 1;
 409        assert(bpf_map_delete_elem(fd, &key) < 0 && errno == EINVAL);
 410
 411        close(fd);
 412}
 413
 414static void test_arraymap_percpu(unsigned int task, void *data)
 415{
 416        unsigned int nr_cpus = bpf_num_possible_cpus();
 417        BPF_DECLARE_PERCPU(long, values);
 418        int key, next_key, fd, i;
 419
 420        fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, NULL, sizeof(key),
 421                            sizeof(bpf_percpu(values, 0)), 2, NULL);
 422        if (fd < 0) {
 423                printf("Failed to create arraymap '%s'!\n", strerror(errno));
 424                exit(1);
 425        }
 426
 427        for (i = 0; i < nr_cpus; i++)
 428                bpf_percpu(values, i) = i + 100;
 429
 430        key = 1;
 431        /* Insert key=1 element. */
 432        assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
 433
 434        bpf_percpu(values, 0) = 0;
 435        assert(bpf_map_update_elem(fd, &key, values, BPF_NOEXIST) < 0 &&
 436               errno == EEXIST);
 437
 438        /* Check that key=1 can be found. */
 439        assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
 440               bpf_percpu(values, 0) == 100);
 441
 442        key = 0;
 443        /* Check that key=0 is also found and zero initialized. */
 444        assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
 445               bpf_percpu(values, 0) == 0 &&
 446               bpf_percpu(values, nr_cpus - 1) == 0);
 447
 448        /* Check that key=2 cannot be inserted due to max_entries limit. */
 449        key = 2;
 450        assert(bpf_map_update_elem(fd, &key, values, BPF_EXIST) < 0 &&
 451               errno == E2BIG);
 452
 453        /* Check that key = 2 doesn't exist. */
 454        assert(bpf_map_lookup_elem(fd, &key, values) < 0 && errno == ENOENT);
 455
 456        /* Iterate over two elements. */
 457        assert(bpf_map_get_next_key(fd, NULL, &next_key) == 0 &&
 458               next_key == 0);
 459        assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
 460               next_key == 0);
 461        assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
 462               next_key == 1);
 463        assert(bpf_map_get_next_key(fd, &next_key, &next_key) < 0 &&
 464               errno == ENOENT);
 465
 466        /* Delete shouldn't succeed. */
 467        key = 1;
 468        assert(bpf_map_delete_elem(fd, &key) < 0 && errno == EINVAL);
 469
 470        close(fd);
 471}
 472
 473static void test_arraymap_percpu_many_keys(void)
 474{
 475        unsigned int nr_cpus = bpf_num_possible_cpus();
 476        BPF_DECLARE_PERCPU(long, values);
 477        /* nr_keys is not too large otherwise the test stresses percpu
 478         * allocator more than anything else
 479         */
 480        unsigned int nr_keys = 2000;
 481        int key, fd, i;
 482
 483        fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, NULL, sizeof(key),
 484                            sizeof(bpf_percpu(values, 0)), nr_keys, NULL);
 485        if (fd < 0) {
 486                printf("Failed to create per-cpu arraymap '%s'!\n",
 487                       strerror(errno));
 488                exit(1);
 489        }
 490
 491        for (i = 0; i < nr_cpus; i++)
 492                bpf_percpu(values, i) = i + 10;
 493
 494        for (key = 0; key < nr_keys; key++)
 495                assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
 496
 497        for (key = 0; key < nr_keys; key++) {
 498                for (i = 0; i < nr_cpus; i++)
 499                        bpf_percpu(values, i) = 0;
 500
 501                assert(bpf_map_lookup_elem(fd, &key, values) == 0);
 502
 503                for (i = 0; i < nr_cpus; i++)
 504                        assert(bpf_percpu(values, i) == i + 10);
 505        }
 506
 507        close(fd);
 508}
 509
 510static void test_devmap(unsigned int task, void *data)
 511{
 512        int fd;
 513        __u32 key, value;
 514
 515        fd = bpf_map_create(BPF_MAP_TYPE_DEVMAP, NULL, sizeof(key), sizeof(value), 2, NULL);
 516        if (fd < 0) {
 517                printf("Failed to create devmap '%s'!\n", strerror(errno));
 518                exit(1);
 519        }
 520
 521        close(fd);
 522}
 523
 524static void test_devmap_hash(unsigned int task, void *data)
 525{
 526        int fd;
 527        __u32 key, value;
 528
 529        fd = bpf_map_create(BPF_MAP_TYPE_DEVMAP_HASH, NULL, sizeof(key), sizeof(value), 2, NULL);
 530        if (fd < 0) {
 531                printf("Failed to create devmap_hash '%s'!\n", strerror(errno));
 532                exit(1);
 533        }
 534
 535        close(fd);
 536}
 537
 538static void test_queuemap(unsigned int task, void *data)
 539{
 540        const int MAP_SIZE = 32;
 541        __u32 vals[MAP_SIZE + MAP_SIZE/2], val;
 542        int fd, i;
 543
 544        /* Fill test values to be used */
 545        for (i = 0; i < MAP_SIZE + MAP_SIZE/2; i++)
 546                vals[i] = rand();
 547
 548        /* Invalid key size */
 549        fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, NULL, 4, sizeof(val), MAP_SIZE, &map_opts);
 550        assert(fd < 0 && errno == EINVAL);
 551
 552        fd = bpf_map_create(BPF_MAP_TYPE_QUEUE, NULL, 0, sizeof(val), MAP_SIZE, &map_opts);
 553        /* Queue map does not support BPF_F_NO_PREALLOC */
 554        if (map_opts.map_flags & BPF_F_NO_PREALLOC) {
 555                assert(fd < 0 && errno == EINVAL);
 556                return;
 557        }
 558        if (fd < 0) {
 559                printf("Failed to create queuemap '%s'!\n", strerror(errno));
 560                exit(1);
 561        }
 562
 563        /* Push MAP_SIZE elements */
 564        for (i = 0; i < MAP_SIZE; i++)
 565                assert(bpf_map_update_elem(fd, NULL, &vals[i], 0) == 0);
 566
 567        /* Check that element cannot be pushed due to max_entries limit */
 568        assert(bpf_map_update_elem(fd, NULL, &val, 0) < 0 &&
 569               errno == E2BIG);
 570
 571        /* Peek element */
 572        assert(bpf_map_lookup_elem(fd, NULL, &val) == 0 && val == vals[0]);
 573
 574        /* Replace half elements */
 575        for (i = MAP_SIZE; i < MAP_SIZE + MAP_SIZE/2; i++)
 576                assert(bpf_map_update_elem(fd, NULL, &vals[i], BPF_EXIST) == 0);
 577
 578        /* Pop all elements */
 579        for (i = MAP_SIZE/2; i < MAP_SIZE + MAP_SIZE/2; i++)
 580                assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == 0 &&
 581                       val == vals[i]);
 582
 583        /* Check that there are not elements left */
 584        assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) < 0 &&
 585               errno == ENOENT);
 586
 587        /* Check that non supported functions set errno to EINVAL */
 588        assert(bpf_map_delete_elem(fd, NULL) < 0 && errno == EINVAL);
 589        assert(bpf_map_get_next_key(fd, NULL, NULL) < 0 && errno == EINVAL);
 590
 591        close(fd);
 592}
 593
 594static void test_stackmap(unsigned int task, void *data)
 595{
 596        const int MAP_SIZE = 32;
 597        __u32 vals[MAP_SIZE + MAP_SIZE/2], val;
 598        int fd, i;
 599
 600        /* Fill test values to be used */
 601        for (i = 0; i < MAP_SIZE + MAP_SIZE/2; i++)
 602                vals[i] = rand();
 603
 604        /* Invalid key size */
 605        fd = bpf_map_create(BPF_MAP_TYPE_STACK, NULL, 4, sizeof(val), MAP_SIZE, &map_opts);
 606        assert(fd < 0 && errno == EINVAL);
 607
 608        fd = bpf_map_create(BPF_MAP_TYPE_STACK, NULL, 0, sizeof(val), MAP_SIZE, &map_opts);
 609        /* Stack map does not support BPF_F_NO_PREALLOC */
 610        if (map_opts.map_flags & BPF_F_NO_PREALLOC) {
 611                assert(fd < 0 && errno == EINVAL);
 612                return;
 613        }
 614        if (fd < 0) {
 615                printf("Failed to create stackmap '%s'!\n", strerror(errno));
 616                exit(1);
 617        }
 618
 619        /* Push MAP_SIZE elements */
 620        for (i = 0; i < MAP_SIZE; i++)
 621                assert(bpf_map_update_elem(fd, NULL, &vals[i], 0) == 0);
 622
 623        /* Check that element cannot be pushed due to max_entries limit */
 624        assert(bpf_map_update_elem(fd, NULL, &val, 0) < 0 &&
 625               errno == E2BIG);
 626
 627        /* Peek element */
 628        assert(bpf_map_lookup_elem(fd, NULL, &val) == 0 && val == vals[i - 1]);
 629
 630        /* Replace half elements */
 631        for (i = MAP_SIZE; i < MAP_SIZE + MAP_SIZE/2; i++)
 632                assert(bpf_map_update_elem(fd, NULL, &vals[i], BPF_EXIST) == 0);
 633
 634        /* Pop all elements */
 635        for (i = MAP_SIZE + MAP_SIZE/2 - 1; i >= MAP_SIZE/2; i--)
 636                assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) == 0 &&
 637                       val == vals[i]);
 638
 639        /* Check that there are not elements left */
 640        assert(bpf_map_lookup_and_delete_elem(fd, NULL, &val) < 0 &&
 641               errno == ENOENT);
 642
 643        /* Check that non supported functions set errno to EINVAL */
 644        assert(bpf_map_delete_elem(fd, NULL) < 0 && errno == EINVAL);
 645        assert(bpf_map_get_next_key(fd, NULL, NULL) < 0 && errno == EINVAL);
 646
 647        close(fd);
 648}
 649
 650#include <sys/ioctl.h>
 651#include <arpa/inet.h>
 652#include <sys/select.h>
 653#include <linux/err.h>
 654#define SOCKMAP_PARSE_PROG "./sockmap_parse_prog.o"
 655#define SOCKMAP_VERDICT_PROG "./sockmap_verdict_prog.o"
 656#define SOCKMAP_TCP_MSG_PROG "./sockmap_tcp_msg_prog.o"
 657static void test_sockmap(unsigned int tasks, void *data)
 658{
 659        struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_msg, *bpf_map_break;
 660        int map_fd_msg = 0, map_fd_rx = 0, map_fd_tx = 0, map_fd_break;
 661        int ports[] = {50200, 50201, 50202, 50204};
 662        int err, i, fd, udp, sfd[6] = {0xdeadbeef};
 663        u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0};
 664        int parse_prog, verdict_prog, msg_prog;
 665        struct sockaddr_in addr;
 666        int one = 1, s, sc, rc;
 667        struct bpf_object *obj;
 668        struct timeval to;
 669        __u32 key, value;
 670        pid_t pid[tasks];
 671        fd_set w;
 672
 673        /* Create some sockets to use with sockmap */
 674        for (i = 0; i < 2; i++) {
 675                sfd[i] = socket(AF_INET, SOCK_STREAM, 0);
 676                if (sfd[i] < 0)
 677                        goto out;
 678                err = setsockopt(sfd[i], SOL_SOCKET, SO_REUSEADDR,
 679                                 (char *)&one, sizeof(one));
 680                if (err) {
 681                        printf("failed to setsockopt\n");
 682                        goto out;
 683                }
 684                err = ioctl(sfd[i], FIONBIO, (char *)&one);
 685                if (err < 0) {
 686                        printf("failed to ioctl\n");
 687                        goto out;
 688                }
 689                memset(&addr, 0, sizeof(struct sockaddr_in));
 690                addr.sin_family = AF_INET;
 691                addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 692                addr.sin_port = htons(ports[i]);
 693                err = bind(sfd[i], (struct sockaddr *)&addr, sizeof(addr));
 694                if (err < 0) {
 695                        printf("failed to bind: err %i: %i:%i\n",
 696                               err, i, sfd[i]);
 697                        goto out;
 698                }
 699                err = listen(sfd[i], 32);
 700                if (err < 0) {
 701                        printf("failed to listen\n");
 702                        goto out;
 703                }
 704        }
 705
 706        for (i = 2; i < 4; i++) {
 707                sfd[i] = socket(AF_INET, SOCK_STREAM, 0);
 708                if (sfd[i] < 0)
 709                        goto out;
 710                err = setsockopt(sfd[i], SOL_SOCKET, SO_REUSEADDR,
 711                                 (char *)&one, sizeof(one));
 712                if (err) {
 713                        printf("set sock opt\n");
 714                        goto out;
 715                }
 716                memset(&addr, 0, sizeof(struct sockaddr_in));
 717                addr.sin_family = AF_INET;
 718                addr.sin_addr.s_addr = inet_addr("127.0.0.1");
 719                addr.sin_port = htons(ports[i - 2]);
 720                err = connect(sfd[i], (struct sockaddr *)&addr, sizeof(addr));
 721                if (err) {
 722                        printf("failed to connect\n");
 723                        goto out;
 724                }
 725        }
 726
 727
 728        for (i = 4; i < 6; i++) {
 729                sfd[i] = accept(sfd[i - 4], NULL, NULL);
 730                if (sfd[i] < 0) {
 731                        printf("accept failed\n");
 732                        goto out;
 733                }
 734        }
 735
 736        /* Test sockmap with connected sockets */
 737        fd = bpf_map_create(BPF_MAP_TYPE_SOCKMAP, NULL,
 738                            sizeof(key), sizeof(value),
 739                            6, NULL);
 740        if (fd < 0) {
 741                if (!libbpf_probe_bpf_map_type(BPF_MAP_TYPE_SOCKMAP, NULL)) {
 742                        printf("%s SKIP (unsupported map type BPF_MAP_TYPE_SOCKMAP)\n",
 743                               __func__);
 744                        skips++;
 745                        for (i = 0; i < 6; i++)
 746                                close(sfd[i]);
 747                        return;
 748                }
 749
 750                printf("Failed to create sockmap %i\n", fd);
 751                goto out_sockmap;
 752        }
 753
 754        /* Test update with unsupported UDP socket */
 755        udp = socket(AF_INET, SOCK_DGRAM, 0);
 756        i = 0;
 757        err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY);
 758        if (err) {
 759                printf("Failed socket update SOCK_DGRAM '%i:%i'\n",
 760                       i, udp);
 761                goto out_sockmap;
 762        }
 763
 764        /* Test update without programs */
 765        for (i = 0; i < 6; i++) {
 766                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
 767                if (err) {
 768                        printf("Failed noprog update sockmap '%i:%i'\n",
 769                               i, sfd[i]);
 770                        goto out_sockmap;
 771                }
 772        }
 773
 774        /* Test attaching/detaching bad fds */
 775        err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);
 776        if (!err) {
 777                printf("Failed invalid parser prog attach\n");
 778                goto out_sockmap;
 779        }
 780
 781        err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_VERDICT, 0);
 782        if (!err) {
 783                printf("Failed invalid verdict prog attach\n");
 784                goto out_sockmap;
 785        }
 786
 787        err = bpf_prog_attach(-1, fd, BPF_SK_MSG_VERDICT, 0);
 788        if (!err) {
 789                printf("Failed invalid msg verdict prog attach\n");
 790                goto out_sockmap;
 791        }
 792
 793        err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
 794        if (!err) {
 795                printf("Failed unknown prog attach\n");
 796                goto out_sockmap;
 797        }
 798
 799        err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER);
 800        if (!err) {
 801                printf("Failed empty parser prog detach\n");
 802                goto out_sockmap;
 803        }
 804
 805        err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT);
 806        if (!err) {
 807                printf("Failed empty verdict prog detach\n");
 808                goto out_sockmap;
 809        }
 810
 811        err = bpf_prog_detach(fd, BPF_SK_MSG_VERDICT);
 812        if (!err) {
 813                printf("Failed empty msg verdict prog detach\n");
 814                goto out_sockmap;
 815        }
 816
 817        err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
 818        if (!err) {
 819                printf("Detach invalid prog successful\n");
 820                goto out_sockmap;
 821        }
 822
 823        /* Load SK_SKB program and Attach */
 824        err = bpf_prog_test_load(SOCKMAP_PARSE_PROG,
 825                            BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
 826        if (err) {
 827                printf("Failed to load SK_SKB parse prog\n");
 828                goto out_sockmap;
 829        }
 830
 831        err = bpf_prog_test_load(SOCKMAP_TCP_MSG_PROG,
 832                            BPF_PROG_TYPE_SK_MSG, &obj, &msg_prog);
 833        if (err) {
 834                printf("Failed to load SK_SKB msg prog\n");
 835                goto out_sockmap;
 836        }
 837
 838        err = bpf_prog_test_load(SOCKMAP_VERDICT_PROG,
 839                            BPF_PROG_TYPE_SK_SKB, &obj, &verdict_prog);
 840        if (err) {
 841                printf("Failed to load SK_SKB verdict prog\n");
 842                goto out_sockmap;
 843        }
 844
 845        bpf_map_rx = bpf_object__find_map_by_name(obj, "sock_map_rx");
 846        if (!bpf_map_rx) {
 847                printf("Failed to load map rx from verdict prog\n");
 848                goto out_sockmap;
 849        }
 850
 851        map_fd_rx = bpf_map__fd(bpf_map_rx);
 852        if (map_fd_rx < 0) {
 853                printf("Failed to get map rx fd\n");
 854                goto out_sockmap;
 855        }
 856
 857        bpf_map_tx = bpf_object__find_map_by_name(obj, "sock_map_tx");
 858        if (!bpf_map_tx) {
 859                printf("Failed to load map tx from verdict prog\n");
 860                goto out_sockmap;
 861        }
 862
 863        map_fd_tx = bpf_map__fd(bpf_map_tx);
 864        if (map_fd_tx < 0) {
 865                printf("Failed to get map tx fd\n");
 866                goto out_sockmap;
 867        }
 868
 869        bpf_map_msg = bpf_object__find_map_by_name(obj, "sock_map_msg");
 870        if (!bpf_map_msg) {
 871                printf("Failed to load map msg from msg_verdict prog\n");
 872                goto out_sockmap;
 873        }
 874
 875        map_fd_msg = bpf_map__fd(bpf_map_msg);
 876        if (map_fd_msg < 0) {
 877                printf("Failed to get map msg fd\n");
 878                goto out_sockmap;
 879        }
 880
 881        bpf_map_break = bpf_object__find_map_by_name(obj, "sock_map_break");
 882        if (!bpf_map_break) {
 883                printf("Failed to load map tx from verdict prog\n");
 884                goto out_sockmap;
 885        }
 886
 887        map_fd_break = bpf_map__fd(bpf_map_break);
 888        if (map_fd_break < 0) {
 889                printf("Failed to get map tx fd\n");
 890                goto out_sockmap;
 891        }
 892
 893        err = bpf_prog_attach(parse_prog, map_fd_break,
 894                              BPF_SK_SKB_STREAM_PARSER, 0);
 895        if (!err) {
 896                printf("Allowed attaching SK_SKB program to invalid map\n");
 897                goto out_sockmap;
 898        }
 899
 900        err = bpf_prog_attach(parse_prog, map_fd_rx,
 901                      BPF_SK_SKB_STREAM_PARSER, 0);
 902        if (err) {
 903                printf("Failed stream parser bpf prog attach\n");
 904                goto out_sockmap;
 905        }
 906
 907        err = bpf_prog_attach(verdict_prog, map_fd_rx,
 908                              BPF_SK_SKB_STREAM_VERDICT, 0);
 909        if (err) {
 910                printf("Failed stream verdict bpf prog attach\n");
 911                goto out_sockmap;
 912        }
 913
 914        err = bpf_prog_attach(msg_prog, map_fd_msg, BPF_SK_MSG_VERDICT, 0);
 915        if (err) {
 916                printf("Failed msg verdict bpf prog attach\n");
 917                goto out_sockmap;
 918        }
 919
 920        err = bpf_prog_attach(verdict_prog, map_fd_rx,
 921                              __MAX_BPF_ATTACH_TYPE, 0);
 922        if (!err) {
 923                printf("Attached unknown bpf prog\n");
 924                goto out_sockmap;
 925        }
 926
 927        /* Test map update elem afterwards fd lives in fd and map_fd */
 928        for (i = 2; i < 6; i++) {
 929                err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
 930                if (err) {
 931                        printf("Failed map_fd_rx update sockmap %i '%i:%i'\n",
 932                               err, i, sfd[i]);
 933                        goto out_sockmap;
 934                }
 935                err = bpf_map_update_elem(map_fd_tx, &i, &sfd[i], BPF_ANY);
 936                if (err) {
 937                        printf("Failed map_fd_tx update sockmap %i '%i:%i'\n",
 938                               err, i, sfd[i]);
 939                        goto out_sockmap;
 940                }
 941        }
 942
 943        /* Test map delete elem and remove send/recv sockets */
 944        for (i = 2; i < 4; i++) {
 945                err = bpf_map_delete_elem(map_fd_rx, &i);
 946                if (err) {
 947                        printf("Failed delete sockmap rx %i '%i:%i'\n",
 948                               err, i, sfd[i]);
 949                        goto out_sockmap;
 950                }
 951                err = bpf_map_delete_elem(map_fd_tx, &i);
 952                if (err) {
 953                        printf("Failed delete sockmap tx %i '%i:%i'\n",
 954                               err, i, sfd[i]);
 955                        goto out_sockmap;
 956                }
 957        }
 958
 959        /* Put sfd[2] (sending fd below) into msg map to test sendmsg bpf */
 960        i = 0;
 961        err = bpf_map_update_elem(map_fd_msg, &i, &sfd[2], BPF_ANY);
 962        if (err) {
 963                printf("Failed map_fd_msg update sockmap %i\n", err);
 964                goto out_sockmap;
 965        }
 966
 967        /* Test map send/recv */
 968        for (i = 0; i < 2; i++) {
 969                buf[0] = i;
 970                buf[1] = 0x5;
 971                sc = send(sfd[2], buf, 20, 0);
 972                if (sc < 0) {
 973                        printf("Failed sockmap send\n");
 974                        goto out_sockmap;
 975                }
 976
 977                FD_ZERO(&w);
 978                FD_SET(sfd[3], &w);
 979                to.tv_sec = 30;
 980                to.tv_usec = 0;
 981                s = select(sfd[3] + 1, &w, NULL, NULL, &to);
 982                if (s == -1) {
 983                        perror("Failed sockmap select()");
 984                        goto out_sockmap;
 985                } else if (!s) {
 986                        printf("Failed sockmap unexpected timeout\n");
 987                        goto out_sockmap;
 988                }
 989
 990                if (!FD_ISSET(sfd[3], &w)) {
 991                        printf("Failed sockmap select/recv\n");
 992                        goto out_sockmap;
 993                }
 994
 995                rc = recv(sfd[3], buf, sizeof(buf), 0);
 996                if (rc < 0) {
 997                        printf("Failed sockmap recv\n");
 998                        goto out_sockmap;
 999                }
1000        }
1001
1002        /* Negative null entry lookup from datapath should be dropped */
1003        buf[0] = 1;
1004        buf[1] = 12;
1005        sc = send(sfd[2], buf, 20, 0);
1006        if (sc < 0) {
1007                printf("Failed sockmap send\n");
1008                goto out_sockmap;
1009        }
1010
1011        /* Push fd into same slot */
1012        i = 2;
1013        err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
1014        if (!err) {
1015                printf("Failed allowed sockmap dup slot BPF_NOEXIST\n");
1016                goto out_sockmap;
1017        }
1018
1019        err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
1020        if (err) {
1021                printf("Failed sockmap update new slot BPF_ANY\n");
1022                goto out_sockmap;
1023        }
1024
1025        err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
1026        if (err) {
1027                printf("Failed sockmap update new slot BPF_EXIST\n");
1028                goto out_sockmap;
1029        }
1030
1031        /* Delete the elems without programs */
1032        for (i = 2; i < 6; i++) {
1033                err = bpf_map_delete_elem(fd, &i);
1034                if (err) {
1035                        printf("Failed delete sockmap %i '%i:%i'\n",
1036                               err, i, sfd[i]);
1037                }
1038        }
1039
1040        /* Test having multiple maps open and set with programs on same fds */
1041        err = bpf_prog_attach(parse_prog, fd,
1042                              BPF_SK_SKB_STREAM_PARSER, 0);
1043        if (err) {
1044                printf("Failed fd bpf parse prog attach\n");
1045                goto out_sockmap;
1046        }
1047        err = bpf_prog_attach(verdict_prog, fd,
1048                              BPF_SK_SKB_STREAM_VERDICT, 0);
1049        if (err) {
1050                printf("Failed fd bpf verdict prog attach\n");
1051                goto out_sockmap;
1052        }
1053
1054        for (i = 4; i < 6; i++) {
1055                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
1056                if (!err) {
1057                        printf("Failed allowed duplicate programs in update ANY sockmap %i '%i:%i'\n",
1058                               err, i, sfd[i]);
1059                        goto out_sockmap;
1060                }
1061                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_NOEXIST);
1062                if (!err) {
1063                        printf("Failed allowed duplicate program in update NOEXIST sockmap  %i '%i:%i'\n",
1064                               err, i, sfd[i]);
1065                        goto out_sockmap;
1066                }
1067                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_EXIST);
1068                if (!err) {
1069                        printf("Failed allowed duplicate program in update EXIST sockmap  %i '%i:%i'\n",
1070                               err, i, sfd[i]);
1071                        goto out_sockmap;
1072                }
1073        }
1074
1075        /* Test tasks number of forked operations */
1076        for (i = 0; i < tasks; i++) {
1077                pid[i] = fork();
1078                if (pid[i] == 0) {
1079                        for (i = 0; i < 6; i++) {
1080                                bpf_map_delete_elem(map_fd_tx, &i);
1081                                bpf_map_delete_elem(map_fd_rx, &i);
1082                                bpf_map_update_elem(map_fd_tx, &i,
1083                                                    &sfd[i], BPF_ANY);
1084                                bpf_map_update_elem(map_fd_rx, &i,
1085                                                    &sfd[i], BPF_ANY);
1086                        }
1087                        exit(0);
1088                } else if (pid[i] == -1) {
1089                        printf("Couldn't spawn #%d process!\n", i);
1090                        exit(1);
1091                }
1092        }
1093
1094        for (i = 0; i < tasks; i++) {
1095                int status;
1096
1097                assert(waitpid(pid[i], &status, 0) == pid[i]);
1098                assert(status == 0);
1099        }
1100
1101        err = bpf_prog_detach2(parse_prog, map_fd_rx, __MAX_BPF_ATTACH_TYPE);
1102        if (!err) {
1103                printf("Detached an invalid prog type.\n");
1104                goto out_sockmap;
1105        }
1106
1107        err = bpf_prog_detach2(parse_prog, map_fd_rx, BPF_SK_SKB_STREAM_PARSER);
1108        if (err) {
1109                printf("Failed parser prog detach\n");
1110                goto out_sockmap;
1111        }
1112
1113        err = bpf_prog_detach2(verdict_prog, map_fd_rx, BPF_SK_SKB_STREAM_VERDICT);
1114        if (err) {
1115                printf("Failed parser prog detach\n");
1116                goto out_sockmap;
1117        }
1118
1119        /* Test map close sockets and empty maps */
1120        for (i = 0; i < 6; i++) {
1121                bpf_map_delete_elem(map_fd_tx, &i);
1122                bpf_map_delete_elem(map_fd_rx, &i);
1123                close(sfd[i]);
1124        }
1125        close(fd);
1126        close(map_fd_rx);
1127        bpf_object__close(obj);
1128        return;
1129out:
1130        for (i = 0; i < 6; i++)
1131                close(sfd[i]);
1132        printf("Failed to create sockmap '%i:%s'!\n", i, strerror(errno));
1133        exit(1);
1134out_sockmap:
1135        for (i = 0; i < 6; i++) {
1136                if (map_fd_tx)
1137                        bpf_map_delete_elem(map_fd_tx, &i);
1138                if (map_fd_rx)
1139                        bpf_map_delete_elem(map_fd_rx, &i);
1140                close(sfd[i]);
1141        }
1142        close(fd);
1143        exit(1);
1144}
1145
1146#define MAPINMAP_PROG "./test_map_in_map.o"
1147#define MAPINMAP_INVALID_PROG "./test_map_in_map_invalid.o"
1148static void test_map_in_map(void)
1149{
1150        struct bpf_object *obj;
1151        struct bpf_map *map;
1152        int mim_fd, fd, err;
1153        int pos = 0;
1154        struct bpf_map_info info = {};
1155        __u32 len = sizeof(info);
1156        __u32 id = 0;
1157        libbpf_print_fn_t old_print_fn;
1158
1159        obj = bpf_object__open(MAPINMAP_PROG);
1160
1161        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(int), sizeof(int), 2, NULL);
1162        if (fd < 0) {
1163                printf("Failed to create hashmap '%s'!\n", strerror(errno));
1164                exit(1);
1165        }
1166
1167        map = bpf_object__find_map_by_name(obj, "mim_array");
1168        if (!map) {
1169                printf("Failed to load array of maps from test prog\n");
1170                goto out_map_in_map;
1171        }
1172        err = bpf_map__set_inner_map_fd(map, fd);
1173        if (err) {
1174                printf("Failed to set inner_map_fd for array of maps\n");
1175                goto out_map_in_map;
1176        }
1177
1178        map = bpf_object__find_map_by_name(obj, "mim_hash");
1179        if (!map) {
1180                printf("Failed to load hash of maps from test prog\n");
1181                goto out_map_in_map;
1182        }
1183        err = bpf_map__set_inner_map_fd(map, fd);
1184        if (err) {
1185                printf("Failed to set inner_map_fd for hash of maps\n");
1186                goto out_map_in_map;
1187        }
1188
1189        bpf_object__load(obj);
1190
1191        map = bpf_object__find_map_by_name(obj, "mim_array");
1192        if (!map) {
1193                printf("Failed to load array of maps from test prog\n");
1194                goto out_map_in_map;
1195        }
1196        mim_fd = bpf_map__fd(map);
1197        if (mim_fd < 0) {
1198                printf("Failed to get descriptor for array of maps\n");
1199                goto out_map_in_map;
1200        }
1201
1202        err = bpf_map_update_elem(mim_fd, &pos, &fd, 0);
1203        if (err) {
1204                printf("Failed to update array of maps\n");
1205                goto out_map_in_map;
1206        }
1207
1208        map = bpf_object__find_map_by_name(obj, "mim_hash");
1209        if (!map) {
1210                printf("Failed to load hash of maps from test prog\n");
1211                goto out_map_in_map;
1212        }
1213        mim_fd = bpf_map__fd(map);
1214        if (mim_fd < 0) {
1215                printf("Failed to get descriptor for hash of maps\n");
1216                goto out_map_in_map;
1217        }
1218
1219        err = bpf_map_update_elem(mim_fd, &pos, &fd, 0);
1220        if (err) {
1221                printf("Failed to update hash of maps\n");
1222                goto out_map_in_map;
1223        }
1224
1225        close(fd);
1226        fd = -1;
1227        bpf_object__close(obj);
1228
1229        /* Test that failing bpf_object__create_map() destroys the inner map */
1230        obj = bpf_object__open(MAPINMAP_INVALID_PROG);
1231        err = libbpf_get_error(obj);
1232        if (err) {
1233                printf("Failed to load %s program: %d %d",
1234                       MAPINMAP_INVALID_PROG, err, errno);
1235                goto out_map_in_map;
1236        }
1237
1238        map = bpf_object__find_map_by_name(obj, "mim");
1239        if (!map) {
1240                printf("Failed to load array of maps from test prog\n");
1241                goto out_map_in_map;
1242        }
1243
1244        old_print_fn = libbpf_set_print(NULL);
1245
1246        err = bpf_object__load(obj);
1247        if (!err) {
1248                printf("Loading obj supposed to fail\n");
1249                goto out_map_in_map;
1250        }
1251
1252        libbpf_set_print(old_print_fn);
1253
1254        /* Iterate over all maps to check whether the internal map
1255         * ("mim.internal") has been destroyed.
1256         */
1257        while (true) {
1258                err = bpf_map_get_next_id(id, &id);
1259                if (err) {
1260                        if (errno == ENOENT)
1261                                break;
1262                        printf("Failed to get next map: %d", errno);
1263                        goto out_map_in_map;
1264                }
1265
1266                fd = bpf_map_get_fd_by_id(id);
1267                if (fd < 0) {
1268                        if (errno == ENOENT)
1269                                continue;
1270                        printf("Failed to get map by id %u: %d", id, errno);
1271                        goto out_map_in_map;
1272                }
1273
1274                err = bpf_obj_get_info_by_fd(fd, &info, &len);
1275                if (err) {
1276                        printf("Failed to get map info by fd %d: %d", fd,
1277                               errno);
1278                        goto out_map_in_map;
1279                }
1280
1281                if (!strcmp(info.name, "mim.inner")) {
1282                        printf("Inner map mim.inner was not destroyed\n");
1283                        goto out_map_in_map;
1284                }
1285        }
1286
1287        return;
1288
1289out_map_in_map:
1290        if (fd >= 0)
1291                close(fd);
1292        exit(1);
1293}
1294
1295#define MAP_SIZE (32 * 1024)
1296
1297static void test_map_large(void)
1298{
1299
1300        struct bigkey {
1301                int a;
1302                char b[4096];
1303                long long c;
1304        } key;
1305        int fd, i, value;
1306
1307        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(key), sizeof(value),
1308                            MAP_SIZE, &map_opts);
1309        if (fd < 0) {
1310                printf("Failed to create large map '%s'!\n", strerror(errno));
1311                exit(1);
1312        }
1313
1314        for (i = 0; i < MAP_SIZE; i++) {
1315                key = (struct bigkey) { .c = i };
1316                value = i;
1317
1318                assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
1319        }
1320
1321        key.c = -1;
1322        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
1323               errno == E2BIG);
1324
1325        /* Iterate through all elements. */
1326        assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
1327        key.c = -1;
1328        for (i = 0; i < MAP_SIZE; i++)
1329                assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1330        assert(bpf_map_get_next_key(fd, &key, &key) < 0 && errno == ENOENT);
1331
1332        key.c = 0;
1333        assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
1334        key.a = 1;
1335        assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
1336
1337        close(fd);
1338}
1339
1340#define run_parallel(N, FN, DATA) \
1341        printf("Fork %u tasks to '" #FN "'\n", N); \
1342        __run_parallel(N, FN, DATA)
1343
1344static void __run_parallel(unsigned int tasks,
1345                           void (*fn)(unsigned int task, void *data),
1346                           void *data)
1347{
1348        pid_t pid[tasks];
1349        int i;
1350
1351        fflush(stdout);
1352
1353        for (i = 0; i < tasks; i++) {
1354                pid[i] = fork();
1355                if (pid[i] == 0) {
1356                        fn(i, data);
1357                        exit(0);
1358                } else if (pid[i] == -1) {
1359                        printf("Couldn't spawn #%d process!\n", i);
1360                        exit(1);
1361                }
1362        }
1363
1364        for (i = 0; i < tasks; i++) {
1365                int status;
1366
1367                assert(waitpid(pid[i], &status, 0) == pid[i]);
1368                assert(status == 0);
1369        }
1370}
1371
1372static void test_map_stress(void)
1373{
1374        run_parallel(100, test_hashmap, NULL);
1375        run_parallel(100, test_hashmap_percpu, NULL);
1376        run_parallel(100, test_hashmap_sizes, NULL);
1377        run_parallel(100, test_hashmap_walk, NULL);
1378
1379        run_parallel(100, test_arraymap, NULL);
1380        run_parallel(100, test_arraymap_percpu, NULL);
1381}
1382
1383#define TASKS 1024
1384
1385#define DO_UPDATE 1
1386#define DO_DELETE 0
1387
1388#define MAP_RETRIES 20
1389#define MAX_DELAY_US 50000
1390#define MIN_DELAY_RANGE_US 5000
1391
1392static int map_update_retriable(int map_fd, const void *key, const void *value,
1393                                int flags, int attempts)
1394{
1395        int delay = rand() % MIN_DELAY_RANGE_US;
1396
1397        while (bpf_map_update_elem(map_fd, key, value, flags)) {
1398                if (!attempts || (errno != EAGAIN && errno != EBUSY))
1399                        return -errno;
1400
1401                if (delay <= MAX_DELAY_US / 2)
1402                        delay *= 2;
1403
1404                usleep(delay);
1405                attempts--;
1406        }
1407
1408        return 0;
1409}
1410
1411static int map_delete_retriable(int map_fd, const void *key, int attempts)
1412{
1413        int delay = rand() % MIN_DELAY_RANGE_US;
1414
1415        while (bpf_map_delete_elem(map_fd, key)) {
1416                if (!attempts || (errno != EAGAIN && errno != EBUSY))
1417                        return -errno;
1418
1419                if (delay <= MAX_DELAY_US / 2)
1420                        delay *= 2;
1421
1422                usleep(delay);
1423                attempts--;
1424        }
1425
1426        return 0;
1427}
1428
1429static void test_update_delete(unsigned int fn, void *data)
1430{
1431        int do_update = ((int *)data)[1];
1432        int fd = ((int *)data)[0];
1433        int i, key, value, err;
1434
1435        for (i = fn; i < MAP_SIZE; i += TASKS) {
1436                key = value = i;
1437
1438                if (do_update) {
1439                        err = map_update_retriable(fd, &key, &value, BPF_NOEXIST, MAP_RETRIES);
1440                        if (err)
1441                                printf("error %d %d\n", err, errno);
1442                        assert(err == 0);
1443                        err = map_update_retriable(fd, &key, &value, BPF_EXIST, MAP_RETRIES);
1444                        if (err)
1445                                printf("error %d %d\n", err, errno);
1446                        assert(err == 0);
1447                } else {
1448                        err = map_delete_retriable(fd, &key, MAP_RETRIES);
1449                        if (err)
1450                                printf("error %d %d\n", err, errno);
1451                        assert(err == 0);
1452                }
1453        }
1454}
1455
1456static void test_map_parallel(void)
1457{
1458        int i, fd, key = 0, value = 0;
1459        int data[2];
1460
1461        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(key), sizeof(value),
1462                            MAP_SIZE, &map_opts);
1463        if (fd < 0) {
1464                printf("Failed to create map for parallel test '%s'!\n",
1465                       strerror(errno));
1466                exit(1);
1467        }
1468
1469        /* Use the same fd in children to add elements to this map:
1470         * child_0 adds key=0, key=1024, key=2048, ...
1471         * child_1 adds key=1, key=1025, key=2049, ...
1472         * child_1023 adds key=1023, ...
1473         */
1474        data[0] = fd;
1475        data[1] = DO_UPDATE;
1476        run_parallel(TASKS, test_update_delete, data);
1477
1478        /* Check that key=0 is already there. */
1479        assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) < 0 &&
1480               errno == EEXIST);
1481
1482        /* Check that all elements were inserted. */
1483        assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
1484        key = -1;
1485        for (i = 0; i < MAP_SIZE; i++)
1486                assert(bpf_map_get_next_key(fd, &key, &key) == 0);
1487        assert(bpf_map_get_next_key(fd, &key, &key) < 0 && errno == ENOENT);
1488
1489        /* Another check for all elements */
1490        for (i = 0; i < MAP_SIZE; i++) {
1491                key = MAP_SIZE - i - 1;
1492
1493                assert(bpf_map_lookup_elem(fd, &key, &value) == 0 &&
1494                       value == key);
1495        }
1496
1497        /* Now let's delete all elemenets in parallel. */
1498        data[1] = DO_DELETE;
1499        run_parallel(TASKS, test_update_delete, data);
1500
1501        /* Nothing should be left. */
1502        key = -1;
1503        assert(bpf_map_get_next_key(fd, NULL, &key) < 0 && errno == ENOENT);
1504        assert(bpf_map_get_next_key(fd, &key, &key) < 0 && errno == ENOENT);
1505}
1506
1507static void test_map_rdonly(void)
1508{
1509        int fd, key = 0, value = 0;
1510        __u32 old_flags;
1511
1512        old_flags = map_opts.map_flags;
1513        map_opts.map_flags |= BPF_F_RDONLY;
1514        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(key), sizeof(value),
1515                            MAP_SIZE, &map_opts);
1516        map_opts.map_flags = old_flags;
1517        if (fd < 0) {
1518                printf("Failed to create map for read only test '%s'!\n",
1519                       strerror(errno));
1520                exit(1);
1521        }
1522
1523        key = 1;
1524        value = 1234;
1525        /* Try to insert key=1 element. */
1526        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) < 0 &&
1527               errno == EPERM);
1528
1529        /* Check that key=1 is not found. */
1530        assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == ENOENT);
1531        assert(bpf_map_get_next_key(fd, &key, &value) < 0 && errno == ENOENT);
1532
1533        close(fd);
1534}
1535
1536static void test_map_wronly_hash(void)
1537{
1538        int fd, key = 0, value = 0;
1539        __u32 old_flags;
1540
1541        old_flags = map_opts.map_flags;
1542        map_opts.map_flags |= BPF_F_WRONLY;
1543        fd = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, sizeof(key), sizeof(value),
1544                            MAP_SIZE, &map_opts);
1545        map_opts.map_flags = old_flags;
1546        if (fd < 0) {
1547                printf("Failed to create map for write only test '%s'!\n",
1548                       strerror(errno));
1549                exit(1);
1550        }
1551
1552        key = 1;
1553        value = 1234;
1554        /* Insert key=1 element. */
1555        assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
1556
1557        /* Check that reading elements and keys from the map is not allowed. */
1558        assert(bpf_map_lookup_elem(fd, &key, &value) < 0 && errno == EPERM);
1559        assert(bpf_map_get_next_key(fd, &key, &value) < 0 && errno == EPERM);
1560
1561        close(fd);
1562}
1563
1564static void test_map_wronly_stack_or_queue(enum bpf_map_type map_type)
1565{
1566        int fd, value = 0;
1567        __u32 old_flags;
1568
1569
1570        assert(map_type == BPF_MAP_TYPE_QUEUE ||
1571               map_type == BPF_MAP_TYPE_STACK);
1572        old_flags = map_opts.map_flags;
1573        map_opts.map_flags |= BPF_F_WRONLY;
1574        fd = bpf_map_create(map_type, NULL, 0, sizeof(value), MAP_SIZE, &map_opts);
1575        map_opts.map_flags = old_flags;
1576        /* Stack/Queue maps do not support BPF_F_NO_PREALLOC */
1577        if (map_opts.map_flags & BPF_F_NO_PREALLOC) {
1578                assert(fd < 0 && errno == EINVAL);
1579                return;
1580        }
1581        if (fd < 0) {
1582                printf("Failed to create map '%s'!\n", strerror(errno));
1583                exit(1);
1584        }
1585
1586        value = 1234;
1587        assert(bpf_map_update_elem(fd, NULL, &value, BPF_ANY) == 0);
1588
1589        /* Peek element should fail */
1590        assert(bpf_map_lookup_elem(fd, NULL, &value) < 0 && errno == EPERM);
1591
1592        /* Pop element should fail */
1593        assert(bpf_map_lookup_and_delete_elem(fd, NULL, &value) < 0 &&
1594               errno == EPERM);
1595
1596        close(fd);
1597}
1598
1599static void test_map_wronly(void)
1600{
1601        test_map_wronly_hash();
1602        test_map_wronly_stack_or_queue(BPF_MAP_TYPE_STACK);
1603        test_map_wronly_stack_or_queue(BPF_MAP_TYPE_QUEUE);
1604}
1605
1606static void prepare_reuseport_grp(int type, int map_fd, size_t map_elem_size,
1607                                  __s64 *fds64, __u64 *sk_cookies,
1608                                  unsigned int n)
1609{
1610        socklen_t optlen, addrlen;
1611        struct sockaddr_in6 s6;
1612        const __u32 index0 = 0;
1613        const int optval = 1;
1614        unsigned int i;
1615        u64 sk_cookie;
1616        void *value;
1617        __s32 fd32;
1618        __s64 fd64;
1619        int err;
1620
1621        s6.sin6_family = AF_INET6;
1622        s6.sin6_addr = in6addr_any;
1623        s6.sin6_port = 0;
1624        addrlen = sizeof(s6);
1625        optlen = sizeof(sk_cookie);
1626
1627        for (i = 0; i < n; i++) {
1628                fd64 = socket(AF_INET6, type, 0);
1629                CHECK(fd64 == -1, "socket()",
1630                      "sock_type:%d fd64:%lld errno:%d\n",
1631                      type, fd64, errno);
1632
1633                err = setsockopt(fd64, SOL_SOCKET, SO_REUSEPORT,
1634                                 &optval, sizeof(optval));
1635                CHECK(err == -1, "setsockopt(SO_REUSEPORT)",
1636                      "err:%d errno:%d\n", err, errno);
1637
1638                /* reuseport_array does not allow unbound sk */
1639                if (map_elem_size == sizeof(__u64))
1640                        value = &fd64;
1641                else {
1642                        assert(map_elem_size == sizeof(__u32));
1643                        fd32 = (__s32)fd64;
1644                        value = &fd32;
1645                }
1646                err = bpf_map_update_elem(map_fd, &index0, value, BPF_ANY);
1647                CHECK(err >= 0 || errno != EINVAL,
1648                      "reuseport array update unbound sk",
1649                      "sock_type:%d err:%d errno:%d\n",
1650                      type, err, errno);
1651
1652                err = bind(fd64, (struct sockaddr *)&s6, sizeof(s6));
1653                CHECK(err == -1, "bind()",
1654                      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1655
1656                if (i == 0) {
1657                        err = getsockname(fd64, (struct sockaddr *)&s6,
1658                                          &addrlen);
1659                        CHECK(err == -1, "getsockname()",
1660                              "sock_type:%d err:%d errno:%d\n",
1661                              type, err, errno);
1662                }
1663
1664                err = getsockopt(fd64, SOL_SOCKET, SO_COOKIE, &sk_cookie,
1665                                 &optlen);
1666                CHECK(err == -1, "getsockopt(SO_COOKIE)",
1667                      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1668
1669                if (type == SOCK_STREAM) {
1670                        /*
1671                         * reuseport_array does not allow
1672                         * non-listening tcp sk.
1673                         */
1674                        err = bpf_map_update_elem(map_fd, &index0, value,
1675                                                  BPF_ANY);
1676                        CHECK(err >= 0 || errno != EINVAL,
1677                              "reuseport array update non-listening sk",
1678                              "sock_type:%d err:%d errno:%d\n",
1679                              type, err, errno);
1680                        err = listen(fd64, 0);
1681                        CHECK(err == -1, "listen()",
1682                              "sock_type:%d, err:%d errno:%d\n",
1683                              type, err, errno);
1684                }
1685
1686                fds64[i] = fd64;
1687                sk_cookies[i] = sk_cookie;
1688        }
1689}
1690
1691static void test_reuseport_array(void)
1692{
1693#define REUSEPORT_FD_IDX(err, last) ({ (err) ? last : !last; })
1694
1695        const __u32 array_size = 4, index0 = 0, index3 = 3;
1696        int types[2] = { SOCK_STREAM, SOCK_DGRAM }, type;
1697        __u64 grpa_cookies[2], sk_cookie, map_cookie;
1698        __s64 grpa_fds64[2] = { -1, -1 }, fd64 = -1;
1699        const __u32 bad_index = array_size;
1700        int map_fd, err, t, f;
1701        __u32 fds_idx = 0;
1702        int fd;
1703
1704        map_fd = bpf_map_create(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, NULL,
1705                                sizeof(__u32), sizeof(__u64), array_size, NULL);
1706        CHECK(map_fd < 0, "reuseport array create",
1707              "map_fd:%d, errno:%d\n", map_fd, errno);
1708
1709        /* Test lookup/update/delete with invalid index */
1710        err = bpf_map_delete_elem(map_fd, &bad_index);
1711        CHECK(err >= 0 || errno != E2BIG, "reuseport array del >=max_entries",
1712              "err:%d errno:%d\n", err, errno);
1713
1714        err = bpf_map_update_elem(map_fd, &bad_index, &fd64, BPF_ANY);
1715        CHECK(err >= 0 || errno != E2BIG,
1716              "reuseport array update >=max_entries",
1717              "err:%d errno:%d\n", err, errno);
1718
1719        err = bpf_map_lookup_elem(map_fd, &bad_index, &map_cookie);
1720        CHECK(err >= 0 || errno != ENOENT,
1721              "reuseport array update >=max_entries",
1722              "err:%d errno:%d\n", err, errno);
1723
1724        /* Test lookup/delete non existence elem */
1725        err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1726        CHECK(err >= 0 || errno != ENOENT,
1727              "reuseport array lookup not-exist elem",
1728              "err:%d errno:%d\n", err, errno);
1729        err = bpf_map_delete_elem(map_fd, &index3);
1730        CHECK(err >= 0 || errno != ENOENT,
1731              "reuseport array del not-exist elem",
1732              "err:%d errno:%d\n", err, errno);
1733
1734        for (t = 0; t < ARRAY_SIZE(types); t++) {
1735                type = types[t];
1736
1737                prepare_reuseport_grp(type, map_fd, sizeof(__u64), grpa_fds64,
1738                                      grpa_cookies, ARRAY_SIZE(grpa_fds64));
1739
1740                /* Test BPF_* update flags */
1741                /* BPF_EXIST failure case */
1742                err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1743                                          BPF_EXIST);
1744                CHECK(err >= 0 || errno != ENOENT,
1745                      "reuseport array update empty elem BPF_EXIST",
1746                      "sock_type:%d err:%d errno:%d\n",
1747                      type, err, errno);
1748                fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1749
1750                /* BPF_NOEXIST success case */
1751                err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1752                                          BPF_NOEXIST);
1753                CHECK(err < 0,
1754                      "reuseport array update empty elem BPF_NOEXIST",
1755                      "sock_type:%d err:%d errno:%d\n",
1756                      type, err, errno);
1757                fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1758
1759                /* BPF_EXIST success case. */
1760                err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1761                                          BPF_EXIST);
1762                CHECK(err < 0,
1763                      "reuseport array update same elem BPF_EXIST",
1764                      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1765                fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1766
1767                /* BPF_NOEXIST failure case */
1768                err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1769                                          BPF_NOEXIST);
1770                CHECK(err >= 0 || errno != EEXIST,
1771                      "reuseport array update non-empty elem BPF_NOEXIST",
1772                      "sock_type:%d err:%d errno:%d\n",
1773                      type, err, errno);
1774                fds_idx = REUSEPORT_FD_IDX(err, fds_idx);
1775
1776                /* BPF_ANY case (always succeed) */
1777                err = bpf_map_update_elem(map_fd, &index3, &grpa_fds64[fds_idx],
1778                                          BPF_ANY);
1779                CHECK(err < 0,
1780                      "reuseport array update same sk with BPF_ANY",
1781                      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1782
1783                fd64 = grpa_fds64[fds_idx];
1784                sk_cookie = grpa_cookies[fds_idx];
1785
1786                /* The same sk cannot be added to reuseport_array twice */
1787                err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_ANY);
1788                CHECK(err >= 0 || errno != EBUSY,
1789                      "reuseport array update same sk with same index",
1790                      "sock_type:%d err:%d errno:%d\n",
1791                      type, err, errno);
1792
1793                err = bpf_map_update_elem(map_fd, &index0, &fd64, BPF_ANY);
1794                CHECK(err >= 0 || errno != EBUSY,
1795                      "reuseport array update same sk with different index",
1796                      "sock_type:%d err:%d errno:%d\n",
1797                      type, err, errno);
1798
1799                /* Test delete elem */
1800                err = bpf_map_delete_elem(map_fd, &index3);
1801                CHECK(err < 0, "reuseport array delete sk",
1802                      "sock_type:%d err:%d errno:%d\n",
1803                      type, err, errno);
1804
1805                /* Add it back with BPF_NOEXIST */
1806                err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1807                CHECK(err < 0,
1808                      "reuseport array re-add with BPF_NOEXIST after del",
1809                      "sock_type:%d err:%d errno:%d\n", type, err, errno);
1810
1811                /* Test cookie */
1812                err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1813                CHECK(err < 0 || sk_cookie != map_cookie,
1814                      "reuseport array lookup re-added sk",
1815                      "sock_type:%d err:%d errno:%d sk_cookie:0x%llx map_cookie:0x%llxn",
1816                      type, err, errno, sk_cookie, map_cookie);
1817
1818                /* Test elem removed by close() */
1819                for (f = 0; f < ARRAY_SIZE(grpa_fds64); f++)
1820                        close(grpa_fds64[f]);
1821                err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1822                CHECK(err >= 0 || errno != ENOENT,
1823                      "reuseport array lookup after close()",
1824                      "sock_type:%d err:%d errno:%d\n",
1825                      type, err, errno);
1826        }
1827
1828        /* Test SOCK_RAW */
1829        fd64 = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP);
1830        CHECK(fd64 == -1, "socket(SOCK_RAW)", "err:%d errno:%d\n",
1831              err, errno);
1832        err = bpf_map_update_elem(map_fd, &index3, &fd64, BPF_NOEXIST);
1833        CHECK(err >= 0 || errno != ENOTSUPP, "reuseport array update SOCK_RAW",
1834              "err:%d errno:%d\n", err, errno);
1835        close(fd64);
1836
1837        /* Close the 64 bit value map */
1838        close(map_fd);
1839
1840        /* Test 32 bit fd */
1841        map_fd = bpf_map_create(BPF_MAP_TYPE_REUSEPORT_SOCKARRAY, NULL,
1842                                sizeof(__u32), sizeof(__u32), array_size, NULL);
1843        CHECK(map_fd < 0, "reuseport array create",
1844              "map_fd:%d, errno:%d\n", map_fd, errno);
1845        prepare_reuseport_grp(SOCK_STREAM, map_fd, sizeof(__u32), &fd64,
1846                              &sk_cookie, 1);
1847        fd = fd64;
1848        err = bpf_map_update_elem(map_fd, &index3, &fd, BPF_NOEXIST);
1849        CHECK(err < 0, "reuseport array update 32 bit fd",
1850              "err:%d errno:%d\n", err, errno);
1851        err = bpf_map_lookup_elem(map_fd, &index3, &map_cookie);
1852        CHECK(err >= 0 || errno != ENOSPC,
1853              "reuseport array lookup 32 bit fd",
1854              "err:%d errno:%d\n", err, errno);
1855        close(fd);
1856        close(map_fd);
1857}
1858
1859static void run_all_tests(void)
1860{
1861        test_hashmap(0, NULL);
1862        test_hashmap_percpu(0, NULL);
1863        test_hashmap_walk(0, NULL);
1864        test_hashmap_zero_seed();
1865
1866        test_arraymap(0, NULL);
1867        test_arraymap_percpu(0, NULL);
1868
1869        test_arraymap_percpu_many_keys();
1870
1871        test_devmap(0, NULL);
1872        test_devmap_hash(0, NULL);
1873        test_sockmap(0, NULL);
1874
1875        test_map_large();
1876        test_map_parallel();
1877        test_map_stress();
1878
1879        test_map_rdonly();
1880        test_map_wronly();
1881
1882        test_reuseport_array();
1883
1884        test_queuemap(0, NULL);
1885        test_stackmap(0, NULL);
1886
1887        test_map_in_map();
1888}
1889
1890#define DEFINE_TEST(name) extern void test_##name(void);
1891#include <map_tests/tests.h>
1892#undef DEFINE_TEST
1893
1894int main(void)
1895{
1896        srand(time(NULL));
1897
1898        libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1899
1900        map_opts.map_flags = 0;
1901        run_all_tests();
1902
1903        map_opts.map_flags = BPF_F_NO_PREALLOC;
1904        run_all_tests();
1905
1906#define DEFINE_TEST(name) test_##name();
1907#include <map_tests/tests.h>
1908#undef DEFINE_TEST
1909
1910        printf("test_maps: OK, %d SKIPPED\n", skips);
1911        return 0;
1912}
1913