aboutsummaryrefslogtreecommitdiff
path: root/xdp_loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'xdp_loader.c')
-rw-r--r--xdp_loader.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/xdp_loader.c b/xdp_loader.c
new file mode 100644
index 0000000..6f620b8
--- /dev/null
+++ b/xdp_loader.c
@@ -0,0 +1,70 @@
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+#include <linux/if_link.h>
+
+int main(int argc, char **argv) {
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <iface>\n", argv[0]);
+ return 1;
+ }
+
+ const char *const iface = argv[1];
+
+ int ifindex = if_nametoindex(iface);
+ if (!ifindex) {
+ perror("if_nametoindex");
+ return 1;
+ }
+
+ struct bpf_object *obj;
+ int prog_fd;
+ const char *const xdp_file = "xdp_udp_handler.o";
+
+ obj = bpf_object__open_file(xdp_file, NULL);
+ if (!obj) {
+ fprintf(stderr, "Error opening BPF object file: `%s'\n", xdp_file);
+ return 1;
+ }
+
+ if (bpf_object__load(obj)) {
+ fprintf(stderr, "Error loading BPF object\n");
+ return 1;
+ }
+
+ struct bpf_program *const prog =
+ bpf_object__find_program_by_name(obj, "xdp_udp_handler");
+ if (!prog) {
+ fprintf(stderr, "Couldn't find program\n");
+ return 1;
+ }
+
+ prog_fd = bpf_program__fd(prog);
+ if (prog_fd < 0) {
+ fprintf(stderr, "Invalid program FD\n");
+ return 1;
+ }
+
+ printf("Attaching BPF program in driver (native) mode..\n");
+ if (bpf_xdp_attach(ifindex, prog_fd,
+ XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_DRV_MODE,
+ NULL) < 0) {
+ perror("bpf_xdp_attach");
+ printf("Attaching BPF program in kernel mode..\n");
+ if (bpf_xdp_attach(ifindex, prog_fd, XDP_FLAGS_UPDATE_IF_NOEXIST, NULL) <
+ 0) {
+ perror("bpf_xdp_attach");
+ return 1;
+ }
+ }
+
+ printf("XDP program loaded\n");
+ return 0;
+}