loader.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. #include "qosify.h"
  11. static int qosify_bpf_pr(enum libbpf_print_level level, const char *format,
  12. va_list args)
  13. {
  14. return vfprintf(stderr, format, args);
  15. }
  16. static void qosify_init_env(void)
  17. {
  18. struct rlimit limit = {
  19. .rlim_cur = RLIM_INFINITY,
  20. .rlim_max = RLIM_INFINITY,
  21. };
  22. setrlimit(RLIMIT_MEMLOCK, &limit);
  23. }
  24. static void qosify_fill_rodata(struct bpf_object *obj, uint32_t flags)
  25. {
  26. struct bpf_map *map = NULL;
  27. while ((map = bpf_map__next(map, obj)) != NULL) {
  28. if (!strstr(bpf_map__name(map), ".rodata"))
  29. continue;
  30. bpf_map__set_initial_value(map, &flags, sizeof(flags));
  31. }
  32. }
  33. static int
  34. qosify_create_program(const char *suffix, uint32_t flags)
  35. {
  36. DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts,
  37. .pin_root_path = CLASSIFY_DATA_PATH,
  38. );
  39. struct bpf_program *prog;
  40. struct bpf_object *obj;
  41. char path[256];
  42. int err;
  43. snprintf(path, sizeof(path), CLASSIFY_PIN_PATH "_" "%s", suffix);
  44. obj = bpf_object__open_file(CLASSIFY_PROG_PATH, &opts);
  45. err = libbpf_get_error(obj);
  46. if (err) {
  47. perror("bpf_object__open_file");
  48. return -1;
  49. }
  50. prog = bpf_object__find_program_by_title(obj, "classifier");
  51. if (!prog) {
  52. fprintf(stderr, "Can't find classifier prog\n");
  53. return -1;
  54. }
  55. bpf_program__set_type(prog, BPF_PROG_TYPE_SCHED_CLS);
  56. qosify_fill_rodata(obj, flags);
  57. err = bpf_object__load(obj);
  58. if (err) {
  59. perror("bpf_object__load");
  60. return -1;
  61. }
  62. libbpf_set_print(NULL);
  63. unlink(path);
  64. err = bpf_program__pin(prog, path);
  65. if (err) {
  66. fprintf(stderr, "Failed to pin program to %s: %s\n",
  67. path, strerror(-err));
  68. }
  69. bpf_object__close(obj);
  70. return 0;
  71. }
  72. int qosify_loader_init(void)
  73. {
  74. static const struct {
  75. const char *suffix;
  76. uint32_t flags;
  77. } progs[] = {
  78. { "egress_eth", 0 },
  79. { "egress_ip", QOSIFY_IP_ONLY },
  80. { "ingress_eth", QOSIFY_INGRESS },
  81. { "ingress_ip", QOSIFY_INGRESS | QOSIFY_IP_ONLY },
  82. };
  83. glob_t g;
  84. int i;
  85. if (glob(CLASSIFY_DATA_PATH "/*", 0, NULL, &g) == 0) {
  86. for (i = 0; i < g.gl_pathc; i++)
  87. unlink(g.gl_pathv[i]);
  88. }
  89. libbpf_set_print(qosify_bpf_pr);
  90. qosify_init_env();
  91. for (i = 0; i < ARRAY_SIZE(progs); i++) {
  92. if (qosify_create_program(progs[i].suffix, progs[i].flags))
  93. return -1;
  94. }
  95. return 0;
  96. }