Mercurial > hg > nginx-quic
comparison src/core/ngx_bpf.c @ 8268: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
8267:2c7f927f7999 | 8268: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 } |