iter.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
  2. // Copyright (C) 2020 Facebook
  3. #define _GNU_SOURCE
  4. #include <unistd.h>
  5. #include <linux/err.h>
  6. #include <bpf/libbpf.h>
  7. #include "main.h"
  8. static int do_pin(int argc, char **argv)
  9. {
  10. DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
  11. union bpf_iter_link_info linfo;
  12. const char *objfile, *path;
  13. struct bpf_program *prog;
  14. struct bpf_object *obj;
  15. struct bpf_link *link;
  16. int err = -1, map_fd = -1;
  17. if (!REQ_ARGS(2))
  18. usage();
  19. objfile = GET_ARG();
  20. path = GET_ARG();
  21. /* optional arguments */
  22. if (argc) {
  23. if (is_prefix(*argv, "map")) {
  24. NEXT_ARG();
  25. if (!REQ_ARGS(2)) {
  26. p_err("incorrect map spec");
  27. return -1;
  28. }
  29. map_fd = map_parse_fd(&argc, &argv);
  30. if (map_fd < 0)
  31. return -1;
  32. memset(&linfo, 0, sizeof(linfo));
  33. linfo.map.map_fd = map_fd;
  34. iter_opts.link_info = &linfo;
  35. iter_opts.link_info_len = sizeof(linfo);
  36. }
  37. }
  38. obj = bpf_object__open(objfile);
  39. err = libbpf_get_error(obj);
  40. if (err) {
  41. p_err("can't open objfile %s", objfile);
  42. goto close_map_fd;
  43. }
  44. err = bpf_object__load(obj);
  45. if (err) {
  46. p_err("can't load objfile %s", objfile);
  47. goto close_obj;
  48. }
  49. prog = bpf_object__next_program(obj, NULL);
  50. if (!prog) {
  51. p_err("can't find bpf program in objfile %s", objfile);
  52. goto close_obj;
  53. }
  54. link = bpf_program__attach_iter(prog, &iter_opts);
  55. err = libbpf_get_error(link);
  56. if (err) {
  57. p_err("attach_iter failed for program %s",
  58. bpf_program__name(prog));
  59. goto close_obj;
  60. }
  61. err = mount_bpffs_for_pin(path);
  62. if (err)
  63. goto close_link;
  64. err = bpf_link__pin(link, path);
  65. if (err) {
  66. p_err("pin_iter failed for program %s to path %s",
  67. bpf_program__name(prog), path);
  68. goto close_link;
  69. }
  70. close_link:
  71. bpf_link__destroy(link);
  72. close_obj:
  73. bpf_object__close(obj);
  74. close_map_fd:
  75. if (map_fd >= 0)
  76. close(map_fd);
  77. return err;
  78. }
  79. static int do_help(int argc, char **argv)
  80. {
  81. fprintf(stderr,
  82. "Usage: %1$s %2$s pin OBJ PATH [map MAP]\n"
  83. " %1$s %2$s help\n"
  84. "\n"
  85. " " HELP_SPEC_MAP "\n"
  86. " " HELP_SPEC_OPTIONS " }\n"
  87. "",
  88. bin_name, "iter");
  89. return 0;
  90. }
  91. static const struct cmd cmds[] = {
  92. { "help", do_help },
  93. { "pin", do_pin },
  94. { 0 }
  95. };
  96. int do_iter(int argc, char **argv)
  97. {
  98. return cmd_select(cmds, argc, argv, do_help);
  99. }