README: fix typo
[project/qosify.git] / loader.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2021 Felix Fietkau <nbd@nbd.name>
4 */
5 #include <sys/resource.h>
6 #include <sys/stat.h>
7 #include <arpa/inet.h>
8 #include <glob.h>
9 #include <unistd.h>
10
11 #include "qosify.h"
12
13 static int qosify_bpf_pr(enum libbpf_print_level level, const char *format,
14 va_list args)
15 {
16 return vfprintf(stderr, format, args);
17 }
18
19 static void qosify_init_env(void)
20 {
21 struct rlimit limit = {
22 .rlim_cur = RLIM_INFINITY,
23 .rlim_max = RLIM_INFINITY,
24 };
25
26 setrlimit(RLIMIT_MEMLOCK, &limit);
27 }
28
29 static void qosify_fill_rodata(struct bpf_object *obj, uint32_t flags)
30 {
31 struct bpf_map *map = NULL;
32
33 while ((map = bpf_map__next(map, obj)) != NULL) {
34 if (!strstr(bpf_map__name(map), ".rodata"))
35 continue;
36
37 bpf_map__set_initial_value(map, &flags, sizeof(flags));
38 }
39 }
40
41 static int
42 qosify_create_program(const char *suffix, uint32_t flags, bool *force_init)
43 {
44 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
45 .pin_root_path = CLASSIFY_DATA_PATH,
46 );
47 struct bpf_program *prog;
48 struct bpf_object *obj;
49 struct stat st;
50 char path[256];
51 int err;
52
53 snprintf(path, sizeof(path), CLASSIFY_PIN_PATH "_" "%s", suffix);
54 if (!*force_init) {
55 if (stat(path, &st) == 0)
56 return 0;
57
58 *force_init = true;
59 }
60
61 obj = bpf_object__open_file(CLASSIFY_PROG_PATH, &opts);
62 err = libbpf_get_error(obj);
63 if (err) {
64 perror("bpf_object__open_file");
65 return -1;
66 }
67
68 prog = bpf_object__find_program_by_title(obj, "classifier");
69 if (!prog) {
70 fprintf(stderr, "Can't find classifier prog\n");
71 return -1;
72 }
73
74 bpf_program__set_type(prog, BPF_PROG_TYPE_SCHED_CLS);
75
76 qosify_fill_rodata(obj, flags);
77
78 err = bpf_object__load(obj);
79 if (err) {
80 perror("bpf_object__load");
81 return -1;
82 }
83
84 libbpf_set_print(NULL);
85
86 unlink(path);
87 err = bpf_program__pin(prog, path);
88 if (err) {
89 fprintf(stderr, "Failed to pin program to %s: %s\n",
90 path, strerror(-err));
91 }
92
93 bpf_object__close(obj);
94
95 return 0;
96 }
97
98 int qosify_loader_init(bool force_init)
99 {
100 static const struct {
101 const char *suffix;
102 uint32_t flags;
103 } progs[] = {
104 { "egress_eth", 0 },
105 { "egress_ip", QOSIFY_IP_ONLY },
106 { "ingress_eth", QOSIFY_INGRESS },
107 { "ingress_ip", QOSIFY_INGRESS | QOSIFY_IP_ONLY },
108 };
109 glob_t g;
110 int i;
111
112 if (force_init &&
113 glob(CLASSIFY_DATA_PATH "/*", 0, NULL, &g) == 0) {
114 for (i = 0; i < g.gl_pathc; i++)
115 unlink(g.gl_pathv[i]);
116 }
117
118
119 libbpf_set_print(qosify_bpf_pr);
120
121 qosify_init_env();
122
123 for (i = 0; i < ARRAY_SIZE(progs); i++) {
124 if (qosify_create_program(progs[i].suffix, progs[i].flags,
125 &force_init))
126 return -1;
127 }
128
129 return 0;
130 }