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