flow_dissector_load.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <error.h>
  3. #include <errno.h>
  4. #include <getopt.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #include <bpf/bpf.h>
  12. #include <bpf/libbpf.h>
  13. #include "flow_dissector_load.h"
  14. const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector";
  15. const char *cfg_map_name = "jmp_table";
  16. bool cfg_attach = true;
  17. char *cfg_prog_name;
  18. char *cfg_path_name;
  19. static void load_and_attach_program(void)
  20. {
  21. int prog_fd, ret;
  22. struct bpf_object *obj;
  23. /* Use libbpf 1.0 API mode */
  24. libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
  25. ret = bpf_flow_load(&obj, cfg_path_name, cfg_prog_name,
  26. cfg_map_name, NULL, &prog_fd, NULL);
  27. if (ret)
  28. error(1, 0, "bpf_flow_load %s", cfg_path_name);
  29. ret = bpf_prog_attach(prog_fd, 0 /* Ignore */, BPF_FLOW_DISSECTOR, 0);
  30. if (ret)
  31. error(1, 0, "bpf_prog_attach %s", cfg_path_name);
  32. ret = bpf_object__pin(obj, cfg_pin_path);
  33. if (ret)
  34. error(1, 0, "bpf_object__pin %s", cfg_pin_path);
  35. }
  36. static void detach_program(void)
  37. {
  38. char command[64];
  39. int ret;
  40. ret = bpf_prog_detach(0, BPF_FLOW_DISSECTOR);
  41. if (ret)
  42. error(1, 0, "bpf_prog_detach");
  43. /* To unpin, it is necessary and sufficient to just remove this dir */
  44. sprintf(command, "rm -r %s", cfg_pin_path);
  45. ret = system(command);
  46. if (ret)
  47. error(1, errno, "%s", command);
  48. }
  49. static void parse_opts(int argc, char **argv)
  50. {
  51. bool attach = false;
  52. bool detach = false;
  53. int c;
  54. while ((c = getopt(argc, argv, "adp:s:")) != -1) {
  55. switch (c) {
  56. case 'a':
  57. if (detach)
  58. error(1, 0, "attach/detach are exclusive");
  59. attach = true;
  60. break;
  61. case 'd':
  62. if (attach)
  63. error(1, 0, "attach/detach are exclusive");
  64. detach = true;
  65. break;
  66. case 'p':
  67. if (cfg_path_name)
  68. error(1, 0, "only one path can be given");
  69. cfg_path_name = optarg;
  70. break;
  71. case 's':
  72. if (cfg_prog_name)
  73. error(1, 0, "only one prog can be given");
  74. cfg_prog_name = optarg;
  75. break;
  76. }
  77. }
  78. if (detach)
  79. cfg_attach = false;
  80. if (cfg_attach && !cfg_path_name)
  81. error(1, 0, "must provide a path to the BPF program");
  82. if (cfg_attach && !cfg_prog_name)
  83. error(1, 0, "must provide a section name");
  84. }
  85. int main(int argc, char **argv)
  86. {
  87. parse_opts(argc, argv);
  88. if (cfg_attach)
  89. load_and_attach_program();
  90. else
  91. detach_program();
  92. return 0;
  93. }