annotate src/core/ngx_bpf.c @ 8675:d3747ba486e7 quic

Core: added interface to linux bpf() system call. It contains wrappers for operations with BPF maps and for loading BPF programs.
author Vladimir Homutov <vl@nginx.com>
date Tue, 15 Dec 2020 15:23:07 +0300
parents
children 7a07724256c2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8675
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
1
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
2 /*
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
3 * Copyright (C) Nginx, Inc.
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
4 */
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
5
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
6
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
7 #include <ngx_config.h>
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
8 #include <ngx_core.h>
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
9
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
10 #define NGX_BPF_LOGBUF_SIZE (16 * 1024)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
11
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
12
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
13 static ngx_inline int
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
14 ngx_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
15 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
16 return syscall(__NR_bpf, cmd, attr, size);
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
17 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
18
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
19
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
20 void
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
21 ngx_bpf_program_link(ngx_bpf_program_t *program, const char *symbol, int fd)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
22 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
23 ngx_uint_t i;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
24 ngx_bpf_reloc_t *rl;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
25
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
26 rl = program->relocs;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
27
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
28 for (i = 0; i < program->nrelocs; i++) {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
29 if (ngx_strcmp(rl[i].name, symbol) == 0) {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
30 program->ins[rl[i].offset].src_reg = 1;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
31 program->ins[rl[i].offset].imm = fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
32 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
33 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
34 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
35
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
36
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
37 int
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
38 ngx_bpf_load_program(ngx_log_t *log, ngx_bpf_program_t *program)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
39 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
40 int fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
41 union bpf_attr attr;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
42 #if (NGX_DEBUG)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
43 char buf[NGX_BPF_LOGBUF_SIZE];
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
44 #endif
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
45
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
46 ngx_memzero(&attr, sizeof(union bpf_attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
47
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
48 attr.license = (uint64_t) program->license;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
49 attr.prog_type = program->type;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
50 attr.insns = (uint64_t) program->ins;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
51 attr.insn_cnt = program->nins;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
52
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
53 #if (NGX_DEBUG)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
54 /* for verifier errors */
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
55 attr.log_buf = (uint64_t) buf;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
56 attr.log_size = NGX_BPF_LOGBUF_SIZE;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
57 attr.log_level = 1;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
58 #endif
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
59
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
60 fd = ngx_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
61 if (fd < 0) {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
62 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
63 "failed to load BPF program");
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
64
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
65 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
66 "bpf verifier: %s", buf);
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
67
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
68 return -1;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
69 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
70
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
71 return fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
72 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
73
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
74
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
75 int
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
76 ngx_bpf_map_create(ngx_log_t *log, enum bpf_map_type type, int key_size,
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
77 int value_size, int max_entries, uint32_t map_flags)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
78 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
79 int fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
80 union bpf_attr attr;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
81
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
82 ngx_memzero(&attr, sizeof(union bpf_attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
83
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
84 attr.map_type = type;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
85 attr.key_size = key_size;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
86 attr.value_size = value_size;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
87 attr.max_entries = max_entries;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
88 attr.map_flags = map_flags;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
89
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
90 fd = ngx_bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
91 if (fd < 0) {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
92 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
93 "failed to create BPF map");
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
94 return NGX_ERROR;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
95 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
96
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
97 return fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
98 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
99
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
100
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
101 int
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
102 ngx_bpf_map_update(int fd, const void *key, const void *value, uint64_t flags)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
103 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
104 union bpf_attr attr;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
105
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
106 ngx_memzero(&attr, sizeof(union bpf_attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
107
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
108 attr.map_fd = fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
109 attr.key = (uint64_t) key;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
110 attr.value = (uint64_t) value;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
111 attr.flags = flags;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
112
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
113 return ngx_bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
114 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
115
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
116
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
117 int
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
118 ngx_bpf_map_delete(int fd, const void *key)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
119 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
120 union bpf_attr attr;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
121
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
122 ngx_memzero(&attr, sizeof(union bpf_attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
123
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
124 attr.map_fd = fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
125 attr.key = (uint64_t) key;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
126
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
127 return ngx_bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
128 }
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
129
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
130
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
131 int
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
132 ngx_bpf_map_lookup(int fd, const void *key, void *value)
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
133 {
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
134 union bpf_attr attr;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
135
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
136 ngx_memzero(&attr, sizeof(union bpf_attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
137
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
138 attr.map_fd = fd;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
139 attr.key = (uint64_t) key;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
140 attr.value = (uint64_t) value;
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
141
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
142 return ngx_bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
d3747ba486e7 Core: added interface to linux bpf() system call.
Vladimir Homutov <vl@nginx.com>
parents:
diff changeset
143 }