mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 16:24:13 +08:00
7cf245a37e
Fix all files in samples/bpf to include libbpf header files with the bpf/
prefix, to be consistent with external users of the library. Also ensure
that all includes of exported libbpf header files (those that are exported
on 'make install' of the library) use bracketed includes instead of quoted.
To make sure no new files are introduced that doesn't include the bpf/
prefix in its include, remove tools/lib/bpf from the include path entirely,
and use tools/lib instead.
Fixes: 6910d7d386
("selftests/bpf: Ensure bpf_helper_defs.h are taken from selftests dir")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/157952560911.1683545.8795966751309534150.stgit@toke.dk
171 lines
3.8 KiB
C
171 lines
3.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Copyright (c) 2017-18 David Ahern <dsahern@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of version 2 of the GNU General Public
|
|
* License as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*/
|
|
|
|
#include <linux/bpf.h>
|
|
#include <linux/if_link.h>
|
|
#include <linux/limits.h>
|
|
#include <net/if.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <libgen.h>
|
|
|
|
#include <bpf/libbpf.h>
|
|
#include <bpf/bpf.h>
|
|
|
|
static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
|
|
|
|
static int do_attach(int idx, int prog_fd, int map_fd, const char *name)
|
|
{
|
|
int err;
|
|
|
|
err = bpf_set_link_xdp_fd(idx, prog_fd, xdp_flags);
|
|
if (err < 0) {
|
|
printf("ERROR: failed to attach program to %s\n", name);
|
|
return err;
|
|
}
|
|
|
|
/* Adding ifindex as a possible egress TX port */
|
|
err = bpf_map_update_elem(map_fd, &idx, &idx, 0);
|
|
if (err)
|
|
printf("ERROR: failed using device %s as TX-port\n", name);
|
|
|
|
return err;
|
|
}
|
|
|
|
static int do_detach(int idx, const char *name)
|
|
{
|
|
int err;
|
|
|
|
err = bpf_set_link_xdp_fd(idx, -1, xdp_flags);
|
|
if (err < 0)
|
|
printf("ERROR: failed to detach program from %s\n", name);
|
|
|
|
/* TODO: Remember to cleanup map, when adding use of shared map
|
|
* bpf_map_delete_elem((map_fd, &idx);
|
|
*/
|
|
return err;
|
|
}
|
|
|
|
static void usage(const char *prog)
|
|
{
|
|
fprintf(stderr,
|
|
"usage: %s [OPTS] interface-list\n"
|
|
"\nOPTS:\n"
|
|
" -d detach program\n"
|
|
" -D direct table lookups (skip fib rules)\n",
|
|
prog);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
struct bpf_prog_load_attr prog_load_attr = {
|
|
.prog_type = BPF_PROG_TYPE_XDP,
|
|
};
|
|
const char *prog_name = "xdp_fwd";
|
|
struct bpf_program *prog;
|
|
int prog_fd, map_fd = -1;
|
|
char filename[PATH_MAX];
|
|
struct bpf_object *obj;
|
|
int opt, i, idx, err;
|
|
int attach = 1;
|
|
int ret = 0;
|
|
|
|
while ((opt = getopt(argc, argv, ":dDSF")) != -1) {
|
|
switch (opt) {
|
|
case 'd':
|
|
attach = 0;
|
|
break;
|
|
case 'S':
|
|
xdp_flags |= XDP_FLAGS_SKB_MODE;
|
|
break;
|
|
case 'F':
|
|
xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST;
|
|
break;
|
|
case 'D':
|
|
prog_name = "xdp_fwd_direct";
|
|
break;
|
|
default:
|
|
usage(basename(argv[0]));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (!(xdp_flags & XDP_FLAGS_SKB_MODE))
|
|
xdp_flags |= XDP_FLAGS_DRV_MODE;
|
|
|
|
if (optind == argc) {
|
|
usage(basename(argv[0]));
|
|
return 1;
|
|
}
|
|
|
|
if (attach) {
|
|
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
|
|
prog_load_attr.file = filename;
|
|
|
|
if (access(filename, O_RDONLY) < 0) {
|
|
printf("error accessing file %s: %s\n",
|
|
filename, strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
err = bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd);
|
|
if (err) {
|
|
printf("Does kernel support devmap lookup?\n");
|
|
/* If not, the error message will be:
|
|
* "cannot pass map_type 14 into func bpf_map_lookup_elem#1"
|
|
*/
|
|
return 1;
|
|
}
|
|
|
|
prog = bpf_object__find_program_by_title(obj, prog_name);
|
|
prog_fd = bpf_program__fd(prog);
|
|
if (prog_fd < 0) {
|
|
printf("program not found: %s\n", strerror(prog_fd));
|
|
return 1;
|
|
}
|
|
map_fd = bpf_map__fd(bpf_object__find_map_by_name(obj,
|
|
"xdp_tx_ports"));
|
|
if (map_fd < 0) {
|
|
printf("map not found: %s\n", strerror(map_fd));
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
for (i = optind; i < argc; ++i) {
|
|
idx = if_nametoindex(argv[i]);
|
|
if (!idx)
|
|
idx = strtoul(argv[i], NULL, 0);
|
|
|
|
if (!idx) {
|
|
fprintf(stderr, "Invalid arg\n");
|
|
return 1;
|
|
}
|
|
if (!attach) {
|
|
err = do_detach(idx, argv[i]);
|
|
if (err)
|
|
ret = err;
|
|
} else {
|
|
err = do_attach(idx, prog_fd, map_fd, argv[i]);
|
|
if (err)
|
|
ret = err;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|