]> ruderich.org/simon Gitweb - bpf/xdp-example.git/blob - example.c
Initial commit
[bpf/xdp-example.git] / example.c
1 // SPDX-License-Identifier: (LGPL-2.1-or-later OR BSD-2-Clause)
2
3 #include <net/if.h>
4 #include <sys/resource.h>
5 #include <sys/time.h>
6 #include <unistd.h>
7
8 #include <bpf/bpf.h>
9 /* XDP_FLAGS_SKB_MODE */
10 #include <linux/if_link.h>
11
12 #include "example.skel.h"
13
14
15 static int libbpf_print(enum libbpf_print_level level, const char *format, va_list args) {
16     if (level == LIBBPF_DEBUG) {
17         return 0;
18     }
19     return vfprintf(stderr, format, args);
20 }
21
22
23 int main(int argc, char **argv) {
24     if (argc != 2) {
25         fprintf(stderr, "usage: %s <iface>\n", argv[0]);
26         return EXIT_FAILURE;
27     }
28
29     const char *iface = argv[1];
30     unsigned int ifindex = if_nametoindex(iface);
31     if (!ifindex) {
32         perror("failed to resolve iface to ifindex");
33         return EXIT_FAILURE;
34     }
35
36     struct rlimit rlim = {
37         .rlim_cur = RLIM_INFINITY,
38         .rlim_max = RLIM_INFINITY,
39     };
40     if (setrlimit(RLIMIT_MEMLOCK, &rlim)) {
41         perror("failed to increase RLIMIT_MEMLOCK");
42         return EXIT_FAILURE;
43     }
44
45     libbpf_set_print(libbpf_print);
46
47     int err;
48     struct example_bpf *obj;
49
50     obj = example_bpf__open();
51     if (!obj) {
52         fprintf(stderr, "failed to open BPF object\n");
53         return EXIT_FAILURE;
54     }
55     err = example_bpf__load(obj);
56     if (err) {
57         fprintf(stderr, "failed to load BPF object: %d\n", err);
58         goto cleanup;
59     }
60
61     /*
62      * Use "xdpgeneric" mode; less performance but supported by all drivers
63      */
64     int flags = XDP_FLAGS_SKB_MODE;
65     int fd = bpf_program__fd(obj->progs.xdp_prog);
66
67     /* Attach BPF to network interface */
68     err = bpf_set_link_xdp_fd(ifindex, fd, flags);
69     if (err) {
70         fprintf(stderr, "failed to attach BPF to iface %s (%d): %d\n",
71             iface, ifindex, err);
72         goto cleanup;
73     }
74
75     // XXX: replace with actual code, e.g. loop to get data from BPF
76     sleep(10);
77
78     /* Remove BPF from network interface */
79     fd = -1;
80     err = bpf_set_link_xdp_fd(ifindex, fd, flags);
81     if (err) {
82         fprintf(stderr, "failed to detach BPF from iface %s (%d): %d\n",
83             iface, ifindex, err);
84         goto cleanup;
85     }
86
87 cleanup:
88     example_bpf__destroy(obj);
89
90     if (err) {
91         return EXIT_FAILURE;
92     }
93     return EXIT_SUCCESS;
94 }