load_sock_ops.c 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* Copyright (c) 2017 Facebook
  2. *
  3. * This program is free software; you can redistribute it and/or
  4. * modify it under the terms of version 2 of the GNU General Public
  5. * License as published by the Free Software Foundation.
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <linux/bpf.h>
  11. #include <bpf/bpf.h>
  12. #include "bpf_load.h"
  13. #include <unistd.h>
  14. #include <errno.h>
  15. #include <fcntl.h>
  16. #include <linux/unistd.h>
  17. static void usage(char *pname)
  18. {
  19. printf("USAGE:\n %s [-l] <cg-path> <prog filename>\n", pname);
  20. printf("\tLoad and attach a sock_ops program to the specified "
  21. "cgroup\n");
  22. printf("\tIf \"-l\" is used, the program will continue to run\n");
  23. printf("\tprinting the BPF log buffer\n");
  24. printf("\tIf the specified filename does not end in \".o\", it\n");
  25. printf("\tappends \"_kern.o\" to the name\n");
  26. printf("\n");
  27. printf(" %s -r <cg-path>\n", pname);
  28. printf("\tDetaches the currently attached sock_ops program\n");
  29. printf("\tfrom the specified cgroup\n");
  30. printf("\n");
  31. exit(1);
  32. }
  33. int main(int argc, char **argv)
  34. {
  35. int logFlag = 0;
  36. int error = 0;
  37. char *cg_path;
  38. char fn[500];
  39. char *prog;
  40. int cg_fd;
  41. if (argc < 3)
  42. usage(argv[0]);
  43. if (!strcmp(argv[1], "-r")) {
  44. cg_path = argv[2];
  45. cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY);
  46. error = bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS);
  47. if (error) {
  48. printf("ERROR: bpf_prog_detach: %d (%s)\n",
  49. error, strerror(errno));
  50. return 2;
  51. }
  52. return 0;
  53. } else if (!strcmp(argv[1], "-h")) {
  54. usage(argv[0]);
  55. } else if (!strcmp(argv[1], "-l")) {
  56. logFlag = 1;
  57. if (argc < 4)
  58. usage(argv[0]);
  59. }
  60. prog = argv[argc - 1];
  61. cg_path = argv[argc - 2];
  62. if (strlen(prog) > 480) {
  63. fprintf(stderr, "ERROR: program name too long (> 480 chars)\n");
  64. return 3;
  65. }
  66. cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY);
  67. if (!strcmp(prog + strlen(prog)-2, ".o"))
  68. strcpy(fn, prog);
  69. else
  70. sprintf(fn, "%s_kern.o", prog);
  71. if (logFlag)
  72. printf("loading bpf file:%s\n", fn);
  73. if (load_bpf_file(fn)) {
  74. printf("ERROR: load_bpf_file failed for: %s\n", fn);
  75. printf("%s", bpf_log_buf);
  76. return 4;
  77. }
  78. if (logFlag)
  79. printf("TCP BPF Loaded %s\n", fn);
  80. error = bpf_prog_attach(prog_fd[0], cg_fd, BPF_CGROUP_SOCK_OPS, 0);
  81. if (error) {
  82. printf("ERROR: bpf_prog_attach: %d (%s)\n",
  83. error, strerror(errno));
  84. return 5;
  85. } else if (logFlag) {
  86. read_trace_pipe();
  87. }
  88. return error;
  89. }