linux/tools/testing/selftests/bpf/flow_dissector_load.c
<<
>>
Prefs
   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
  14#include "bpf_rlimit.h"
  15#include "flow_dissector_load.h"
  16
  17const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector";
  18const char *cfg_map_name = "jmp_table";
  19bool cfg_attach = true;
  20char *cfg_section_name;
  21char *cfg_path_name;
  22
  23static void load_and_attach_program(void)
  24{
  25        int prog_fd, ret;
  26        struct bpf_object *obj;
  27
  28        ret = bpf_flow_load(&obj, cfg_path_name, cfg_section_name,
  29                            cfg_map_name, NULL, &prog_fd, NULL);
  30        if (ret)
  31                error(1, 0, "bpf_flow_load %s", cfg_path_name);
  32
  33        ret = bpf_prog_attach(prog_fd, 0 /* Ignore */, BPF_FLOW_DISSECTOR, 0);
  34        if (ret)
  35                error(1, 0, "bpf_prog_attach %s", cfg_path_name);
  36
  37        ret = bpf_object__pin(obj, cfg_pin_path);
  38        if (ret)
  39                error(1, 0, "bpf_object__pin %s", cfg_pin_path);
  40}
  41
  42static void detach_program(void)
  43{
  44        char command[64];
  45        int ret;
  46
  47        ret = bpf_prog_detach(0, BPF_FLOW_DISSECTOR);
  48        if (ret)
  49                error(1, 0, "bpf_prog_detach");
  50
  51        /* To unpin, it is necessary and sufficient to just remove this dir */
  52        sprintf(command, "rm -r %s", cfg_pin_path);
  53        ret = system(command);
  54        if (ret)
  55                error(1, errno, "%s", command);
  56}
  57
  58static void parse_opts(int argc, char **argv)
  59{
  60        bool attach = false;
  61        bool detach = false;
  62        int c;
  63
  64        while ((c = getopt(argc, argv, "adp:s:")) != -1) {
  65                switch (c) {
  66                case 'a':
  67                        if (detach)
  68                                error(1, 0, "attach/detach are exclusive");
  69                        attach = true;
  70                        break;
  71                case 'd':
  72                        if (attach)
  73                                error(1, 0, "attach/detach are exclusive");
  74                        detach = true;
  75                        break;
  76                case 'p':
  77                        if (cfg_path_name)
  78                                error(1, 0, "only one prog name can be given");
  79
  80                        cfg_path_name = optarg;
  81                        break;
  82                case 's':
  83                        if (cfg_section_name)
  84                                error(1, 0, "only one section can be given");
  85
  86                        cfg_section_name = optarg;
  87                        break;
  88                }
  89        }
  90
  91        if (detach)
  92                cfg_attach = false;
  93
  94        if (cfg_attach && !cfg_path_name)
  95                error(1, 0, "must provide a path to the BPF program");
  96
  97        if (cfg_attach && !cfg_section_name)
  98                error(1, 0, "must provide a section name");
  99}
 100
 101int main(int argc, char **argv)
 102{
 103        parse_opts(argc, argv);
 104        if (cfg_attach)
 105                load_and_attach_program();
 106        else
 107                detach_program();
 108        return 0;
 109}
 110