Skip to content

Commit be5bca4

Browse files
Jakub Kicinskiborkmann
authored andcommitted
samples: bpf: convert some XDP samples from bpf_load to libbpf
Now that we can use full powers of libbpf in BPF samples, we should perhaps make the simplest XDP programs not depend on bpf_load helpers. This way newcomers will be exposed to the recommended library from the start. Use of bpf_prog_load_xattr() will also make it trivial to later on request offload of the programs by simply adding ifindex to the xattr. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 17387dd commit be5bca4

File tree

4 files changed

+78
-43
lines changed

4 files changed

+78
-43
lines changed

samples/bpf/Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ test_cgrp2_attach-objs := test_cgrp2_attach.o $(LIBBPF)
7979
test_cgrp2_attach2-objs := test_cgrp2_attach2.o $(LIBBPF) $(CGROUP_HELPERS)
8080
test_cgrp2_sock-objs := test_cgrp2_sock.o $(LIBBPF)
8181
test_cgrp2_sock2-objs := bpf_load.o $(LIBBPF) test_cgrp2_sock2.o
82-
xdp1-objs := bpf_load.o $(LIBBPF) xdp1_user.o
82+
xdp1-objs := xdp1_user.o $(LIBBPF)
8383
# reuse xdp1 source intentionally
84-
xdp2-objs := bpf_load.o $(LIBBPF) xdp1_user.o
84+
xdp2-objs := xdp1_user.o $(LIBBPF)
8585
xdp_router_ipv4-objs := bpf_load.o $(LIBBPF) xdp_router_ipv4_user.o
8686
test_current_task_under_cgroup-objs := bpf_load.o $(LIBBPF) $(CGROUP_HELPERS) \
8787
test_current_task_under_cgroup_user.o
@@ -96,10 +96,10 @@ xdp_redirect-objs := bpf_load.o $(LIBBPF) xdp_redirect_user.o
9696
xdp_redirect_map-objs := bpf_load.o $(LIBBPF) xdp_redirect_map_user.o
9797
xdp_redirect_cpu-objs := bpf_load.o $(LIBBPF) xdp_redirect_cpu_user.o
9898
xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o
99-
xdp_rxq_info-objs := bpf_load.o $(LIBBPF) xdp_rxq_info_user.o
99+
xdp_rxq_info-objs := xdp_rxq_info_user.o $(LIBBPF)
100100
syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o
101101
cpustat-objs := bpf_load.o $(LIBBPF) cpustat_user.o
102-
xdp_adjust_tail-objs := bpf_load.o $(LIBBPF) xdp_adjust_tail_user.o
102+
xdp_adjust_tail-objs := xdp_adjust_tail_user.o $(LIBBPF)
103103
xdpsock-objs := bpf_load.o $(LIBBPF) xdpsock_user.o
104104
xdp_fwd-objs := bpf_load.o $(LIBBPF) xdp_fwd_user.o
105105

samples/bpf/xdp1_user.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
#include <libgen.h>
1717
#include <sys/resource.h>
1818

19-
#include "bpf_load.h"
2019
#include "bpf_util.h"
21-
#include "libbpf.h"
20+
#include "bpf/bpf.h"
21+
#include "bpf/libbpf.h"
2222

2323
static int ifindex;
2424
static __u32 xdp_flags;
@@ -31,7 +31,7 @@ static void int_exit(int sig)
3131

