iproute2/tc/tc_exec.c
<<
>>
Prefs
   1/*
   2 * tc_exec.c    "tc exec".
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Authors:     Daniel Borkmann <daniel@iogearbox.net>
  10 */
  11
  12#include <stdio.h>
  13#include <stdlib.h>
  14#include <dlfcn.h>
  15
  16#include "utils.h"
  17
  18#include "tc_util.h"
  19#include "tc_common.h"
  20
  21static struct exec_util *exec_list;
  22static void *BODY;
  23
  24static void usage(void)
  25{
  26        fprintf(stderr,
  27                "Usage: tc exec [ EXEC_TYPE ] [ help | OPTIONS ]\n"
  28                "Where:\n"
  29                "EXEC_TYPE := { bpf | etc. }\n"
  30                "OPTIONS := ... try tc exec <desired EXEC_KIND> help\n");
  31}
  32
  33static int parse_noeopt(struct exec_util *eu, int argc, char **argv)
  34{
  35        if (argc) {
  36                fprintf(stderr, "Unknown exec \"%s\", hence option \"%s\" is unparsable\n",
  37                        eu->id, *argv);
  38                return -1;
  39        }
  40
  41        return 0;
  42}
  43
  44static struct exec_util *get_exec_kind(const char *name)
  45{
  46        struct exec_util *eu;
  47        char buf[256];
  48        void *dlh;
  49
  50        for (eu = exec_list; eu; eu = eu->next)
  51                if (strcmp(eu->id, name) == 0)
  52                        return eu;
  53
  54        snprintf(buf, sizeof(buf), "%s/e_%s.so", get_tc_lib(), name);
  55        dlh = dlopen(buf, RTLD_LAZY);
  56        if (dlh == NULL) {
  57                dlh = BODY;
  58                if (dlh == NULL) {
  59                        dlh = BODY = dlopen(NULL, RTLD_LAZY);
  60                        if (dlh == NULL)
  61                                goto noexist;
  62                }
  63        }
  64
  65        snprintf(buf, sizeof(buf), "%s_exec_util", name);
  66        eu = dlsym(dlh, buf);
  67        if (eu == NULL)
  68                goto noexist;
  69reg:
  70        eu->next = exec_list;
  71        exec_list = eu;
  72
  73        return eu;
  74noexist:
  75        eu = calloc(1, sizeof(*eu));
  76        if (eu) {
  77                strncpy(eu->id, name, sizeof(eu->id) - 1);
  78                eu->parse_eopt = parse_noeopt;
  79                goto reg;
  80        }
  81
  82        return eu;
  83}
  84
  85int do_exec(int argc, char **argv)
  86{
  87        struct exec_util *eu;
  88        char kind[FILTER_NAMESZ] = {};
  89
  90        if (argc < 1) {
  91                fprintf(stderr, "No command given, try \"tc exec help\".\n");
  92                return -1;
  93        }
  94
  95        if (matches(*argv, "help") == 0) {
  96                usage();
  97                return 0;
  98        }
  99
 100        strncpy(kind, *argv, sizeof(kind) - 1);
 101
 102        eu = get_exec_kind(kind);
 103
 104        argc--;
 105        argv++;
 106
 107        return eu->parse_eopt(eu, argc, argv);
 108}
 109