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 struct { 14 const char *suffix; 15 uint32_t flags; 16 int fd; 17 } bpf_progs[] = { 18 { "egress_eth", 0 }, 19 { "egress_ip", QOSIFY_IP_ONLY }, 20 { "ingress_eth", QOSIFY_INGRESS }, 21 { "ingress_ip", QOSIFY_INGRESS | QOSIFY_IP_ONLY }, 22 }; 23 24 static int qosify_bpf_pr(enum libbpf_print_level level, const char *format, 25 va_list args) 26 { 27 return vfprintf(stderr, format, args); 28 } 29 30 static void qosify_init_env(void) 31 { 32 struct rlimit limit = { 33 .rlim_cur = RLIM_INFINITY, 34 .rlim_max = RLIM_INFINITY, 35 }; 36 37 setrlimit(RLIMIT_MEMLOCK, &limit); 38 } 39 40 static void qosify_fill_rodata(struct bpf_object *obj, uint32_t flags) 41 { 42 struct bpf_map *map = NULL; 43 44 while ((map = bpf_object__next_map(obj, map)) != NULL) { 45 if (!strstr(bpf_map__name(map), ".rodata")) 46 continue; 47 48 bpf_map__set_initial_value(map, &flags, sizeof(flags)); 49 } 50 } 51 52 const char *qosify_get_program(uint32_t flags, int *fd) 53 { 54 int i; 55 56 for (i = 0; i < ARRAY_SIZE(bpf_progs); i++) { 57 if (bpf_progs[i].flags != flags) 58 continue; 59 60 *fd = bpf_progs[i].fd; 61 return bpf_progs[i].suffix; 62 } 63 64 return NULL; 65 } 66 67 68 static int 69 qosify_create_program(int idx) 70 { 71 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, 72 .pin_root_path = CLASSIFY_DATA_PATH, 73 ); 74 struct bpf_program *prog; 75 struct bpf_object *obj; 76 char path[256]; 77 int err; 78 79 snprintf(path, sizeof(path), CLASSIFY_PIN_PATH "_" "%s", bpf_progs[idx].suffix); 80 81 obj = bpf_object__open_file(CLASSIFY_PROG_PATH, &opts); 82 err = libbpf_get_error(obj); 83 if (err) { 84 perror("bpf_object__open_file"); 85 return -1; 86 } 87 88 prog = bpf_object__find_program_by_name(obj, "classify"); 89 if (!prog) { 90 fprintf(stderr, "Can't find classifier prog\n"); 91 return -1; 92 } 93 94 bpf_program__set_type(prog, BPF_PROG_TYPE_SCHED_CLS); 95 96 qosify_fill_rodata(obj, bpf_progs[idx].flags); 97 98 err = bpf_object__load(obj); 99 if (err) { 100 perror("bpf_object__load"); 101 return -1; 102 } 103 104 libbpf_set_print(NULL); 105 106 unlink(path); 107 err = bpf_program__pin(prog, path); 108 if (err) { 109 fprintf(stderr, "Failed to pin program to %s: %s\n", 110 path, strerror(-err)); 111 return -1; 112 } 113 114 bpf_object__close(obj); 115 116 err = bpf_obj_get(path); 117 if (err < 0) { 118 fprintf(stderr, "Failed to load pinned program %s: %s\n", 119 path, strerror(errno)); 120 } 121 bpf_progs[idx].fd = err; 122 123 return 0; 124 } 125 126 int qosify_loader_init(void) 127 { 128 glob_t g; 129 int i; 130 131 if (glob(CLASSIFY_DATA_PATH "/*", 0, NULL, &g) == 0) { 132 for (i = 0; i < g.gl_pathc; i++) 133 unlink(g.gl_pathv[i]); 134 } 135 136 libbpf_set_print(qosify_bpf_pr); 137 138 qosify_init_env(); 139 140 for (i = 0; i < ARRAY_SIZE(bpf_progs); i++) { 141 if (qosify_create_program(i)) 142 return -1; 143 } 144 145 return 0; 146 } 147
This page was automatically generated by LXR 0.3.1. • OpenWrt