linux/samples/bpf/test_map_in_map_user.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2017 Facebook
   3 *
   4 * This program is free software; you can redistribute it and/or
   5 * modify it under the terms of version 2 of the GNU General Public
   6 * License as published by the Free Software Foundation.
   7 */
   8#include <sys/resource.h>
   9#include <sys/socket.h>
  10#include <arpa/inet.h>
  11#include <stdint.h>
  12#include <assert.h>
  13#include <errno.h>
  14#include <stdlib.h>
  15#include <stdio.h>
  16#include "libbpf.h"
  17#include "bpf_load.h"
  18
  19#define PORT_A          (map_fd[0])
  20#define PORT_H          (map_fd[1])
  21#define REG_RESULT_H    (map_fd[2])
  22#define INLINE_RESULT_H (map_fd[3])
  23#define A_OF_PORT_A     (map_fd[4]) /* Test case #0 */
  24#define H_OF_PORT_A     (map_fd[5]) /* Test case #1 */
  25#define H_OF_PORT_H     (map_fd[6]) /* Test case #2 */
  26
  27static const char * const test_names[] = {
  28        "Array of Array",
  29        "Hash of Array",
  30        "Hash of Hash",
  31};
  32
  33#define NR_TESTS (sizeof(test_names) / sizeof(*test_names))
  34
  35static void populate_map(uint32_t port_key, int magic_result)
  36{
  37        int ret;
  38
  39        ret = bpf_map_update_elem(PORT_A, &port_key, &magic_result, BPF_ANY);
  40        assert(!ret);
  41
  42        ret = bpf_map_update_elem(PORT_H, &port_key, &magic_result,
  43                                  BPF_NOEXIST);
  44        assert(!ret);
  45
  46        ret = bpf_map_update_elem(A_OF_PORT_A, &port_key, &PORT_A, BPF_ANY);
  47        assert(!ret);
  48
  49        ret = bpf_map_update_elem(H_OF_PORT_A, &port_key, &PORT_A, BPF_NOEXIST);
  50        assert(!ret);
  51
  52        ret = bpf_map_update_elem(H_OF_PORT_H, &port_key, &PORT_H, BPF_NOEXIST);
  53        assert(!ret);
  54}
  55
  56static void test_map_in_map(void)
  57{
  58        struct sockaddr_in6 in6 = { .sin6_family = AF_INET6 };
  59        uint32_t result_key = 0, port_key;
  60        int result, inline_result;
  61        int magic_result = 0xfaceb00c;
  62        int ret;
  63        int i;
  64
  65        port_key = rand() & 0x00FF;
  66        populate_map(port_key, magic_result);
  67
  68        in6.sin6_addr.s6_addr16[0] = 0xdead;
  69        in6.sin6_addr.s6_addr16[1] = 0xbeef;
  70        in6.sin6_port = port_key;
  71
  72        for (i = 0; i < NR_TESTS; i++) {
  73                printf("%s: ", test_names[i]);
  74
  75                in6.sin6_addr.s6_addr16[7] = i;
  76                ret = connect(-1, (struct sockaddr *)&in6, sizeof(in6));
  77                assert(ret == -1 && errno == EBADF);
  78
  79                ret = bpf_map_lookup_elem(REG_RESULT_H, &result_key, &result);
  80                assert(!ret);
  81
  82                ret = bpf_map_lookup_elem(INLINE_RESULT_H, &result_key,
  83                                          &inline_result);
  84                assert(!ret);
  85
  86                if (result != magic_result || inline_result != magic_result) {
  87                        printf("Error. result:%d inline_result:%d\n",
  88                               result, inline_result);
  89                        exit(1);
  90                }
  91
  92                bpf_map_delete_elem(REG_RESULT_H, &result_key);
  93                bpf_map_delete_elem(INLINE_RESULT_H, &result_key);
  94
  95                printf("Pass\n");
  96        }
  97}
  98
  99int main(int argc, char **argv)
 100{
 101        struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
 102        char filename[256];
 103
 104        assert(!setrlimit(RLIMIT_MEMLOCK, &r));
 105
 106        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 107
 108        if (load_bpf_file(filename)) {
 109                printf("%s", bpf_log_buf);
 110                return 1;
 111        }
 112
 113        test_map_in_map();
 114
 115        return 0;
 116}
 117