Commit f2cbf958 authored by Alexei Starovoitov's avatar Alexei Starovoitov

Merge branch 'bpftool-flow-dissector'

Stanislav Fomichev says:

====================
v5 changes:
* FILE -> PATH for load/loadall (can be either file or directory now)
* simpler implementation for __bpf_program__pin_name
* removed p_err for REQ_ARGS checks
* parse_atach_detach_args -> parse_attach_detach_args
* for -> while in bpf_object__pin_{programs,maps} recovery

v4 changes:
* addressed another round of comments/style issues from Jakub Kicinski &
  Quentin Monnet (thanks!)
* implemented bpf_object__pin_maps and bpf_object__pin_programs helpers and
  used them in bpf_program__pin
* added new pin_name to bpf_program so bpf_program__pin
  works with sections that contain '/'
* moved *loadall* command implementation into a separate patch
* added patch that implements *pinmaps* to pin maps when doing
  load/loadall

v3 changes:
* (maybe) better cleanup for partial failure in bpf_object__pin
* added special case in bpf_program__pin for programs with single
  instances

v2 changes:
* addressed comments/style issues from Jakub Kicinski & Quentin Monnet
* removed logic that populates jump table
* added cleanup for partial failure in bpf_object__pin

This patch series adds support for loading and attaching flow dissector
programs from the bpftool:

* first patch fixes flow dissector section name in the selftests (so
  libbpf auto-detection works)
* second patch adds proper cleanup to bpf_object__pin, parts of which are now
  being used to attach all flow dissector progs/maps
