Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/samples/bpf/fds_example.c
25924 views
1
#include <linux/unistd.h>
2
#include <linux/bpf.h>
3
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <stdint.h>
7
#include <unistd.h>
8
#include <string.h>
9
#include <assert.h>
10
#include <errno.h>
11
12
#include <sys/types.h>
13
#include <sys/socket.h>
14
15
#include <bpf/bpf.h>
16
17
#include <bpf/libbpf.h>
18
#include "bpf_insn.h"
19
#include "sock_example.h"
20
#include "bpf_util.h"
21
22
#define BPF_F_PIN (1 << 0)
23
#define BPF_F_GET (1 << 1)
24
#define BPF_F_PIN_GET (BPF_F_PIN | BPF_F_GET)
25
26
#define BPF_F_KEY (1 << 2)
27
#define BPF_F_VAL (1 << 3)
28
#define BPF_F_KEY_VAL (BPF_F_KEY | BPF_F_VAL)
29
30
#define BPF_M_UNSPEC 0
31
#define BPF_M_MAP 1
32
#define BPF_M_PROG 2
33
34
char bpf_log_buf[BPF_LOG_BUF_SIZE];
35
36
static void usage(void)
37
{
38
printf("Usage: fds_example [...]\n");
39
printf(" -F <file> File to pin/get object\n");
40
printf(" -P |- pin object\n");
41
printf(" -G `- get object\n");
42
printf(" -m eBPF map mode\n");
43
printf(" -k <key> |- map key\n");
44
printf(" -v <value> `- map value\n");
45
printf(" -p eBPF prog mode\n");
46
printf(" -o <object> `- object file\n");
47
printf(" -h Display this help.\n");
48
}
49
50
static int bpf_prog_create(const char *object)
51
{
52
static struct bpf_insn insns[] = {
53
BPF_MOV64_IMM(BPF_REG_0, 1),
54
BPF_EXIT_INSN(),
55
};
56
size_t insns_cnt = ARRAY_SIZE(insns);
57
struct bpf_object *obj;
58
int err;
59
60
if (object) {
61
obj = bpf_object__open_file(object, NULL);
62
assert(!libbpf_get_error(obj));
63
err = bpf_object__load(obj);
64
assert(!err);
65
return bpf_program__fd(bpf_object__next_program(obj, NULL));
66
} else {
67
LIBBPF_OPTS(bpf_prog_load_opts, opts,
68
.log_buf = bpf_log_buf,
69
.log_size = BPF_LOG_BUF_SIZE,
70
);
71
72
return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL",
73
insns, insns_cnt, &opts);
74
}
75
}
76
77
static int bpf_do_map(const char *file, uint32_t flags, uint32_t key,
78
uint32_t value)
79
{
80
int fd, ret;
81
82
if (flags & BPF_F_PIN) {
83
fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, sizeof(uint32_t),
84
sizeof(uint32_t), 1024, NULL);
85
printf("bpf: map fd:%d (%s)\n", fd, strerror(errno));
86
assert(fd > 0);
87
88
ret = bpf_obj_pin(fd, file);
89
printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno));
90
assert(ret == 0);
91
} else {
92
fd = bpf_obj_get(file);
93
printf("bpf: get fd:%d (%s)\n", fd, strerror(errno));
94
assert(fd > 0);
95
}
96
97
if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) {
98
ret = bpf_map_update_elem(fd, &key, &value, 0);
99
printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value,
100
ret, strerror(errno));
101
assert(ret == 0);
102
} else if (flags & BPF_F_KEY) {
103
ret = bpf_map_lookup_elem(fd, &key, &value);
104
printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value,
105
ret, strerror(errno));
106
assert(ret == 0);
107
}
108
109
return 0;
110
}
111
112
static int bpf_do_prog(const char *file, uint32_t flags, const char *object)
113
{
114
int fd, sock, ret;
115
116
if (flags & BPF_F_PIN) {
117
fd = bpf_prog_create(object);
118
printf("bpf: prog fd:%d (%s)\n", fd, strerror(errno));
119
assert(fd > 0);
120
121
ret = bpf_obj_pin(fd, file);
122
printf("bpf: pin ret:(%d,%s)\n", ret, strerror(errno));
123
assert(ret == 0);
124
} else {
125
fd = bpf_obj_get(file);
126
printf("bpf: get fd:%d (%s)\n", fd, strerror(errno));
127
assert(fd > 0);
128
}
129
130
sock = open_raw_sock("lo");
131
assert(sock > 0);
132
133
ret = setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &fd, sizeof(fd));
134
printf("bpf: sock:%d <- fd:%d attached ret:(%d,%s)\n", sock, fd,
135
ret, strerror(errno));
136
assert(ret == 0);
137
138
return 0;
139
}
140
141
int main(int argc, char **argv)
142
{
143
const char *file = NULL, *object = NULL;
144
uint32_t key = 0, value = 0, flags = 0;
145
int opt, mode = BPF_M_UNSPEC;
146
147
while ((opt = getopt(argc, argv, "F:PGmk:v:po:")) != -1) {
148
switch (opt) {
149
/* General args */
150
case 'F':
151
file = optarg;
152
break;
153
case 'P':
154
flags |= BPF_F_PIN;
155
break;
156
case 'G':
157
flags |= BPF_F_GET;
158
break;
159
/* Map-related args */
160
case 'm':
161
mode = BPF_M_MAP;
162
break;
163
case 'k':
164
key = strtoul(optarg, NULL, 0);
165
flags |= BPF_F_KEY;
166
break;
167
case 'v':
168
value = strtoul(optarg, NULL, 0);
169
flags |= BPF_F_VAL;
170
break;
171
/* Prog-related args */
172
case 'p':
173
mode = BPF_M_PROG;
174
break;
175
case 'o':
176
object = optarg;
177
break;
178
default:
179
goto out;
180
}
181
}
182
183
if (!(flags & BPF_F_PIN_GET) || !file)
184
goto out;
185
186
switch (mode) {
187
case BPF_M_MAP:
188
return bpf_do_map(file, flags, key, value);
189
case BPF_M_PROG:
190
return bpf_do_prog(file, flags, object);
191
}
192
out:
193
usage();
194
return -1;
195
}
196
197