Merge branch 'bpf-selftests-improve-and-use-library'
Mickaël Salaün says:
====================
Improve BPF selftests and use the library (net-next tree)
This series brings some fixes to selftests, add the ability to test
unprivileged BPF programs as root and replace bpf_sys.h with calls to the BPF
library.
This is intended for the net-next tree and apply on c0e4dadb34
("net: dsa:
mv88e6xxx: Move forward declaration to where it is needed").
Changes since v4:
* align text for function calls as requested by Daniel Borkmann
(bpf_load_program and bpf_map_update_elem)
* rebase
Changes since v3:
* keep the bzero() calls
Changes since v2:
* use the patches from two previous series (unprivileged tests and bpf_sys.h
replacement)
* include one more stdint.h
* rebase on net-next
* add this cover letter
Changes since v1:
* exclude patches not intended for the net-next tree
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
daa5fc711e
|
@ -63,6 +63,12 @@ struct bpf_insn {
|
|||
__s32 imm; /* signed immediate constant */
|
||||
};
|
||||
|
||||
/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
|
||||
struct bpf_lpm_trie_key {
|
||||
__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
|
||||
__u8 data[0]; /* Arbitrary size */
|
||||
};
|
||||
|
||||
/* BPF syscall commands, see bpf(2) man-page for details. */
|
||||
enum bpf_cmd {
|
||||
BPF_MAP_CREATE,
|
||||
|
@ -89,6 +95,7 @@ enum bpf_map_type {
|
|||
BPF_MAP_TYPE_CGROUP_ARRAY,
|
||||
BPF_MAP_TYPE_LRU_HASH,
|
||||
BPF_MAP_TYPE_LRU_PERCPU_HASH,
|
||||
BPF_MAP_TYPE_LPM_TRIE,
|
||||
};
|
||||
|
||||
enum bpf_prog_type {
|
||||
|
@ -430,6 +437,18 @@ union bpf_attr {
|
|||
* @xdp_md: pointer to xdp_md
|
||||
* @delta: An positive/negative integer to be added to xdp_md.data
|
||||
* Return: 0 on success or negative on error
|
||||
*
|
||||
* int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr)
|
||||
* Copy a NUL terminated string from unsafe address. In case the string
|
||||
* length is smaller than size, the target is not padded with further NUL
|
||||
* bytes. In case the string length is larger than size, just count-1
|
||||
* bytes are copied and the last byte is set to NUL.
|
||||
* @dst: destination address
|
||||
* @size: maximum number of bytes to copy, including the trailing NUL
|
||||
* @unsafe_ptr: unsafe address
|
||||
* Return:
|
||||
* > 0 length of the string including the trailing NUL on success
|
||||
* < 0 error
|
||||
*/
|
||||
#define __BPF_FUNC_MAPPER(FN) \
|
||||
FN(unspec), \
|
||||
|
@ -476,7 +495,8 @@ union bpf_attr {
|
|||
FN(set_hash_invalid), \
|
||||
FN(get_numa_node_id), \
|
||||
FN(skb_change_head), \
|
||||
FN(xdp_adjust_head),
|
||||
FN(xdp_adjust_head), \
|
||||
FN(probe_read_str),
|
||||
|
||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
|
||||
* function eBPF program intends to call
|
||||
|
@ -502,6 +522,7 @@ enum bpf_func_id {
|
|||
/* BPF_FUNC_l4_csum_replace flags. */
|
||||
#define BPF_F_PSEUDO_HDR (1ULL << 4)
|
||||
#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
|
||||
#define BPF_F_MARK_ENFORCE (1ULL << 6)
|
||||
|
||||
/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
|
||||
#define BPF_F_INGRESS (1ULL << 0)
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
static __u64 ptr_to_u64(void *ptr)
|
||||
static __u64 ptr_to_u64(const void *ptr)
|
||||
{
|
||||
return (__u64) (unsigned long) ptr;
|
||||
}
|
||||
|
@ -50,7 +50,13 @@ static __u64 ptr_to_u64(void *ptr)
|
|||
static int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
|
||||
unsigned int size)
|
||||
{
|
||||
#ifdef __NR_bpf
|
||||
return syscall(__NR_bpf, cmd, attr, size);
|
||||
#else
|
||||
fprintf(stderr, "No bpf syscall, kernel headers too old?\n");
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int bpf_create_map(enum bpf_map_type map_type, int key_size,
|
||||
|
@ -69,8 +75,8 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size,
|
|||
return sys_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
|
||||
size_t insns_cnt, char *license,
|
||||
int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
|
||||
size_t insns_cnt, const char *license,
|
||||
__u32 kern_version, char *log_buf, size_t log_buf_sz)
|
||||
{
|
||||
int fd;
|
||||
|
@ -98,7 +104,7 @@ int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
|
|||
return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_map_update_elem(int fd, void *key, void *value,
|
||||
int bpf_map_update_elem(int fd, const void *key, const void *value,
|
||||
__u64 flags)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
|
@ -112,7 +118,7 @@ int bpf_map_update_elem(int fd, void *key, void *value,
|
|||
return sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_map_lookup_elem(int fd, void *key, void *value)
|
||||
int bpf_map_lookup_elem(int fd, const void *key, void *value)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
|
||||
|
@ -124,7 +130,7 @@ int bpf_map_lookup_elem(int fd, void *key, void *value)
|
|||
return sys_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_map_delete_elem(int fd, void *key)
|
||||
int bpf_map_delete_elem(int fd, const void *key)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
|
||||
|
@ -135,7 +141,7 @@ int bpf_map_delete_elem(int fd, void *key)
|
|||
return sys_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_map_get_next_key(int fd, void *key, void *next_key)
|
||||
int bpf_map_get_next_key(int fd, const void *key, void *next_key)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
|
||||
|
|
|
@ -28,17 +28,17 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
|
|||
|
||||
/* Recommend log buffer size */
|
||||
#define BPF_LOG_BUF_SIZE 65536
|
||||
int bpf_load_program(enum bpf_prog_type type, struct bpf_insn *insns,
|
||||
size_t insns_cnt, char *license,
|
||||
int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
|
||||
size_t insns_cnt, const char *license,
|
||||
__u32 kern_version, char *log_buf,
|
||||
size_t log_buf_sz);
|
||||
|
||||
int bpf_map_update_elem(int fd, void *key, void *value,
|
||||
int bpf_map_update_elem(int fd, const void *key, const void *value,
|
||||
__u64 flags);
|
||||
|
||||
int bpf_map_lookup_elem(int fd, void *key, void *value);
|
||||
int bpf_map_delete_elem(int fd, void *key);
|
||||
int bpf_map_get_next_key(int fd, void *key, void *next_key);
|
||||
int bpf_map_lookup_elem(int fd, const void *key, void *value);
|
||||
int bpf_map_delete_elem(int fd, const void *key);
|
||||
int bpf_map_get_next_key(int fd, const void *key, void *next_key);
|
||||
int bpf_obj_pin(int fd, const char *pathname);
|
||||
int bpf_obj_get(const char *pathname);
|
||||
int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type);
|
||||
|
|
1
tools/testing/selftests/bpf/.gitignore
vendored
1
tools/testing/selftests/bpf/.gitignore
vendored
|
@ -2,3 +2,4 @@ test_verifier
|
|||
test_maps
|
||||
test_lru_map
|
||||
test_lpm_map
|
||||
test_tag
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
CFLAGS += -Wall -O2 -I../../../../usr/include
|
||||
CFLAGS += -Wall -O2 -lcap -I../../../include/uapi -I../../../lib
|
||||
|
||||
test_objs = test_verifier test_tag test_maps test_lru_map test_lpm_map
|
||||
|
||||
|
@ -7,6 +7,8 @@ TEST_FILES := $(test_objs)
|
|||
|
||||
all: $(test_objs)
|
||||
|
||||
$(test_objs): ../../../lib/bpf/bpf.o
|
||||
|
||||
include ../lib.mk
|
||||
|
||||
clean:
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
#ifndef __BPF_SYS__
|
||||
#define __BPF_SYS__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <linux/bpf.h>
|
||||
|
||||
static inline __u64 bpf_ptr_to_u64(const void *ptr)
|
||||
{
|
||||
return (__u64)(unsigned long) ptr;
|
||||
}
|
||||
|
||||
static inline int bpf(int cmd, union bpf_attr *attr, unsigned int size)
|
||||
{
|
||||
#ifdef __NR_bpf
|
||||
return syscall(__NR_bpf, cmd, attr, size);
|
||||
#else
|
||||
fprintf(stderr, "No bpf syscall, kernel headers too old?\n");
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int bpf_map_lookup(int fd, const void *key, void *value)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
|
||||
attr.map_fd = fd;
|
||||
attr.key = bpf_ptr_to_u64(key);
|
||||
attr.value = bpf_ptr_to_u64(value);
|
||||
|
||||
return bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static inline int bpf_map_update(int fd, const void *key, const void *value,
|
||||
uint64_t flags)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
|
||||
attr.map_fd = fd;
|
||||
attr.key = bpf_ptr_to_u64(key);
|
||||
attr.value = bpf_ptr_to_u64(value);
|
||||
attr.flags = flags;
|
||||
|
||||
return bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static inline int bpf_map_delete(int fd, const void *key)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
|
||||
attr.map_fd = fd;
|
||||
attr.key = bpf_ptr_to_u64(key);
|
||||
|
||||
return bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static inline int bpf_map_next_key(int fd, const void *key, void *next_key)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
|
||||
attr.map_fd = fd;
|
||||
attr.key = bpf_ptr_to_u64(key);
|
||||
attr.next_key = bpf_ptr_to_u64(next_key);
|
||||
|
||||
return bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static inline int bpf_map_create(enum bpf_map_type type, uint32_t size_key,
|
||||
uint32_t size_value, uint32_t max_elem,
|
||||
uint32_t flags)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
|
||||
attr.map_type = type;
|
||||
attr.key_size = size_key;
|
||||
attr.value_size = size_value;
|
||||
attr.max_entries = max_elem;
|
||||
attr.map_flags = flags;
|
||||
|
||||
return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
static inline int bpf_prog_load(enum bpf_prog_type type,
|
||||
const struct bpf_insn *insns, size_t size_insns,
|
||||
const char *license, char *log, size_t size_log)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
|
||||
attr.prog_type = type;
|
||||
attr.insns = bpf_ptr_to_u64(insns);
|
||||
attr.insn_cnt = size_insns / sizeof(struct bpf_insn);
|
||||
attr.license = bpf_ptr_to_u64(license);
|
||||
|
||||
if (size_log > 0) {
|
||||
attr.log_buf = bpf_ptr_to_u64(log);
|
||||
attr.log_size = size_log;
|
||||
attr.log_level = 1;
|
||||
log[0] = 0;
|
||||
}
|
||||
|
||||
return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
#endif /* __BPF_SYS__ */
|
|
@ -22,7 +22,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "bpf_sys.h"
|
||||
#include <bpf/bpf.h>
|
||||
#include "bpf_util.h"
|
||||
|
||||
struct tlpm_node {
|
||||
|
@ -182,7 +182,7 @@ static void test_lpm_map(int keysize)
|
|||
key = alloca(sizeof(*key) + keysize);
|
||||
memset(key, 0, sizeof(*key) + keysize);
|
||||
|
||||
map = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE,
|
||||
map = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE,
|
||||
sizeof(*key) + keysize,
|
||||
keysize + 1,
|
||||
4096,
|
||||
|
@ -198,7 +198,7 @@ static void test_lpm_map(int keysize)
|
|||
|
||||
key->prefixlen = value[keysize];
|
||||
memcpy(key->data, value, keysize);
|
||||
r = bpf_map_update(map, key, value, 0);
|
||||
r = bpf_map_update_elem(map, key, value, 0);
|
||||
assert(!r);
|
||||
}
|
||||
|
||||
|
@ -210,7 +210,7 @@ static void test_lpm_map(int keysize)
|
|||
|
||||
key->prefixlen = 8 * keysize;
|
||||
memcpy(key->data, data, keysize);
|
||||
r = bpf_map_lookup(map, key, value);
|
||||
r = bpf_map_lookup_elem(map, key, value);
|
||||
assert(!r || errno == ENOENT);
|
||||
assert(!t == !!r);
|
||||
|
||||
|
@ -252,12 +252,12 @@ static void test_lpm_ipaddr(void)
|
|||
key_ipv4 = alloca(key_size_ipv4);
|
||||
key_ipv6 = alloca(key_size_ipv6);
|
||||
|
||||
map_fd_ipv4 = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE,
|
||||
map_fd_ipv4 = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE,
|
||||
key_size_ipv4, sizeof(value),
|
||||
100, BPF_F_NO_PREALLOC);
|
||||
assert(map_fd_ipv4 >= 0);
|
||||
|
||||
map_fd_ipv6 = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE,
|
||||
map_fd_ipv6 = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE,
|
||||
key_size_ipv6, sizeof(value),
|
||||
100, BPF_F_NO_PREALLOC);
|
||||
assert(map_fd_ipv6 >= 0);
|
||||
|
@ -266,32 +266,32 @@ static void test_lpm_ipaddr(void)
|
|||
value = 1;
|
||||
key_ipv4->prefixlen = 16;
|
||||
inet_pton(AF_INET, "192.168.0.0", key_ipv4->data);
|
||||
assert(bpf_map_update(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
|
||||
value = 2;
|
||||
key_ipv4->prefixlen = 24;
|
||||
inet_pton(AF_INET, "192.168.0.0", key_ipv4->data);
|
||||
assert(bpf_map_update(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
|
||||
value = 3;
|
||||
key_ipv4->prefixlen = 24;
|
||||
inet_pton(AF_INET, "192.168.128.0", key_ipv4->data);
|
||||
assert(bpf_map_update(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
|
||||
value = 5;
|
||||
key_ipv4->prefixlen = 24;
|
||||
inet_pton(AF_INET, "192.168.1.0", key_ipv4->data);
|
||||
assert(bpf_map_update(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
|
||||
value = 4;
|
||||
key_ipv4->prefixlen = 23;
|
||||
inet_pton(AF_INET, "192.168.0.0", key_ipv4->data);
|
||||
assert(bpf_map_update(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
assert(bpf_map_update_elem(map_fd_ipv4, key_ipv4, &value, 0) == 0);
|
||||
|
||||
value = 0xdeadbeef;
|
||||
key_ipv6->prefixlen = 64;
|
||||
inet_pton(AF_INET6, "2a00:1450:4001:814::200e", key_ipv6->data);
|
||||
assert(bpf_map_update(map_fd_ipv6, key_ipv6, &value, 0) == 0);
|
||||
assert(bpf_map_update_elem(map_fd_ipv6, key_ipv6, &value, 0) == 0);
|
||||
|
||||
/* Set tprefixlen to maximum for lookups */
|
||||
key_ipv4->prefixlen = 32;
|
||||
|
@ -299,32 +299,32 @@ static void test_lpm_ipaddr(void)
|
|||
|
||||
/* Test some lookups that should come back with a value */
|
||||
inet_pton(AF_INET, "192.168.128.23", key_ipv4->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv4, key_ipv4, &value) == 0);
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == 0);
|
||||
assert(value == 3);
|
||||
|
||||
inet_pton(AF_INET, "192.168.0.1", key_ipv4->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv4, key_ipv4, &value) == 0);
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == 0);
|
||||
assert(value == 2);
|
||||
|
||||
inet_pton(AF_INET6, "2a00:1450:4001:814::", key_ipv6->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv6, key_ipv6, &value) == 0);
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv6, key_ipv6, &value) == 0);
|
||||
assert(value == 0xdeadbeef);
|
||||
|
||||
inet_pton(AF_INET6, "2a00:1450:4001:814::1", key_ipv6->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv6, key_ipv6, &value) == 0);
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv6, key_ipv6, &value) == 0);
|
||||
assert(value == 0xdeadbeef);
|
||||
|
||||
/* Test some lookups that should not match any entry */
|
||||
inet_pton(AF_INET, "10.0.0.1", key_ipv4->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv4, key_ipv4, &value) == -1 &&
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
inet_pton(AF_INET, "11.11.11.11", key_ipv4->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv4, key_ipv4, &value) == -1 &&
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv4, key_ipv4, &value) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
inet_pton(AF_INET6, "2a00:ffff::", key_ipv6->data);
|
||||
assert(bpf_map_lookup(map_fd_ipv6, key_ipv6, &value) == -1 &&
|
||||
assert(bpf_map_lookup_elem(map_fd_ipv6, key_ipv6, &value) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
close(map_fd_ipv4);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <sys/wait.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "bpf_sys.h"
|
||||
#include <bpf/bpf.h>
|
||||
#include "bpf_util.h"
|
||||
|
||||
#define LOCAL_FREE_TARGET (128)
|
||||
|
@ -30,11 +30,11 @@ static int create_map(int map_type, int map_flags, unsigned int size)
|
|||
{
|
||||
int map_fd;
|
||||
|
||||
map_fd = bpf_map_create(map_type, sizeof(unsigned long long),
|
||||
map_fd = bpf_create_map(map_type, sizeof(unsigned long long),
|
||||
sizeof(unsigned long long), size, map_flags);
|
||||
|
||||
if (map_fd == -1)
|
||||
perror("bpf_map_create");
|
||||
perror("bpf_create_map");
|
||||
|
||||
return map_fd;
|
||||
}
|
||||
|
@ -45,9 +45,9 @@ static int map_subset(int map0, int map1)
|
|||
unsigned long long value0[nr_cpus], value1[nr_cpus];
|
||||
int ret;
|
||||
|
||||
while (!bpf_map_next_key(map1, &next_key, &next_key)) {
|
||||
assert(!bpf_map_lookup(map1, &next_key, value1));
|
||||
ret = bpf_map_lookup(map0, &next_key, value0);
|
||||
while (!bpf_map_get_next_key(map1, &next_key, &next_key)) {
|
||||
assert(!bpf_map_lookup_elem(map1, &next_key, value1));
|
||||
ret = bpf_map_lookup_elem(map0, &next_key, value0);
|
||||
if (ret) {
|
||||
printf("key:%llu not found from map. %s(%d)\n",
|
||||
next_key, strerror(errno), errno);
|
||||
|
@ -119,52 +119,54 @@ static void test_lru_sanity0(int map_type, int map_flags)
|
|||
/* insert key=1 element */
|
||||
|
||||
key = 1;
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
/* BPF_NOEXIST means: add new element if it doesn't exist */
|
||||
assert(bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST) == -1
|
||||
/* key=1 already exists */
|
||||
errno == EEXIST);
|
||||
&& errno == EEXIST);
|
||||
|
||||
assert(bpf_map_update(lru_map_fd, &key, value, -1) == -1 &&
|
||||
assert(bpf_map_update_elem(lru_map_fd, &key, value, -1) == -1 &&
|
||||
errno == EINVAL);
|
||||
|
||||
/* insert key=2 element */
|
||||
|
||||
/* check that key=2 is not found */
|
||||
key = 2;
|
||||
assert(bpf_map_lookup(lru_map_fd, &key, value) == -1 &&
|
||||
assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
/* BPF_EXIST means: update existing element */
|
||||
assert(bpf_map_update(lru_map_fd, &key, value, BPF_EXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_EXIST) == -1 &&
|
||||
/* key=2 is not there */
|
||||
errno == ENOENT);
|
||||
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
|
||||
/* insert key=3 element */
|
||||
|
||||
/* check that key=3 is not found */
|
||||
key = 3;
|
||||
assert(bpf_map_lookup(lru_map_fd, &key, value) == -1 &&
|
||||
assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
/* check that key=1 can be found and mark the ref bit to
|
||||
* stop LRU from removing key=1
|
||||
*/
|
||||
key = 1;
|
||||
assert(!bpf_map_lookup(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
|
||||
assert(value[0] == 1234);
|
||||
|
||||
key = 3;
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
/* key=2 has been removed from the LRU */
|
||||
key = 2;
|
||||
assert(bpf_map_lookup(lru_map_fd, &key, value) == -1);
|
||||
assert(bpf_map_lookup_elem(lru_map_fd, &key, value) == -1);
|
||||
|
||||
assert(map_equal(lru_map_fd, expected_map_fd));
|
||||
|
||||
|
@ -217,14 +219,15 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free)
|
|||
/* Insert 1 to tgt_free (+tgt_free keys) */
|
||||
end_key = 1 + tgt_free;
|
||||
for (key = 1; key < end_key; key++)
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
/* Lookup 1 to tgt_free/2 */
|
||||
end_key = 1 + batch_size;
|
||||
for (key = 1; key < end_key; key++) {
|
||||
assert(!bpf_map_lookup(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
/* Insert 1+tgt_free to 2*tgt_free
|
||||
|
@ -234,9 +237,10 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free)
|
|||
key = 1 + tgt_free;
|
||||
end_key = key + tgt_free;
|
||||
for (; key < end_key; key++) {
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
assert(map_equal(lru_map_fd, expected_map_fd));
|
||||
|
@ -301,9 +305,10 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
|
|||
/* Insert 1 to tgt_free (+tgt_free keys) */
|
||||
end_key = 1 + tgt_free;
|
||||
for (key = 1; key < end_key; key++)
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
/* Any bpf_map_update will require to acquire a new node
|
||||
/* Any bpf_map_update_elem will require to acquire a new node
|
||||
* from LRU first.
|
||||
*
|
||||
* The local list is running out of free nodes.
|
||||
|
@ -316,10 +321,12 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
|
|||
*/
|
||||
key = 1;
|
||||
if (map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_delete(lru_map_fd, &key));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_delete_elem(lru_map_fd, &key));
|
||||
} else {
|
||||
assert(bpf_map_update(lru_map_fd, &key, value, BPF_EXIST));
|
||||
assert(bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_EXIST));
|
||||
}
|
||||
|
||||
/* Re-insert 1 to tgt_free/2 again and do a lookup
|
||||
|
@ -328,12 +335,13 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
|
|||
end_key = 1 + batch_size;
|
||||
value[0] = 4321;
|
||||
for (key = 1; key < end_key; key++) {
|
||||
assert(bpf_map_lookup(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup(lru_map_fd, &key, value));
|
||||
assert(bpf_map_lookup_elem(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
|
||||
assert(value[0] == 4321);
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
value[0] = 1234;
|
||||
|
@ -344,14 +352,16 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
|
|||
/* These newly added but not referenced keys will be
|
||||
* gone during the next LRU shrink.
|
||||
*/
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
/* Insert 1+tgt_free*3/2 to tgt_free*5/2 */
|
||||
end_key = key + tgt_free;
|
||||
for (; key < end_key; key++) {
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
assert(map_equal(lru_map_fd, expected_map_fd));
|
||||
|
@ -401,14 +411,15 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
|
|||
/* Insert 1 to 2*tgt_free (+2*tgt_free keys) */
|
||||
end_key = 1 + (2 * tgt_free);
|
||||
for (key = 1; key < end_key; key++)
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
/* Lookup key 1 to tgt_free*3/2 */
|
||||
end_key = tgt_free + batch_size;
|
||||
for (key = 1; key < end_key; key++) {
|
||||
assert(!bpf_map_lookup(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
/* Add 1+2*tgt_free to tgt_free*5/2
|
||||
|
@ -417,9 +428,10 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
|
|||
key = 2 * tgt_free + 1;
|
||||
end_key = key + batch_size;
|
||||
for (; key < end_key; key++) {
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
assert(map_equal(lru_map_fd, expected_map_fd));
|
||||
|
@ -457,27 +469,29 @@ static void test_lru_sanity4(int map_type, int map_flags, unsigned int tgt_free)
|
|||
value[0] = 1234;
|
||||
|
||||
for (key = 1; key <= 2 * tgt_free; key++)
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
|
||||
key = 1;
|
||||
assert(bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(bpf_map_update_elem(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
|
||||
for (key = 1; key <= tgt_free; key++) {
|
||||
assert(!bpf_map_lookup(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup_elem(lru_map_fd, &key, value));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
for (; key <= 2 * tgt_free; key++) {
|
||||
assert(!bpf_map_delete(lru_map_fd, &key));
|
||||
assert(bpf_map_delete(lru_map_fd, &key));
|
||||
assert(!bpf_map_delete_elem(lru_map_fd, &key));
|
||||
assert(bpf_map_delete_elem(lru_map_fd, &key));
|
||||
}
|
||||
|
||||
end_key = key + 2 * tgt_free;
|
||||
for (; key < end_key; key++) {
|
||||
assert(!bpf_map_update(lru_map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(lru_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(expected_map_fd, &key, value,
|
||||
BPF_NOEXIST));
|
||||
}
|
||||
|
||||
assert(map_equal(lru_map_fd, expected_map_fd));
|
||||
|
@ -493,16 +507,16 @@ static void do_test_lru_sanity5(unsigned long long last_key, int map_fd)
|
|||
unsigned long long key, value[nr_cpus];
|
||||
|
||||
/* Ensure the last key inserted by previous CPU can be found */
|
||||
assert(!bpf_map_lookup(map_fd, &last_key, value));
|
||||
assert(!bpf_map_lookup_elem(map_fd, &last_key, value));
|
||||
|
||||
value[0] = 1234;
|
||||
|
||||
key = last_key + 1;
|
||||
assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup(map_fd, &key, value));
|
||||
assert(!bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_lookup_elem(map_fd, &key, value));
|
||||
|
||||
/* Cannot find the last key because it was removed by LRU */
|
||||
assert(bpf_map_lookup(map_fd, &last_key, value));
|
||||
assert(bpf_map_lookup_elem(map_fd, &last_key, value));
|
||||
}
|
||||
|
||||
/* Test map with only one element */
|
||||
|
@ -523,7 +537,7 @@ static void test_lru_sanity5(int map_type, int map_flags)
|
|||
|
||||
value[0] = 1234;
|
||||
key = 0;
|
||||
assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST));
|
||||
assert(!bpf_map_update_elem(map_fd, &key, value, BPF_NOEXIST));
|
||||
|
||||
while (sched_next_online(0, &next_cpu) != -1) {
|
||||
pid_t pid;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include <linux/bpf.h>
|
||||
|
||||
#include "bpf_sys.h"
|
||||
#include <bpf/bpf.h>
|
||||
#include "bpf_util.h"
|
||||
|
||||
static int map_flags;
|
||||
|
@ -31,7 +31,7 @@ static void test_hashmap(int task, void *data)
|
|||
long long key, next_key, value;
|
||||
int fd;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
|
||||
2, map_flags);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create hashmap '%s'!\n", strerror(errno));
|
||||
|
@ -41,69 +41,70 @@ static void test_hashmap(int task, void *data)
|
|||
key = 1;
|
||||
value = 1234;
|
||||
/* Insert key=1 element. */
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
|
||||
|
||||
value = 0;
|
||||
/* BPF_NOEXIST means add new element if it doesn't exist. */
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
/* key=1 already exists. */
|
||||
errno == EEXIST);
|
||||
|
||||
/* -1 is an invalid flag. */
|
||||
assert(bpf_map_update(fd, &key, &value, -1) == -1 && errno == EINVAL);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, -1) == -1 &&
|
||||
errno == EINVAL);
|
||||
|
||||
/* Check that key=1 can be found. */
|
||||
assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 1234);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
|
||||
|
||||
key = 2;
|
||||
/* Check that key=2 is not found. */
|
||||
assert(bpf_map_lookup(fd, &key, &value) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
|
||||
|
||||
/* BPF_EXIST means update existing element. */
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == -1 &&
|
||||
/* key=2 is not there. */
|
||||
errno == ENOENT);
|
||||
|
||||
/* Insert key=2 element. */
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
|
||||
|
||||
/* key=1 and key=2 were inserted, check that key=0 cannot be
|
||||
* inserted due to max_entries limit.
|
||||
*/
|
||||
key = 0;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
errno == E2BIG);
|
||||
|
||||
/* Update existing element, though the map is full. */
|
||||
key = 1;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
|
||||
key = 2;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
|
||||
key = 1;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
|
||||
|
||||
/* Check that key = 0 doesn't exist. */
|
||||
key = 0;
|
||||
assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
|
||||
|
||||
/* Iterate over two elements. */
|
||||
assert(bpf_map_next_key(fd, &key, &next_key) == 0 &&
|
||||
assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
|
||||
(next_key == 1 || next_key == 2));
|
||||
assert(bpf_map_next_key(fd, &next_key, &next_key) == 0 &&
|
||||
assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
|
||||
(next_key == 1 || next_key == 2));
|
||||
assert(bpf_map_next_key(fd, &next_key, &next_key) == -1 &&
|
||||
assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
/* Delete both elements. */
|
||||
key = 1;
|
||||
assert(bpf_map_delete(fd, &key) == 0);
|
||||
assert(bpf_map_delete_elem(fd, &key) == 0);
|
||||
key = 2;
|
||||
assert(bpf_map_delete(fd, &key) == 0);
|
||||
assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_delete_elem(fd, &key) == 0);
|
||||
assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
|
||||
|
||||
key = 0;
|
||||
/* Check that map is empty. */
|
||||
assert(bpf_map_next_key(fd, &key, &next_key) == -1 &&
|
||||
assert(bpf_map_get_next_key(fd, &key, &next_key) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
close(fd);
|
||||
|
@ -117,7 +118,7 @@ static void test_hashmap_percpu(int task, void *data)
|
|||
int expected_key_mask = 0;
|
||||
int fd, i;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_HASH, sizeof(key),
|
||||
sizeof(value[0]), 2, map_flags);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create hashmap '%s'!\n", strerror(errno));
|
||||
|
@ -130,53 +131,54 @@ static void test_hashmap_percpu(int task, void *data)
|
|||
key = 1;
|
||||
/* Insert key=1 element. */
|
||||
assert(!(expected_key_mask & key));
|
||||
assert(bpf_map_update(fd, &key, value, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, value, BPF_ANY) == 0);
|
||||
expected_key_mask |= key;
|
||||
|
||||
/* BPF_NOEXIST means add new element if it doesn't exist. */
|
||||
assert(bpf_map_update(fd, &key, value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == -1 &&
|
||||
/* key=1 already exists. */
|
||||
errno == EEXIST);
|
||||
|
||||
/* -1 is an invalid flag. */
|
||||
assert(bpf_map_update(fd, &key, value, -1) == -1 && errno == EINVAL);
|
||||
assert(bpf_map_update_elem(fd, &key, value, -1) == -1 &&
|
||||
errno == EINVAL);
|
||||
|
||||
/* Check that key=1 can be found. Value could be 0 if the lookup
|
||||
* was run from a different CPU.
|
||||
*/
|
||||
value[0] = 1;
|
||||
assert(bpf_map_lookup(fd, &key, value) == 0 && value[0] == 100);
|
||||
assert(bpf_map_lookup_elem(fd, &key, value) == 0 && value[0] == 100);
|
||||
|
||||
key = 2;
|
||||
/* Check that key=2 is not found. */
|
||||
assert(bpf_map_lookup(fd, &key, value) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_lookup_elem(fd, &key, value) == -1 && errno == ENOENT);
|
||||
|
||||
/* BPF_EXIST means update existing element. */
|
||||
assert(bpf_map_update(fd, &key, value, BPF_EXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == -1 &&
|
||||
/* key=2 is not there. */
|
||||
errno == ENOENT);
|
||||
|
||||
/* Insert key=2 element. */
|
||||
assert(!(expected_key_mask & key));
|
||||
assert(bpf_map_update(fd, &key, value, BPF_NOEXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == 0);
|
||||
expected_key_mask |= key;
|
||||
|
||||
/* key=1 and key=2 were inserted, check that key=0 cannot be
|
||||
* inserted due to max_entries limit.
|
||||
*/
|
||||
key = 0;
|
||||
assert(bpf_map_update(fd, &key, value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, value, BPF_NOEXIST) == -1 &&
|
||||
errno == E2BIG);
|
||||
|
||||
/* Check that key = 0 doesn't exist. */
|
||||
assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
|
||||
|
||||
/* Iterate over two elements. */
|
||||
while (!bpf_map_next_key(fd, &key, &next_key)) {
|
||||
while (!bpf_map_get_next_key(fd, &key, &next_key)) {
|
||||
assert((expected_key_mask & next_key) == next_key);
|
||||
expected_key_mask &= ~next_key;
|
||||
|
||||
assert(bpf_map_lookup(fd, &next_key, value) == 0);
|
||||
assert(bpf_map_lookup_elem(fd, &next_key, value) == 0);
|
||||
|
||||
for (i = 0; i < nr_cpus; i++)
|
||||
assert(value[i] == i + 100);
|
||||
|
@ -187,18 +189,18 @@ static void test_hashmap_percpu(int task, void *data)
|
|||
|
||||
/* Update with BPF_EXIST. */
|
||||
key = 1;
|
||||
assert(bpf_map_update(fd, &key, value, BPF_EXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, value, BPF_EXIST) == 0);
|
||||
|
||||
/* Delete both elements. */
|
||||
key = 1;
|
||||
assert(bpf_map_delete(fd, &key) == 0);
|
||||
assert(bpf_map_delete_elem(fd, &key) == 0);
|
||||
key = 2;
|
||||
assert(bpf_map_delete(fd, &key) == 0);
|
||||
assert(bpf_map_delete(fd, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_delete_elem(fd, &key) == 0);
|
||||
assert(bpf_map_delete_elem(fd, &key) == -1 && errno == ENOENT);
|
||||
|
||||
key = 0;
|
||||
/* Check that map is empty. */
|
||||
assert(bpf_map_next_key(fd, &key, &next_key) == -1 &&
|
||||
assert(bpf_map_get_next_key(fd, &key, &next_key) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
close(fd);
|
||||
|
@ -209,7 +211,7 @@ static void test_arraymap(int task, void *data)
|
|||
int key, next_key, fd;
|
||||
long long value;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(value),
|
||||
2, 0);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create arraymap '%s'!\n", strerror(errno));
|
||||
|
@ -219,40 +221,40 @@ static void test_arraymap(int task, void *data)
|
|||
key = 1;
|
||||
value = 1234;
|
||||
/* Insert key=1 element. */
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_ANY) == 0);
|
||||
|
||||
value = 0;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
errno == EEXIST);
|
||||
|
||||
/* Check that key=1 can be found. */
|
||||
assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 1234);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 1234);
|
||||
|
||||
key = 0;
|
||||
/* Check that key=0 is also found and zero initialized. */
|
||||
assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 0);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
|
||||
|
||||
/* key=0 and key=1 were inserted, check that key=2 cannot be inserted
|
||||
* due to max_entries limit.
|
||||
*/
|
||||
key = 2;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == -1 &&
|
||||
errno == E2BIG);
|
||||
|
||||
/* Check that key = 2 doesn't exist. */
|
||||
assert(bpf_map_lookup(fd, &key, &value) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
|
||||
|
||||
/* Iterate over two elements. */
|
||||
assert(bpf_map_next_key(fd, &key, &next_key) == 0 &&
|
||||
assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
|
||||
next_key == 0);
|
||||
assert(bpf_map_next_key(fd, &next_key, &next_key) == 0 &&
|
||||
assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
|
||||
next_key == 1);
|
||||
assert(bpf_map_next_key(fd, &next_key, &next_key) == -1 &&
|
||||
assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
/* Delete shouldn't succeed. */
|
||||
key = 1;
|
||||
assert(bpf_map_delete(fd, &key) == -1 && errno == EINVAL);
|
||||
assert(bpf_map_delete_elem(fd, &key) == -1 && errno == EINVAL);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
@ -263,7 +265,7 @@ static void test_arraymap_percpu(int task, void *data)
|
|||
int key, next_key, fd, i;
|
||||
long values[nr_cpus];
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
|
||||
sizeof(values[0]), 2, 0);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create arraymap '%s'!\n", strerror(errno));
|
||||
|
@ -275,39 +277,39 @@ static void test_arraymap_percpu(int task, void *data)
|
|||
|
||||
key = 1;
|
||||
/* Insert key=1 element. */
|
||||
assert(bpf_map_update(fd, &key, values, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
|
||||
|
||||
values[0] = 0;
|
||||
assert(bpf_map_update(fd, &key, values, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, values, BPF_NOEXIST) == -1 &&
|
||||
errno == EEXIST);
|
||||
|
||||
/* Check that key=1 can be found. */
|
||||
assert(bpf_map_lookup(fd, &key, values) == 0 && values[0] == 100);
|
||||
assert(bpf_map_lookup_elem(fd, &key, values) == 0 && values[0] == 100);
|
||||
|
||||
key = 0;
|
||||
/* Check that key=0 is also found and zero initialized. */
|
||||
assert(bpf_map_lookup(fd, &key, values) == 0 &&
|
||||
assert(bpf_map_lookup_elem(fd, &key, values) == 0 &&
|
||||
values[0] == 0 && values[nr_cpus - 1] == 0);
|
||||
|
||||
/* Check that key=2 cannot be inserted due to max_entries limit. */
|
||||
key = 2;
|
||||
assert(bpf_map_update(fd, &key, values, BPF_EXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, values, BPF_EXIST) == -1 &&
|
||||
errno == E2BIG);
|
||||
|
||||
/* Check that key = 2 doesn't exist. */
|
||||
assert(bpf_map_lookup(fd, &key, values) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_lookup_elem(fd, &key, values) == -1 && errno == ENOENT);
|
||||
|
||||
/* Iterate over two elements. */
|
||||
assert(bpf_map_next_key(fd, &key, &next_key) == 0 &&
|
||||
assert(bpf_map_get_next_key(fd, &key, &next_key) == 0 &&
|
||||
next_key == 0);
|
||||
assert(bpf_map_next_key(fd, &next_key, &next_key) == 0 &&
|
||||
assert(bpf_map_get_next_key(fd, &next_key, &next_key) == 0 &&
|
||||
next_key == 1);
|
||||
assert(bpf_map_next_key(fd, &next_key, &next_key) == -1 &&
|
||||
assert(bpf_map_get_next_key(fd, &next_key, &next_key) == -1 &&
|
||||
errno == ENOENT);
|
||||
|
||||
/* Delete shouldn't succeed. */
|
||||
key = 1;
|
||||
assert(bpf_map_delete(fd, &key) == -1 && errno == EINVAL);
|
||||
assert(bpf_map_delete_elem(fd, &key) == -1 && errno == EINVAL);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
@ -319,7 +321,7 @@ static void test_arraymap_percpu_many_keys(void)
|
|||
long values[nr_cpus];
|
||||
int key, fd, i;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_ARRAY, sizeof(key),
|
||||
sizeof(values[0]), nr_keys, 0);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create per-cpu arraymap '%s'!\n",
|
||||
|
@ -331,13 +333,13 @@ static void test_arraymap_percpu_many_keys(void)
|
|||
values[i] = i + 10;
|
||||
|
||||
for (key = 0; key < nr_keys; key++)
|
||||
assert(bpf_map_update(fd, &key, values, BPF_ANY) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, values, BPF_ANY) == 0);
|
||||
|
||||
for (key = 0; key < nr_keys; key++) {
|
||||
for (i = 0; i < nr_cpus; i++)
|
||||
values[i] = 0;
|
||||
|
||||
assert(bpf_map_lookup(fd, &key, values) == 0);
|
||||
assert(bpf_map_lookup_elem(fd, &key, values) == 0);
|
||||
|
||||
for (i = 0; i < nr_cpus; i++)
|
||||
assert(values[i] == i + 10);
|
||||
|
@ -357,7 +359,7 @@ static void test_map_large(void)
|
|||
} key;
|
||||
int fd, i, value;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
|
||||
MAP_SIZE, map_flags);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create large map '%s'!\n", strerror(errno));
|
||||
|
@ -368,22 +370,22 @@ static void test_map_large(void)
|
|||
key = (struct bigkey) { .c = i };
|
||||
value = i;
|
||||
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
|
||||
}
|
||||
|
||||
key.c = -1;
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
errno == E2BIG);
|
||||
|
||||
/* Iterate through all elements. */
|
||||
for (i = 0; i < MAP_SIZE; i++)
|
||||
assert(bpf_map_next_key(fd, &key, &key) == 0);
|
||||
assert(bpf_map_next_key(fd, &key, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_get_next_key(fd, &key, &key) == 0);
|
||||
assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
|
||||
|
||||
key.c = 0;
|
||||
assert(bpf_map_lookup(fd, &key, &value) == 0 && value == 0);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == 0 && value == 0);
|
||||
key.a = 1;
|
||||
assert(bpf_map_lookup(fd, &key, &value) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == -1 && errno == ENOENT);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
@ -437,10 +439,12 @@ static void do_work(int fn, void *data)
|
|||
key = value = i;
|
||||
|
||||
if (do_update) {
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == 0);
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_EXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value,
|
||||
BPF_NOEXIST) == 0);
|
||||
assert(bpf_map_update_elem(fd, &key, &value,
|
||||
BPF_EXIST) == 0);
|
||||
} else {
|
||||
assert(bpf_map_delete(fd, &key) == 0);
|
||||
assert(bpf_map_delete_elem(fd, &key) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,7 +454,7 @@ static void test_map_parallel(void)
|
|||
int i, fd, key = 0, value = 0;
|
||||
int data[2];
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
|
||||
MAP_SIZE, map_flags);
|
||||
if (fd < 0) {
|
||||
printf("Failed to create map for parallel test '%s'!\n",
|
||||
|
@ -468,20 +472,20 @@ static void test_map_parallel(void)
|
|||
run_parallel(TASKS, do_work, data);
|
||||
|
||||
/* Check that key=0 is already there. */
|
||||
assert(bpf_map_update(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == -1 &&
|
||||
errno == EEXIST);
|
||||
|
||||
/* Check that all elements were inserted. */
|
||||
key = -1;
|
||||
for (i = 0; i < MAP_SIZE; i++)
|
||||
assert(bpf_map_next_key(fd, &key, &key) == 0);
|
||||
assert(bpf_map_next_key(fd, &key, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_get_next_key(fd, &key, &key) == 0);
|
||||
assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
|
||||
|
||||
/* Another check for all elements */
|
||||
for (i = 0; i < MAP_SIZE; i++) {
|
||||
key = MAP_SIZE - i - 1;
|
||||
|
||||
assert(bpf_map_lookup(fd, &key, &value) == 0 &&
|
||||
assert(bpf_map_lookup_elem(fd, &key, &value) == 0 &&
|
||||
value == key);
|
||||
}
|
||||
|
||||
|
@ -491,7 +495,7 @@ static void test_map_parallel(void)
|
|||
|
||||
/* Nothing should be left. */
|
||||
key = -1;
|
||||
assert(bpf_map_next_key(fd, &key, &key) == -1 && errno == ENOENT);
|
||||
assert(bpf_map_get_next_key(fd, &key, &key) == -1 && errno == ENOENT);
|
||||
}
|
||||
|
||||
static void run_all_tests(void)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
@ -16,9 +17,9 @@
|
|||
#include <linux/bpf.h>
|
||||
#include <linux/if_alg.h>
|
||||
|
||||
#include "../../../include/linux/filter.h"
|
||||
#include <bpf/bpf.h>
|
||||
|
||||
#include "bpf_sys.h"
|
||||
#include "../../../include/linux/filter.h"
|
||||
|
||||
static struct bpf_insn prog[BPF_MAXINSNS];
|
||||
|
||||
|
@ -55,8 +56,8 @@ static int bpf_try_load_prog(int insns, int fd_map,
|
|||
int fd_prog;
|
||||
|
||||
bpf_filler(insns, fd_map);
|
||||
fd_prog = bpf_prog_load(BPF_PROG_TYPE_SCHED_CLS, prog, insns *
|
||||
sizeof(struct bpf_insn), "", NULL, 0);
|
||||
fd_prog = bpf_load_program(BPF_PROG_TYPE_SCHED_CLS, prog, insns, "", 0,
|
||||
NULL, 0);
|
||||
assert(fd_prog > 0);
|
||||
if (fd_map > 0)
|
||||
bpf_filler(insns, 0);
|
||||
|
@ -187,7 +188,7 @@ int main(void)
|
|||
int i, fd_map;
|
||||
|
||||
setrlimit(RLIMIT_MEMLOCK, &rinf);
|
||||
fd_map = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(int),
|
||||
fd_map = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int),
|
||||
sizeof(int), 1, BPF_F_NO_PREALLOC);
|
||||
assert(fd_map > 0);
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
* License as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
@ -16,6 +18,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <sys/capability.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <linux/unistd.h>
|
||||
|
@ -23,9 +26,9 @@
|
|||
#include <linux/bpf_perf_event.h>
|
||||
#include <linux/bpf.h>
|
||||
|
||||
#include "../../../include/linux/filter.h"
|
||||
#include <bpf/bpf.h>
|
||||
|
||||
#include "bpf_sys.h"
|
||||
#include "../../../include/linux/filter.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
@ -4464,7 +4467,7 @@ static int create_map(uint32_t size_value, uint32_t max_elem)
|
|||
{
|
||||
int fd;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_HASH, sizeof(long long),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(long long),
|
||||
size_value, max_elem, BPF_F_NO_PREALLOC);
|
||||
if (fd < 0)
|
||||
printf("Failed to create hash map '%s'!\n", strerror(errno));
|
||||
|
@ -4476,7 +4479,7 @@ static int create_prog_array(void)
|
|||
{
|
||||
int fd;
|
||||
|
||||
fd = bpf_map_create(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
|
||||
fd = bpf_create_map(BPF_MAP_TYPE_PROG_ARRAY, sizeof(int),
|
||||
sizeof(int), 4, 0);
|
||||
if (fd < 0)
|
||||
printf("Failed to create prog array '%s'!\n", strerror(errno));
|
||||
|
@ -4534,9 +4537,9 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
|
|||
|
||||
do_test_fixup(test, prog, &fd_f1, &fd_f2, &fd_f3);
|
||||
|
||||
fd_prog = bpf_prog_load(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
|
||||
prog, prog_len * sizeof(struct bpf_insn),
|
||||
"GPL", bpf_vlog, sizeof(bpf_vlog));
|
||||
fd_prog = bpf_load_program(prog_type ? : BPF_PROG_TYPE_SOCKET_FILTER,
|
||||
prog, prog_len, "GPL", 0, bpf_vlog,
|
||||
sizeof(bpf_vlog));
|
||||
|
||||
expected_ret = unpriv && test->result_unpriv != UNDEF ?
|
||||
test->result_unpriv : test->result;
|
||||
|
@ -4574,6 +4577,55 @@ fail_log:
|
|||
goto close_fds;
|
||||
}
|
||||
|
||||
static bool is_admin(void)
|
||||
{
|
||||
cap_t caps;
|
||||
cap_flag_value_t sysadmin = CAP_CLEAR;
|
||||
const cap_value_t cap_val = CAP_SYS_ADMIN;
|
||||
|
||||
if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
|
||||
perror("cap_get_flag");
|
||||
return false;
|
||||
}
|
||||
caps = cap_get_proc();
|
||||
if (!caps) {
|
||||
perror("cap_get_proc");
|
||||
return false;
|
||||
}
|
||||
if (cap_get_flag(caps, cap_val, CAP_EFFECTIVE, &sysadmin))
|
||||
perror("cap_get_flag");
|
||||
if (cap_free(caps))
|
||||
perror("cap_free");
|
||||
return (sysadmin == CAP_SET);
|
||||
}
|
||||
|
||||
static int set_admin(bool admin)
|
||||
{
|
||||
cap_t caps;
|
||||
const cap_value_t cap_val = CAP_SYS_ADMIN;
|
||||
int ret = -1;
|
||||
|
||||
caps = cap_get_proc();
|
||||
if (!caps) {
|
||||
perror("cap_get_proc");
|
||||
return -1;
|
||||
}
|
||||
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &cap_val,
|
||||
admin ? CAP_SET : CAP_CLEAR)) {
|
||||
perror("cap_set_flag");
|
||||
goto out;
|
||||
}
|
||||
if (cap_set_proc(caps)) {
|
||||
perror("cap_set_proc");
|
||||
goto out;
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
if (cap_free(caps))
|
||||
perror("cap_free");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_test(bool unpriv, unsigned int from, unsigned int to)
|
||||
{
|
||||
int i, passes = 0, errors = 0;
|
||||
|
@ -4584,11 +4636,19 @@ static int do_test(bool unpriv, unsigned int from, unsigned int to)
|
|||
/* Program types that are not supported by non-root we
|
||||
* skip right away.
|
||||
*/
|
||||
if (unpriv && test->prog_type)
|
||||
continue;
|
||||
if (!test->prog_type) {
|
||||
if (!unpriv)
|
||||
set_admin(false);
|
||||
printf("#%d/u %s ", i, test->descr);
|
||||
do_test_single(test, true, &passes, &errors);
|
||||
if (!unpriv)
|
||||
set_admin(true);
|
||||
}
|
||||
|
||||
printf("#%d %s ", i, test->descr);
|
||||
do_test_single(test, unpriv, &passes, &errors);
|
||||
if (!unpriv) {
|
||||
printf("#%d/p %s ", i, test->descr);
|
||||
do_test_single(test, false, &passes, &errors);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Summary: %d PASSED, %d FAILED\n", passes, errors);
|
||||
|
@ -4600,7 +4660,7 @@ int main(int argc, char **argv)
|
|||
struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
|
||||
struct rlimit rlim = { 1 << 20, 1 << 20 };
|
||||
unsigned int from = 0, to = ARRAY_SIZE(tests);
|
||||
bool unpriv = geteuid() != 0;
|
||||
bool unpriv = !is_admin();
|
||||
|
||||
if (argc == 3) {
|
||||
unsigned int l = atoi(argv[argc - 2]);
|
||||
|
|
Loading…
Reference in a new issue