* third patch adds special case in bpf_program__pin for programs with
  single instances (we don't create <prog>/0 pin anymore, just <prog>)
* forth patch adds pin_name to the bpf_program struct
  which is now used as a pin name in bpf_program__pin et al
* fifth patch adds *loadall* command that pins all programs, not just
  the first one
* sixth patch adds *pinmaps* argument to load/loadall to let users pin
  all maps of the obj file
* seventh patch adds actual flow_dissector support to the bpftool and
  an example
====================
Acked-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents 0157edc8 092f0892
...@@ -15,7 +15,8 @@ SYNOPSIS ...@@ -15,7 +15,8 @@ SYNOPSIS
*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } } *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
*COMMANDS* := *COMMANDS* :=
{ **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** | **help** } { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load**
| **loadall** | **help** }
MAP COMMANDS MAP COMMANDS
============= =============
...@@ -24,9 +25,9 @@ MAP COMMANDS ...@@ -24,9 +25,9 @@ MAP COMMANDS
| **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}] | **bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes** | **visual**}]
| **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}] | **bpftool** **prog dump jited** *PROG* [{**file** *FILE* | **opcodes**}]
| **bpftool** **prog pin** *PROG* *FILE* | **bpftool** **prog pin** *PROG* *FILE*
| **bpftool** **prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] | **bpftool** **prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*]
| **bpftool** **prog attach** *PROG* *ATTACH_TYPE* *MAP* | **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
| **bpftool** **prog detach** *PROG* *ATTACH_TYPE* *MAP* | **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
| **bpftool** **prog help** | **bpftool** **prog help**
| |
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* } | *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
...@@ -39,7 +40,9 @@ MAP COMMANDS ...@@ -39,7 +40,9 @@ MAP COMMANDS
| **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** | | **cgroup/bind4** | **cgroup/bind6** | **cgroup/post_bind4** | **cgroup/post_bind6** |
| **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6** | **cgroup/connect4** | **cgroup/connect6** | **cgroup/sendmsg4** | **cgroup/sendmsg6**
| } | }
| *ATTACH_TYPE* := { **msg_verdict** | **skb_verdict** | **skb_parse** } | *ATTACH_TYPE* := {
| **msg_verdict** | **skb_verdict** | **skb_parse** | **flow_dissector**
| }
DESCRIPTION DESCRIPTION
...@@ -79,8 +82,11 @@ DESCRIPTION ...@@ -79,8 +82,11 @@ DESCRIPTION
contain a dot character ('.'), which is reserved for future contain a dot character ('.'), which is reserved for future
extensions of *bpffs*. extensions of *bpffs*.
**bpftool prog load** *OBJ* *FILE* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] **bpftool prog { load | loadall }** *OBJ* *PATH* [**type** *TYPE*] [**map** {**idx** *IDX* | **name** *NAME*} *MAP*] [**dev** *NAME*] [**pinmaps** *MAP_DIR*]
Load bpf program from binary *OBJ* and pin as *FILE*. Load bpf program(s) from binary *OBJ* and pin as *PATH*.
**bpftool prog load** pins only the first program from the
*OBJ* as *PATH*. **bpftool prog loadall** pins all programs
from the *OBJ* under *PATH* directory.
**type** is optional, if not specified program type will be **type** is optional, if not specified program type will be
inferred from section names. inferred from section names.
By default bpftool will create new maps as declared in the ELF By default bpftool will create new maps as declared in the ELF
...@@ -92,18 +98,24 @@ DESCRIPTION ...@@ -92,18 +98,24 @@ DESCRIPTION
use, referring to it by **id** or through a **pinned** file. use, referring to it by **id** or through a **pinned** file.
If **dev** *NAME* is specified program will be loaded onto If **dev** *NAME* is specified program will be loaded onto
given networking device (offload). given networking device (offload).
Optional **pinmaps** argument can be provided to pin all
maps under *MAP_DIR* directory.
Note: *FILE* must be located in *bpffs* mount. It must not Note: *PATH* must be located in *bpffs* mount. It must not
contain a dot character ('.'), which is reserved for future contain a dot character ('.'), which is reserved for future
extensions of *bpffs*. extensions of *bpffs*.
**bpftool prog attach** *PROG* *ATTACH_TYPE* *MAP* **bpftool prog attach** *PROG* *ATTACH_TYPE* [*MAP*]
Attach bpf program *PROG* (with type specified by *ATTACH_TYPE*) Attach bpf program *PROG* (with type specified by
to the map *MAP*. *ATTACH_TYPE*). Most *ATTACH_TYPEs* require a *MAP*
parameter, with the exception of *flow_dissector* which is
**bpftool prog detach** *PROG* *ATTACH_TYPE* *MAP* attached to current networking name space.
Detach bpf program *PROG* (with type specified by *ATTACH_TYPE*)
from the map *MAP*. **bpftool prog detach** *PROG* *ATTACH_TYPE* [*MAP*]
Detach bpf program *PROG* (with type specified by
*ATTACH_TYPE*). Most *ATTACH_TYPEs* require a *MAP*
parameter, with the exception of *flow_dissector* which is
detached from the current networking name space.
**bpftool prog help** **bpftool prog help**
Print short help message. Print short help message.
......
...@@ -243,7 +243,7 @@ _bpftool() ...@@ -243,7 +243,7 @@ _bpftool()
# Completion depends on object and command in use # Completion depends on object and command in use
case $object in case $object in
prog) prog)
if [[ $command != "load" ]]; then if [[ $command != "load" && $command != "loadall" ]]; then
case $prev in case $prev in
id) id)
_bpftool_get_prog_ids _bpftool_get_prog_ids
...@@ -299,7 +299,8 @@ _bpftool() ...@@ -299,7 +299,8 @@ _bpftool()
fi fi
if [[ ${#words[@]} == 6 ]]; then if [[ ${#words[@]} == 6 ]]; then
COMPREPLY=( $( compgen -W "msg_verdict skb_verdict skb_parse" -- "$cur" ) ) COMPREPLY=( $( compgen -W "msg_verdict skb_verdict \
skb_parse flow_dissector" -- "$cur" ) )
return 0 return 0
fi fi
...@@ -309,7 +310,7 @@ _bpftool() ...@@ -309,7 +310,7 @@ _bpftool()
fi fi
return 0 return 0
;; ;;
load) load|loadall)
local obj local obj
if [[ ${#words[@]} -lt 6 ]]; then if [[ ${#words[@]} -lt 6 ]]; then
...@@ -338,7 +339,16 @@ _bpftool() ...@@ -338,7 +339,16 @@ _bpftool()
case $prev in case $prev in
type) type)
COMPREPLY=( $( compgen -W "socket kprobe kretprobe classifier action tracepoint raw_tracepoint xdp perf_event cgroup/skb cgroup/sock cgroup/dev lwt_in lwt_out lwt_xmit lwt_seg6local sockops sk_skb sk_msg lirc_mode2 cgroup/bind4 cgroup/bind6 cgroup/connect4 cgroup/connect6 cgroup/sendmsg4 cgroup/sendmsg6 cgroup/post_bind4 cgroup/post_bind6" -- \ COMPREPLY=( $( compgen -W "socket kprobe \
kretprobe classifier flow_dissector \
action tracepoint raw_tracepoint \
xdp perf_event cgroup/skb cgroup/sock \
cgroup/dev lwt_in lwt_out lwt_xmit \
lwt_seg6local sockops sk_skb sk_msg \
lirc_mode2 cgroup/bind4 cgroup/bind6 \
cgroup/connect4 cgroup/connect6 \
cgroup/sendmsg4 cgroup/sendmsg6 \
cgroup/post_bind4 cgroup/post_bind6" -- \
"$cur" ) ) "$cur" ) )
return 0 return 0
;; ;;
...@@ -346,7 +356,7 @@ _bpftool() ...@@ -346,7 +356,7 @@ _bpftool()
_bpftool_get_map_ids _bpftool_get_map_ids
return 0 return 0
;; ;;
pinned) pinned|pinmaps)
_filedir _filedir
return 0 return 0
;; ;;
...@@ -358,6 +368,7 @@ _bpftool() ...@@ -358,6 +368,7 @@ _bpftool()
COMPREPLY=( $( compgen -W "map" -- "$cur" ) ) COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
_bpftool_once_attr 'type' _bpftool_once_attr 'type'
_bpftool_once_attr 'dev' _bpftool_once_attr 'dev'
_bpftool_once_attr 'pinmaps'
return 0 return 0
;; ;;
esac esac
......
...@@ -177,34 +177,23 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type) ...@@ -177,34 +177,23 @@ int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type)
return fd; return fd;
} }
int do_pin_fd(int fd, const char *name) int mount_bpffs_for_pin(const char *name)
{ {
char err_str[ERR_MAX_LEN]; char err_str[ERR_MAX_LEN];
char *file; char *file;
char *dir; char *dir;
int err = 0; int err = 0;
err = bpf_obj_pin(fd, name);
if (!err)
goto out;
file = malloc(strlen(name) + 1); file = malloc(strlen(name) + 1);
strcpy(file, name); strcpy(file, name);
dir = dirname(file); dir = dirname(file);
if (errno != EPERM || is_bpffs(dir)) { if (is_bpffs(dir))
p_err("can't pin the object (%s): %s", name, strerror(errno)); /* nothing to do if already mounted */
goto out_free; goto out_free;
}
/* Attempt to mount bpffs, then retry pinning. */
err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
if (!err) { if (err) {
err = bpf_obj_pin(fd, name);
if (err)
p_err("can't pin the object (%s): %s", name,
strerror(errno));
} else {
err_str[ERR_MAX_LEN - 1] = '\0'; err_str[ERR_MAX_LEN - 1] = '\0';
p_err("can't mount BPF file system to pin the object (%s): %s", p_err("can't mount BPF file system to pin the object (%s): %s",
name, err_str); name, err_str);
...@@ -212,10 +201,20 @@ int do_pin_fd(int fd, const char *name) ...@@ -212,10 +201,20 @@ int do_pin_fd(int fd, const char *name)
out_free: out_free:
free(file); free(file);
out:
return err; return err;
} }
int do_pin_fd(int fd, const char *name)
{
int err;
err = mount_bpffs_for_pin(name);
if (err)
return err;
return bpf_obj_pin(fd, name);
}
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)) int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
{ {
unsigned int id; unsigned int id;
......
...@@ -131,6 +131,7 @@ const char *get_fd_type_name(enum bpf_obj_type type); ...@@ -131,6 +131,7 @@ const char *get_fd_type_name(enum bpf_obj_type type);
char *get_fdinfo(int fd, const char *key); char *get_fdinfo(int fd, const char *key);
int open_obj_pinned(char *path); int open_obj_pinned(char *path);
int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type); int open_obj_pinned_any(char *path, enum bpf_obj_type exp_type);
int mount_bpffs_for_pin(const char *name);
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32)); int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32));
int do_pin_fd(int fd, const char *name); int do_pin_fd(int fd, const char *name);
......
...@@ -81,6 +81,7 @@ static const char * const attach_type_strings[] = { ...@@ -81,6 +81,7 @@ static const char * const attach_type_strings[] = {
[BPF_SK_SKB_STREAM_PARSER] = "stream_parser", [BPF_SK_SKB_STREAM_PARSER] = "stream_parser",
[BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict", [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict",
[BPF_SK_MSG_VERDICT] = "msg_verdict", [BPF_SK_MSG_VERDICT] = "msg_verdict",
[BPF_FLOW_DISSECTOR] = "flow_dissector",
[__MAX_BPF_ATTACH_TYPE] = NULL, [__MAX_BPF_ATTACH_TYPE] = NULL,
}; };
...@@ -721,30 +722,49 @@ int map_replace_compar(const void *p1, const void *p2) ...@@ -721,30 +722,49 @@ int map_replace_compar(const void *p1, const void *p2)
return a->idx - b->idx; return a->idx - b->idx;
} }
static int do_attach(int argc, char **argv) static int parse_attach_detach_args(int argc, char **argv, int *progfd,
enum bpf_attach_type *attach_type,
int *mapfd)
{ {
enum bpf_attach_type attach_type; if (!REQ_ARGS(3))
int err, mapfd, progfd;
if (!REQ_ARGS(5)) {
p_err("too few parameters for map attach");
return -EINVAL; return -EINVAL;
}
progfd = prog_parse_fd(&argc, &argv); *progfd = prog_parse_fd(&argc, &argv);
if (progfd < 0) if (*progfd < 0)
return progfd; return *progfd;
attach_type = parse_attach_type(*argv); *attach_type = parse_attach_type(*argv);
if (attach_type == __MAX_BPF_ATTACH_TYPE) { if (*attach_type == __MAX_BPF_ATTACH_TYPE) {
p_err("invalid attach type"); p_err("invalid attach/detach type");
return -EINVAL; return -EINVAL;
} }
if (*attach_type == BPF_FLOW_DISSECTOR) {
*mapfd = -1;
return 0;
}
NEXT_ARG(); NEXT_ARG();
if (!REQ_ARGS(2))
return -EINVAL;
*mapfd = map_parse_fd(&argc, &argv);
if (*mapfd < 0)
return *mapfd;
return 0;
}
mapfd = map_parse_fd(&argc, &argv); static int do_attach(int argc, char **argv)
if (mapfd < 0) {
return mapfd; enum bpf_attach_type attach_type;
int err, progfd;
int mapfd;
err = parse_attach_detach_args(argc, argv,
&progfd, &attach_type, &mapfd);
if (err)
return err;
err = bpf_prog_attach(progfd, mapfd, attach_type, 0); err = bpf_prog_attach(progfd, mapfd, attach_type, 0);
if (err) { if (err) {
...@@ -760,27 +780,13 @@ static int do_attach(int argc, char **argv) ...@@ -760,27 +780,13 @@ static int do_attach(int argc, char **argv)
static int do_detach(int argc, char **argv) static int do_detach(int argc, char **argv)
{ {
enum bpf_attach_type attach_type; enum bpf_attach_type attach_type;
int err, mapfd, progfd; int err, progfd;
int mapfd;
if (!REQ_ARGS(5)) {
p_err("too few parameters for map detach");
return -EINVAL;
}
progfd = prog_parse_fd(&argc, &argv);
if (progfd < 0)
return progfd;
attach_type = parse_attach_type(*argv);
if (attach_type == __MAX_BPF_ATTACH_TYPE) {
p_err("invalid attach type");
return -EINVAL;
}
NEXT_ARG();
mapfd = map_parse_fd(&argc, &argv); err = parse_attach_detach_args(argc, argv,
if (mapfd < 0) &progfd, &attach_type, &mapfd);
return mapfd; if (err)
return err;
err = bpf_prog_detach2(progfd, mapfd, attach_type); err = bpf_prog_detach2(progfd, mapfd, attach_type);
if (err) { if (err) {
...@@ -792,15 +798,17 @@ static int do_detach(int argc, char **argv) ...@@ -792,15 +798,17 @@ static int do_detach(int argc, char **argv)
jsonw_null(json_wtr); jsonw_null(json_wtr);
return 0; return 0;
} }
static int do_load(int argc, char **argv)
static int load_with_options(int argc, char **argv, bool first_prog_only)
{ {
enum bpf_attach_type expected_attach_type; enum bpf_attach_type expected_attach_type;
struct bpf_object_open_attr attr = { struct bpf_object_open_attr attr = {
.prog_type = BPF_PROG_TYPE_UNSPEC, .prog_type = BPF_PROG_TYPE_UNSPEC,
}; };
struct map_replace *map_replace = NULL; struct map_replace *map_replace = NULL;
struct bpf_program *prog = NULL, *pos;
unsigned int old_map_fds = 0; unsigned int old_map_fds = 0;
struct bpf_program *prog; const char *pinmaps = NULL;
struct bpf_object *obj; struct bpf_object *obj;
struct bpf_map *map; struct bpf_map *map;
const char *pinfile; const char *pinfile;
...@@ -905,6 +913,13 @@ static int do_load(int argc, char **argv) ...@@ -905,6 +913,13 @@ static int do_load(int argc, char **argv)
goto err_free_reuse_maps; goto err_free_reuse_maps;
} }
NEXT_ARG(); NEXT_ARG();
} else if (is_prefix(*argv, "pinmaps")) {
NEXT_ARG();
if (!REQ_ARGS(1))
goto err_free_reuse_maps;
pinmaps = GET_ARG();
} else { } else {
p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?", p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?",
*argv); *argv);
...@@ -918,26 +933,25 @@ static int do_load(int argc, char **argv) ...@@ -918,26 +933,25 @@ static int do_load(int argc, char **argv)
goto err_free_reuse_maps; goto err_free_reuse_maps;
} }
prog = bpf_program__next(NULL, obj); bpf_object__for_each_program(pos, obj) {
if (!prog) { enum bpf_prog_type prog_type = attr.prog_type;
p_err("object file doesn't contain any bpf program");
goto err_close_obj;
}
bpf_program__set_ifindex(prog, ifindex); if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) {
if (attr.prog_type == BPF_PROG_TYPE_UNSPEC) { const char *sec_name = bpf_program__title(pos, false);
const char *sec_name = bpf_program__title(prog, false);
err = libbpf_prog_type_by_name(sec_name, &attr.prog_type, err = libbpf_prog_type_by_name(sec_name, &prog_type,
&expected_attach_type); &expected_attach_type);
if (err < 0) { if (err < 0) {
p_err("failed to guess program type based on section name %s\n", p_err("failed to guess program type based on section name %s\n",
sec_name); sec_name);
goto err_close_obj; goto err_close_obj;
}
} }
bpf_program__set_ifindex(pos, ifindex);
bpf_program__set_type(pos, prog_type);
bpf_program__set_expected_attach_type(pos, expected_attach_type);
} }
bpf_program__set_type(prog, attr.prog_type);
bpf_program__set_expected_attach_type(prog, expected_attach_type);
qsort(map_replace, old_map_fds, sizeof(*map_replace), qsort(map_replace, old_map_fds, sizeof(*map_replace),
map_replace_compar); map_replace_compar);
...@@ -1003,9 +1017,39 @@ static int do_load(int argc, char **argv) ...@@ -1003,9 +1017,39 @@ static int do_load(int argc, char **argv)
goto err_close_obj; goto err_close_obj;
} }
if (do_pin_fd(bpf_program__fd(prog), pinfile)) err = mount_bpffs_for_pin(pinfile);
if (err)
goto err_close_obj; goto err_close_obj;
if (first_prog_only) {
prog = bpf_program__next(NULL, obj);
if (!prog) {
p_err("object file doesn't contain any bpf program");
goto err_close_obj;
}
err = bpf_obj_pin(bpf_program__fd(prog), pinfile);
if (err) {
p_err("failed to pin program %s",
bpf_program__title(prog, false));
goto err_close_obj;
}
} else {
err = bpf_object__pin_programs(obj, pinfile);
if (err) {
p_err("failed to pin all programs");
goto err_close_obj;
}
}
if (pinmaps) {
err = bpf_object__pin_maps(obj, pinmaps);
if (err) {
p_err("failed to pin all maps");
goto err_unpin;
}
}
if (json_output) if (json_output)
jsonw_null(json_wtr); jsonw_null(json_wtr);
...@@ -1016,6 +1060,11 @@ static int do_load(int argc, char **argv) ...@@ -1016,6 +1060,11 @@ static int do_load(int argc, char **argv)
return 0; return 0;
err_unpin:
if (first_prog_only)
unlink(pinfile);
else
bpf_object__unpin_programs(obj, pinfile);
err_close_obj: err_close_obj:
bpf_object__close(obj); bpf_object__close(obj);
err_free_reuse_maps: err_free_reuse_maps:
...@@ -1025,6 +1074,16 @@ static int do_load(int argc, char **argv) ...@@ -1025,6 +1074,16 @@ static int do_load(int argc, char **argv)
return -1; return -1;
} }
static int do_load(int argc, char **argv)
{
return load_with_options(argc, argv, true);
}
static int do_loadall(int argc, char **argv)
{
return load_with_options(argc, argv, false);
}
static int do_help(int argc, char **argv) static int do_help(int argc, char **argv)
{ {
if (json_output) { if (json_output) {
...@@ -1037,10 +1096,12 @@ static int do_help(int argc, char **argv) ...@@ -1037,10 +1096,12 @@ static int do_help(int argc, char **argv)
" %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n" " %s %s dump xlated PROG [{ file FILE | opcodes | visual }]\n"
" %s %s dump jited PROG [{ file FILE | opcodes }]\n" " %s %s dump jited PROG [{ file FILE | opcodes }]\n"
" %s %s pin PROG FILE\n" " %s %s pin PROG FILE\n"
" %s %s load OBJ FILE [type TYPE] [dev NAME] \\\n" " %s %s { load | loadall } OBJ PATH \\\n"
" [map { idx IDX | name NAME } MAP]\n" " [type TYPE] [dev NAME] \\\n"
" %s %s attach PROG ATTACH_TYPE MAP\n" " [map { idx IDX | name NAME } MAP]\\\n"
" %s %s detach PROG ATTACH_TYPE MAP\n" " [pinmaps MAP_DIR]\n"
" %s %s attach PROG ATTACH_TYPE [MAP]\n"
" %s %s detach PROG ATTACH_TYPE [MAP]\n"
" %s %s help\n" " %s %s help\n"
"\n" "\n"
" " HELP_SPEC_MAP "\n" " " HELP_SPEC_MAP "\n"
...@@ -1052,7 +1113,8 @@ static int do_help(int argc, char **argv) ...@@ -1052,7 +1113,8 @@ static int do_help(int argc, char **argv)
" cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n" " cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
" cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n" " cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
" cgroup/sendmsg4 | cgroup/sendmsg6 }\n" " cgroup/sendmsg4 | cgroup/sendmsg6 }\n"
" ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse }\n" " ATTACH_TYPE := { msg_verdict | skb_verdict | skb_parse |\n"
" flow_dissector }\n"
" " HELP_SPEC_OPTIONS "\n" " " HELP_SPEC_OPTIONS "\n"
"", "",
bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
...@@ -1069,6 +1131,7 @@ static const struct cmd cmds[] = { ...@@ -1069,6 +1131,7 @@ static const struct cmd cmds[] = {
{ "dump", do_dump }, { "dump", do_dump },
{ "pin", do_pin }, { "pin", do_pin },
{ "load", do_load }, { "load", do_load },
{ "loadall", do_loadall },
{ "attach", do_attach }, { "attach", do_attach },
{ "detach", do_detach }, { "detach", do_detach },
{ 0 } { 0 }
......
This diff is collapsed.
...@@ -71,6 +71,13 @@ struct bpf_object *__bpf_object__open_xattr(struct bpf_object_open_attr *attr, ...@@ -71,6 +71,13 @@ struct bpf_object *__bpf_object__open_xattr(struct bpf_object_open_attr *attr,
LIBBPF_API struct bpf_object *bpf_object__open_buffer(void *obj_buf, LIBBPF_API struct bpf_object *bpf_object__open_buffer(void *obj_buf,
size_t obj_buf_sz, size_t obj_buf_sz,
const char *name); const char *name);
LIBBPF_API int bpf_object__pin_maps(struct bpf_object *obj, const char *path);
LIBBPF_API int bpf_object__unpin_maps(struct bpf_object *obj,
const char *path);
LIBBPF_API int bpf_object__pin_programs(struct bpf_object *obj,
const char *path);
LIBBPF_API int bpf_object__unpin_programs(struct bpf_object *obj,
const char *path);
LIBBPF_API int bpf_object__pin(struct bpf_object *object, const char *path); LIBBPF_API int bpf_object__pin(struct bpf_object *object, const char *path);
LIBBPF_API void bpf_object__close(struct bpf_object *object); LIBBPF_API void bpf_object__close(struct bpf_object *object);
...@@ -112,6 +119,9 @@ LIBBPF_API struct bpf_program *bpf_program__next(struct bpf_program *prog, ...@@ -112,6 +119,9 @@ LIBBPF_API struct bpf_program *bpf_program__next(struct bpf_program *prog,
(pos) != NULL; \ (pos) != NULL; \
(pos) = bpf_program__next((pos), (obj))) (pos) = bpf_program__next((pos), (obj)))
LIBBPF_API struct bpf_program *bpf_program__prev(struct bpf_program *prog,
struct bpf_object *obj);
typedef void (*bpf_program_clear_priv_t)(struct bpf_program *, typedef void (*bpf_program_clear_priv_t)(struct bpf_program *,
void *); void *);
...@@ -131,7 +141,11 @@ LIBBPF_API int bpf_program__fd(struct bpf_program *prog); ...@@ -131,7 +141,11 @@ LIBBPF_API int bpf_program__fd(struct bpf_program *prog);
LIBBPF_API int bpf_program__pin_instance(struct bpf_program *prog, LIBBPF_API int bpf_program__pin_instance(struct bpf_program *prog,
const char *path, const char *path,
int instance); int instance);
LIBBPF_API int bpf_program__unpin_instance(struct bpf_program *prog,
const char *path,
int instance);
LIBBPF_API int bpf_program__pin(struct bpf_program *prog, const char *path); LIBBPF_API int bpf_program__pin(struct bpf_program *prog, const char *path);
LIBBPF_API int bpf_program__unpin(struct bpf_program *prog, const char *path);
LIBBPF_API void bpf_program__unload(struct bpf_program *prog); LIBBPF_API void bpf_program__unload(struct bpf_program *prog);
struct bpf_insn; struct bpf_insn;
...@@ -260,6 +274,9 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj); ...@@ -260,6 +274,9 @@ bpf_map__next(struct bpf_map *map, struct bpf_object *obj);
(pos) != NULL; \ (pos) != NULL; \
(pos) = bpf_map__next((pos), (obj))) (pos) = bpf_map__next((pos), (obj)))
LIBBPF_API struct bpf_map *
bpf_map__prev(struct bpf_map *map, struct bpf_object *obj);
LIBBPF_API int bpf_map__fd(struct bpf_map *map); LIBBPF_API int bpf_map__fd(struct bpf_map *map);
LIBBPF_API const struct bpf_map_def *bpf_map__def(struct bpf_map *map); LIBBPF_API const struct bpf_map_def *bpf_map__def(struct bpf_map *map);
LIBBPF_API const char *bpf_map__name(struct bpf_map *map); LIBBPF_API const char *bpf_map__name(struct bpf_map *map);
...@@ -274,6 +291,7 @@ LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd); ...@@ -274,6 +291,7 @@ LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd);
LIBBPF_API bool bpf_map__is_offload_neutral(struct bpf_map *map); LIBBPF_API bool bpf_map__is_offload_neutral(struct bpf_map *map);
LIBBPF_API void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex); LIBBPF_API void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
LIBBPF_API int bpf_map__pin(struct bpf_map *map, const char *path); LIBBPF_API int bpf_map__pin(struct bpf_map *map, const char *path);
LIBBPF_API int bpf_map__unpin(struct bpf_map *map, const char *path);
LIBBPF_API long libbpf_get_error(const void *ptr); LIBBPF_API long libbpf_get_error(const void *ptr);
......
...@@ -116,7 +116,7 @@ static __always_inline int parse_eth_proto(struct __sk_buff *skb, __be16 proto) ...@@ -116,7 +116,7 @@ static __always_inline int parse_eth_proto(struct __sk_buff *skb, __be16 proto)
return BPF_DROP; return BPF_DROP;
} }
SEC("dissect") SEC("flow_dissector")
int _dissect(struct __sk_buff *skb) int _dissect(struct __sk_buff *skb)
{ {
if (!skb->vlan_present) if (!skb->vlan_present)
......
...@@ -59,7 +59,7 @@ else ...@@ -59,7 +59,7 @@ else
fi fi
# Attach BPF program # Attach BPF program
./flow_dissector_load -p bpf_flow.o -s dissect ./flow_dissector_load -p bpf_flow.o -s flow_dissector
# Setup # Setup
tc qdisc add dev lo ingress tc qdisc add dev lo ingress
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment