6e1051a54e
Use the libbpf skeleton facility and other utilities provided by XDP samples helper. A lot of the code in xdp_monitor and xdp_redirect_cpu has been moved to the xdp_sample_user.o helper, so we remove the duplicate functions here that are no longer needed. Thanks to BPF skeleton, we no longer depend on order of tracepoints to uninstall them on startup. Instead, the sample mask is used to install the needed tracepoints. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20210821002010.845777-15-memxor@gmail.com
120 lines
2.8 KiB
C
120 lines
2.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat, Inc. */
|
|
static const char *__doc__=
|
|
"XDP monitor tool, based on tracepoints\n";
|
|
|
|
static const char *__doc_err_only__=
|
|
" NOTICE: Only tracking XDP redirect errors\n"
|
|
" Enable redirect success stats via '-s/--stats'\n"
|
|
" (which comes with a per packet processing overhead)\n";
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <unistd.h>
|
|
#include <locale.h>
|
|
#include <sys/resource.h>
|
|
#include <getopt.h>
|
|
#include <net/if.h>
|
|
#include <time.h>
|
|
#include <signal.h>
|
|
#include <bpf/bpf.h>
|
|
#include <bpf/libbpf.h>
|
|
#include "bpf_util.h"
|
|
#include "xdp_sample_user.h"
|
|
#include "xdp_monitor.skel.h"
|
|
|
|
static int mask = SAMPLE_REDIRECT_ERR_CNT | SAMPLE_CPUMAP_ENQUEUE_CNT |
|
|
SAMPLE_CPUMAP_KTHREAD_CNT | SAMPLE_EXCEPTION_CNT |
|
|
SAMPLE_DEVMAP_XMIT_CNT | SAMPLE_DEVMAP_XMIT_CNT_MULTI;
|
|
|
|
DEFINE_SAMPLE_INIT(xdp_monitor);
|
|
|
|
static const struct option long_options[] = {
|
|
{ "help", no_argument, NULL, 'h' },
|
|
{ "stats", no_argument, NULL, 's' },
|
|
{ "interval", required_argument, NULL, 'i' },
|
|
{ "verbose", no_argument, NULL, 'v' },
|
|
{}
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
unsigned long interval = 2;
|
|
int ret = EXIT_FAIL_OPTION;
|
|
struct xdp_monitor *skel;
|
|
bool errors_only = true;
|
|
int longindex = 0, opt;
|
|
bool error = true;
|
|
|
|
/* Parse commands line args */
|
|
while ((opt = getopt_long(argc, argv, "si:vh",
|
|
long_options, &longindex)) != -1) {
|
|
switch (opt) {
|
|
case 's':
|
|
errors_only = false;
|
|
mask |= SAMPLE_REDIRECT_CNT;
|
|
break;
|
|
case 'i':
|
|
interval = strtoul(optarg, NULL, 0);
|
|
break;
|
|
case 'v':
|
|
sample_switch_mode();
|
|
break;
|
|
case 'h':
|
|
error = false;
|
|
default:
|
|
sample_usage(argv, long_options, __doc__, mask, error);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
skel = xdp_monitor__open();
|
|
if (!skel) {
|
|
fprintf(stderr, "Failed to xdp_monitor__open: %s\n",
|
|
strerror(errno));
|
|
ret = EXIT_FAIL_BPF;
|
|
goto end;
|
|
}
|
|
|
|
ret = sample_init_pre_load(skel);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "Failed to sample_init_pre_load: %s\n", strerror(-ret));
|
|
ret = EXIT_FAIL_BPF;
|
|
goto end_destroy;
|
|
}
|
|
|
|
ret = xdp_monitor__load(skel);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "Failed to xdp_monitor__load: %s\n", strerror(errno));
|
|
ret = EXIT_FAIL_BPF;
|
|
goto end_destroy;
|
|
}
|
|
|
|
ret = sample_init(skel, mask);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "Failed to initialize sample: %s\n", strerror(-ret));
|
|
ret = EXIT_FAIL_BPF;
|
|
goto end_destroy;
|
|
}
|
|
|
|
if (errors_only)
|
|
printf("%s", __doc_err_only__);
|
|
|
|
ret = sample_run(interval, NULL, NULL);
|
|
if (ret < 0) {
|
|
fprintf(stderr, "Failed during sample run: %s\n", strerror(-ret));
|
|
ret = EXIT_FAIL;
|
|
goto end_destroy;
|
|
}
|
|
ret = EXIT_OK;
|
|
end_destroy:
|
|
xdp_monitor__destroy(skel);
|
|
end:
|
|
sample_exit(ret);
|
|
}
|