3232
/* simple per-protocol drop counter
3333
*/
34-
static void poll_stats(int interval)
34+
static void poll_stats(int map_fd, int interval)
3535
{
3636
unsigned int nr_cpus = bpf_num_possible_cpus();
3737
const unsigned int nr_keys = 256;
@@ -47,7 +47,7 @@ static void poll_stats(int interval)
4747
for (key = 0; key < nr_keys; key++) {
4848
__u64 sum = 0;
4949

50-
assert(bpf_map_lookup_elem(map_fd[0], &key, values) == 0);
50+
assert(bpf_map_lookup_elem(map_fd, &key, values) == 0);
5151
for (i = 0; i < nr_cpus; i++)
5252
sum += (values[i] - prev[key][i]);
5353
if (sum)
@@ -71,9 +71,14 @@ static void usage(const char *prog)
7171
int main(int argc, char **argv)
7272
{
7373
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
74+
struct bpf_prog_load_attr prog_load_attr = {
75+
.prog_type = BPF_PROG_TYPE_XDP,
76+
};
7477
const char *optstr = "SN";
78+
int prog_fd, map_fd, opt;
79+
struct bpf_object *obj;
80+
struct bpf_map *map;
7581
char filename[256];
76-
int opt;
7782

7883
while ((opt = getopt(argc, argv, optstr)) != -1) {
7984
switch (opt) {
@@ -102,26 +107,32 @@ int main(int argc, char **argv)
102107
ifindex = strtoul(argv[optind], NULL, 0);
103108

104109
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
110+
prog_load_attr.file = filename;
105111

106-
if (load_bpf_file(filename)) {
107-
printf("%s", bpf_log_buf);
112+
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
113+
return 1;
114+
115+
map = bpf_map__next(NULL, obj);
116+
if (!map) {
117+
printf("finding a map in obj file failed\n");
108118
return 1;
109119
}
120+
map_fd = bpf_map__fd(map);
110121

111-
if (!prog_fd[0]) {
122+
if (!prog_fd) {
112123
printf("load_bpf_file: %s\n", strerror(errno));
113124
return 1;
114125
}
115126

116127
signal(SIGINT, int_exit);
117128
signal(SIGTERM, int_exit);
118129

119-
if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
130+
if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
120131
printf("link set xdp fd failed\n");
121132
return 1;
122133
}
123134

124-
poll_stats(2);
135+
poll_stats(map_fd, 2);
125136

126137
return 0;
127138
}

samples/bpf/xdp_adjust_tail_user.c

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@
1818
#include <netinet/ether.h>
1919
#include <unistd.h>
2020
#include <time.h>
21-
#include "bpf_load.h"
22-
#include "libbpf.h"
23-
#include "bpf_util.h"
21+
#include "bpf/bpf.h"
22+
#include "bpf/libbpf.h"
2423

2524
#define STATS_INTERVAL_S 2U
2625

@@ -36,7 +35,7 @@ static void int_exit(int sig)
3635

3736
/* simple "icmp packet too big sent" counter
3837
*/
39-
static void poll_stats(unsigned int kill_after_s)
38+
static void poll_stats(unsigned int map_fd, unsigned int kill_after_s)
4039
{
4140
time_t started_at = time(NULL);
4241
__u64 value = 0;
@@ -46,7 +45,7 @@ static void poll_stats(unsigned int kill_after_s)
4645
while (!kill_after_s || time(NULL) - started_at <= kill_after_s) {
4746
sleep(STATS_INTERVAL_S);
4847

49-
assert(bpf_map_lookup_elem(map_fd[0], &key, &value) == 0);
48+
assert(bpf_map_lookup_elem(map_fd, &key, &value) == 0);
5049

5150
printf("icmp \"packet too big\" sent: %10llu pkts\n", value);
5251
}
@@ -66,14 +65,17 @@ static void usage(const char *cmd)
6665

6766
int main(int argc, char **argv)
6867
{
68+
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
69+
struct bpf_prog_load_attr prog_load_attr = {
70+
.prog_type = BPF_PROG_TYPE_XDP,
71+
};
6972
unsigned char opt_flags[256] = {};
7073
unsigned int kill_after_s = 0;
7174
const char *optstr = "i:T:SNh";
72-
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
75+
int i, prog_fd, map_fd, opt;
76+
struct bpf_object *obj;
77+
struct bpf_map *map;
7378
char filename[256];
74-
int opt;
75-
int i;
76-
7779

7880
for (i = 0; i < strlen(optstr); i++)
7981
if (optstr[i] != 'h' && 'a' <= optstr[i] && optstr[i] <= 'z')
@@ -115,26 +117,32 @@ int main(int argc, char **argv)
115117
}
116118

117119
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
120+
prog_load_attr.file = filename;
121+
122+
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
123+
return 1;
118124

119-
if (load_bpf_file(filename)) {
120-
printf("%s", bpf_log_buf);
125+
map = bpf_map__next(NULL, obj);
126+
if (!map) {
127+
printf("finding a map in obj file failed\n");
121128
return 1;
122129
}
130+
map_fd = bpf_map__fd(map);
123131

124-
if (!prog_fd[0]) {
132+
if (!prog_fd) {
125133
printf("load_bpf_file: %s\n", strerror(errno));
126134
return 1;
127135
}
128136

129137
signal(SIGINT, int_exit);
130138
signal(SIGTERM, int_exit);
131139

132-
if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
140+
if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
133141
printf("link set xdp fd failed\n");
134142
return 1;
135143
}
136144

137-
poll_stats(kill_after_s);
145+
poll_stats(map_fd, kill_after_s);
138146

139147
bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
140148

samples/bpf/xdp_rxq_info_user.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ static const char *__doc__ = " XDP RX-queue info extract example\n\n"
2222
#include <arpa/inet.h>
2323
#include <linux/if_link.h>
2424

25-
#include "libbpf.h"
26-
#include "bpf_load.h"
25+
#include "bpf/bpf.h"
26+
#include "bpf/libbpf.h"
2727
#include "bpf_util.h"
2828

2929
static int ifindex = -1;
@@ -32,6 +32,9 @@ static char *ifname;
3232

3333
static __u32 xdp_flags;
3434

35+
static struct bpf_map *stats_global_map;
36+
static struct bpf_map *rx_queue_index_map;
37+
3538
/* Exit return codes */
3639
#define EXIT_OK 0
3740
#define EXIT_FAIL 1
@@ -174,7 +177,7 @@ static struct datarec *alloc_record_per_cpu(void)
174177

175178
static struct record *alloc_record_per_rxq(void)
176179
{
177-
unsigned int nr_rxqs = map_data[2].def.max_entries;
180+
unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries;
178181
struct record *array;
179182
size_t size;
180183

@@ -190,7 +193,7 @@ static struct record *alloc_record_per_rxq(void)
190193

191194
static struct stats_record *alloc_stats_record(void)
192195
{
193-
unsigned int nr_rxqs = map_data[2].def.max_entries;
196+
unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries;
194197
struct stats_record *rec;
195198
int i;
196199

@@ -210,7 +213,7 @@ static struct stats_record *alloc_stats_record(void)
210213

211214
static void free_stats_record(struct stats_record *r)
212215
{
213-
unsigned int nr_rxqs = map_data[2].def.max_entries;
216+
unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries;
214217
int i;
215218

216219
for (i = 0; i < nr_rxqs; i++)
@@ -254,11 +257,11 @@ static void stats_collect(struct stats_record *rec)
254257
{
255258
int fd, i, max_rxqs;
256259

257-
fd = map_data[1].fd; /* map: stats_global_map */
260+
fd = bpf_map__fd(stats_global_map);
258261
map_collect_percpu(fd, 0, &rec->stats);
259262

260-
fd = map_data[2].fd; /* map: rx_queue_index_map */
261-
max_rxqs = map_data[2].def.max_entries;
263+
fd = bpf_map__fd(rx_queue_index_map);
264+
max_rxqs = bpf_map__def(rx_queue_index_map)->max_entries;
262265
for (i = 0; i < max_rxqs; i++)
263266
map_collect_percpu(fd, i, &rec->rxq[i]);
264267
}
@@ -304,8 +307,8 @@ static void stats_print(struct stats_record *stats_rec,
304307
struct stats_record *stats_prev,
305308
int action)
306309
{
310+
unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries;
307311
unsigned int nr_cpus = bpf_num_possible_cpus();
308-
unsigned int nr_rxqs = map_data[2].def.max_entries;
309312
double pps = 0, err = 0;
310313
struct record *rec, *prev;
311314
double t;
@@ -419,31 +422,44 @@ static void stats_poll(int interval, int action)
419422
int main(int argc, char **argv)
420423
{
421424
struct rlimit r = {10 * 1024 * 1024, RLIM_INFINITY};
425+
struct bpf_prog_load_attr prog_load_attr = {
426+
.prog_type = BPF_PROG_TYPE_XDP,
427+
};
428+
int prog_fd, map_fd, opt, err;
422429
bool use_separators = true;
423430
struct config cfg = { 0 };
431+
struct bpf_object *obj;
432+
struct bpf_map *map;
424433
char filename[256];
425434
int longindex = 0;
426435
int interval = 2;
427436
__u32 key = 0;
428-
int opt, err;
429437

430438
char action_str_buf[XDP_ACTION_MAX_STRLEN + 1 /* for \0 */] = { 0 };
431439
int action = XDP_PASS; /* Default action */
432440
char *action_str = NULL;
433441

434442
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
443+
prog_load_attr.file = filename;
435444

436445
if (setrlimit(RLIMIT_MEMLOCK, &r)) {
437446
perror("setrlimit(RLIMIT_MEMLOCK)");
438447
return 1;
439448
}
440449

441-
if (load_bpf_file(filename)) {
442-
fprintf(stderr, "ERR in load_bpf_file(): %s", bpf_log_buf);
450+
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
451+
return EXIT_FAIL;
452+
453+
map = bpf_map__next(NULL, obj);
454+
stats_global_map = bpf_map__next(map, obj);
455+
rx_queue_index_map = bpf_map__next(stats_global_map, obj);
456+
if (!map || !stats_global_map || !rx_queue_index_map) {
457+
printf("finding a map in obj file failed\n");
443458
return EXIT_FAIL;
444459
}
460+
map_fd = bpf_map__fd(map);
445461

446-
if (!prog_fd[0]) {
462+
if (!prog_fd) {
447463
fprintf(stderr, "ERR: load_bpf_file: %s\n", strerror(errno));
448464
return EXIT_FAIL;
449465
}
@@ -512,7 +528,7 @@ int main(int argc, char **argv)
512528
setlocale(LC_NUMERIC, "en_US");
513529

514530
/* User-side setup ifindex in config_map */
515-
err = bpf_map_update_elem(map_fd[0], &key, &cfg, 0);
531+
err = bpf_map_update_elem(map_fd, &key, &cfg, 0);
516532
if (err) {
517533
fprintf(stderr, "Store config failed (err:%d)\n", err);
518534
exit(EXIT_FAIL_BPF);
@@ -521,7 +537,7 @@ int main(int argc, char **argv)
521537
/* Remove XDP program when program is interrupted */
522538
signal(SIGINT, int_exit);
523539

524-
if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
540+
if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
525541
fprintf(stderr, "link set xdp fd failed\n");
526542
return EXIT_FAIL_XDP;
527543
}

0 commit comments

Comments
 (0)