linux/samples/bpf/xdp_monitor_user.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat, Inc. */
   3static const char *__doc__=
   4"XDP monitor tool, based on tracepoints\n";
   5
   6static const char *__doc_err_only__=
   7" NOTICE: Only tracking XDP redirect errors\n"
   8"         Enable redirect success stats via '-s/--stats'\n"
   9"         (which comes with a per packet processing overhead)\n";
  10
  11#include <errno.h>
  12#include <stdio.h>
  13#include <stdlib.h>
  14#include <stdbool.h>
  15#include <stdint.h>
  16#include <string.h>
  17#include <ctype.h>
  18#include <unistd.h>
  19#include <locale.h>
  20#include <sys/resource.h>
  21#include <getopt.h>
  22#include <net/if.h>
  23#include <time.h>
  24#include <signal.h>
  25#include <bpf/bpf.h>
  26#include <bpf/libbpf.h>
  27#include "bpf_util.h"
  28#include "xdp_sample_user.h"
  29#include "xdp_monitor.skel.h"
  30
  31static int mask = SAMPLE_REDIRECT_ERR_CNT | SAMPLE_CPUMAP_ENQUEUE_CNT |
  32                  SAMPLE_CPUMAP_KTHREAD_CNT | SAMPLE_EXCEPTION_CNT |
  33                  SAMPLE_DEVMAP_XMIT_CNT | SAMPLE_DEVMAP_XMIT_CNT_MULTI;
  34
  35DEFINE_SAMPLE_INIT(xdp_monitor);
  36
  37static const struct option long_options[] = {
  38        { "help", no_argument, NULL, 'h' },
  39        { "stats", no_argument, NULL, 's' },
  40        { "interval", required_argument, NULL, 'i' },
  41        { "verbose", no_argument, NULL, 'v' },
  42        {}
  43};
  44
  45int main(int argc, char **argv)
  46{
  47        unsigned long interval = 2;
  48        int ret = EXIT_FAIL_OPTION;
  49        struct xdp_monitor *skel;
  50        bool errors_only = true;
  51        int longindex = 0, opt;
  52        bool error = true;
  53
  54        /* Parse commands line args */
  55        while ((opt = getopt_long(argc, argv, "si:vh",
  56                                  long_options, &longindex)) != -1) {
  57                switch (opt) {
  58                case 's':
  59                        errors_only = false;
  60                        mask |= SAMPLE_REDIRECT_CNT;
  61                        break;
  62                case 'i':
  63                        interval = strtoul(optarg, NULL, 0);
  64                        break;
  65                case 'v':
  66                        sample_switch_mode();
  67                        break;
  68                case 'h':
  69                        error = false;
  70                default:
  71                        sample_usage(argv, long_options, __doc__, mask, error);
  72                        return ret;
  73                }
  74        }
  75
  76        skel = xdp_monitor__open();
  77        if (!skel) {
  78                fprintf(stderr, "Failed to xdp_monitor__open: %s\n",
  79                        strerror(errno));
  80                ret = EXIT_FAIL_BPF;
  81                goto end;
  82        }
  83
  84        ret = sample_init_pre_load(skel);
  85        if (ret < 0) {
  86                fprintf(stderr, "Failed to sample_init_pre_load: %s\n", strerror(-ret));
  87                ret = EXIT_FAIL_BPF;
  88                goto end_destroy;
  89        }
  90
  91        ret = xdp_monitor__load(skel);
  92        if (ret < 0) {
  93                fprintf(stderr, "Failed to xdp_monitor__load: %s\n", strerror(errno));
  94                ret = EXIT_FAIL_BPF;
  95                goto end_destroy;
  96        }
  97
  98        ret = sample_init(skel, mask);
  99        if (ret < 0) {
 100                fprintf(stderr, "Failed to initialize sample: %s\n", strerror(-ret));
 101                ret = EXIT_FAIL_BPF;
 102                goto end_destroy;
 103        }
 104
 105        if (errors_only)
 106                printf("%s", __doc_err_only__);
 107
 108        ret = sample_run(interval, NULL, NULL);
 109        if (ret < 0) {
 110                fprintf(stderr, "Failed during sample run: %s\n", strerror(-ret));
 111                ret = EXIT_FAIL;
 112                goto end_destroy;
 113        }
 114        ret = EXIT_OK;
 115end_destroy:
 116        xdp_monitor__destroy(skel);
 117end:
 118        sample_exit(ret);
 119}
 120