Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <error.h>
0003 #include <errno.h>
0004 #include <getopt.h>
0005 #include <stdio.h>
0006 #include <stdlib.h>
0007 #include <string.h>
0008 #include <sys/stat.h>
0009 #include <fcntl.h>
0010 #include <unistd.h>
0011 #include <bpf/bpf.h>
0012 #include <bpf/libbpf.h>
0013 
0014 #include "flow_dissector_load.h"
0015 
0016 const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector";
0017 const char *cfg_map_name = "jmp_table";
0018 bool cfg_attach = true;
0019 char *cfg_prog_name;
0020 char *cfg_path_name;
0021 
0022 static void load_and_attach_program(void)
0023 {
0024     int prog_fd, ret;
0025     struct bpf_object *obj;
0026 
0027     /* Use libbpf 1.0 API mode */
0028     libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
0029 
0030     ret = bpf_flow_load(&obj, cfg_path_name, cfg_prog_name,
0031                 cfg_map_name, NULL, &prog_fd, NULL);
0032     if (ret)
0033         error(1, 0, "bpf_flow_load %s", cfg_path_name);
0034 
0035     ret = bpf_prog_attach(prog_fd, 0 /* Ignore */, BPF_FLOW_DISSECTOR, 0);
0036     if (ret)
0037         error(1, 0, "bpf_prog_attach %s", cfg_path_name);
0038 
0039     ret = bpf_object__pin(obj, cfg_pin_path);
0040     if (ret)
0041         error(1, 0, "bpf_object__pin %s", cfg_pin_path);
0042 }
0043 
0044 static void detach_program(void)
0045 {
0046     char command[64];
0047     int ret;
0048 
0049     ret = bpf_prog_detach(0, BPF_FLOW_DISSECTOR);
0050     if (ret)
0051         error(1, 0, "bpf_prog_detach");
0052 
0053     /* To unpin, it is necessary and sufficient to just remove this dir */
0054     sprintf(command, "rm -r %s", cfg_pin_path);
0055     ret = system(command);
0056     if (ret)
0057         error(1, errno, "%s", command);
0058 }
0059 
0060 static void parse_opts(int argc, char **argv)
0061 {
0062     bool attach = false;
0063     bool detach = false;
0064     int c;
0065 
0066     while ((c = getopt(argc, argv, "adp:s:")) != -1) {
0067         switch (c) {
0068         case 'a':
0069             if (detach)
0070                 error(1, 0, "attach/detach are exclusive");
0071             attach = true;
0072             break;
0073         case 'd':
0074             if (attach)
0075                 error(1, 0, "attach/detach are exclusive");
0076             detach = true;
0077             break;
0078         case 'p':
0079             if (cfg_path_name)
0080                 error(1, 0, "only one path can be given");
0081 
0082             cfg_path_name = optarg;
0083             break;
0084         case 's':
0085             if (cfg_prog_name)
0086                 error(1, 0, "only one prog can be given");
0087 
0088             cfg_prog_name = optarg;
0089             break;
0090         }
0091     }
0092 
0093     if (detach)
0094         cfg_attach = false;
0095 
0096     if (cfg_attach && !cfg_path_name)
0097         error(1, 0, "must provide a path to the BPF program");
0098 
0099     if (cfg_attach && !cfg_prog_name)
0100         error(1, 0, "must provide a section name");
0101 }
0102 
0103 int main(int argc, char **argv)
0104 {
0105     parse_opts(argc, argv);
0106     if (cfg_attach)
0107         load_and_attach_program();
0108     else
0109         detach_program();
0110     return 0;
0111 }