Skip to content

Commit

Permalink
bpftool: Match programs by name
Browse files Browse the repository at this point in the history
When working with frequently modified BPF programs, both the ID and the
tag may change.  bpftool currently doesn't provide a "stable" way to match
such programs.

This patch implements lookup by name for programs.  The show and dump
commands will return all programs with the given name, whereas other
commands will error out if several programs have the same name.

Signed-off-by: Paul Chaignon <paul.chaignon@orange.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Link: https://lore.kernel.org/bpf/b5fc1a5dcfaeb5f16fc80295cdaa606dd2d91534.1576263640.git.paul.chaignon@gmail.com
  • Loading branch information
Paul Chaignon authored and Alexei Starovoitov committed Dec 15, 2019
1 parent ec20250 commit a7d22ca
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 18 deletions.
2 changes: 1 addition & 1 deletion tools/bpf/bpftool/Documentation/bpftool-map.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ MAP COMMANDS
|
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
| *DATA* := { [**hex**] *BYTES* }
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
| *VALUE* := { *DATA* | *MAP* | *PROG* }
| *UPDATE_FLAGS* := { **any** | **exist** | **noexist** }
| *TYPE* := { **hash** | **array** | **prog_array** | **perf_event_array** | **percpu_hash**
Expand Down
12 changes: 6 additions & 6 deletions tools/bpf/bpftool/Documentation/bpftool-prog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ PROG COMMANDS
| **bpftool** **prog help**
|
| *MAP* := { **id** *MAP_ID* | **pinned** *FILE* }
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
| *PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* | **name** *PROG_NAME* }
| *TYPE* := {
| **socket** | **kprobe** | **kretprobe** | **classifier** | **action** |
| **tracepoint** | **raw_tracepoint** | **xdp** | **perf_event** | **cgroup/skb** |
Expand All @@ -55,8 +55,8 @@ DESCRIPTION
Show information about loaded programs. If *PROG* is
specified show information only about given programs,
otherwise list all programs currently loaded on the system.
In case of **tag**, *PROG* may match several programs which
will all be shown.
In case of **tag** or **name**, *PROG* may match several
programs which will all be shown.

Output will start with program ID followed by program type and
zero or more named attributes (depending on kernel version).
Expand All @@ -75,9 +75,9 @@ DESCRIPTION
output in human-readable format. In this case, **opcodes**
controls if raw opcodes should be printed as well.

In case of **tag**, *PROG* may match several programs which
will all be dumped. However, if **file** or **visual** is
specified, *PROG* must match a single program.
In case of **tag** or **name**, *PROG* may match several
programs which will all be dumped. However, if **file** or
**visual** is specified, *PROG* must match a single program.

If **file** is specified, the binary image will instead be
written to *FILE*.
Expand Down
22 changes: 16 additions & 6 deletions tools/bpf/bpftool/bash-completion/bpftool
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ _bpftool_get_prog_tags()
command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
}

_bpftool_get_prog_names()
{
COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
command sed -n 's/.*"name": "\(.*\)",$/\1/p' )" -- "$cur" ) )
}

_bpftool_get_btf_ids()
{
COMPREPLY+=( $( compgen -W "$( bpftool -jp btf 2>&1 | \
Expand Down Expand Up @@ -201,6 +207,10 @@ _bpftool()
_bpftool_get_prog_tags
return 0
;;
name)
_bpftool_get_prog_names
return 0
;;
dev)
_sysfs_get_netdevs
return 0
Expand Down Expand Up @@ -263,7 +273,7 @@ _bpftool()
;;
esac

local PROG_TYPE='id pinned tag'
local PROG_TYPE='id pinned tag name'
local MAP_TYPE='id pinned'
case $command in
show|list)
Expand Down Expand Up @@ -559,7 +569,7 @@ _bpftool()
return 0
;;
prog_array)
local PROG_TYPE='id pinned tag'
local PROG_TYPE='id pinned tag name'
COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
-- "$cur" ) )
return 0
Expand Down Expand Up @@ -644,7 +654,7 @@ _bpftool()
esac
;;
btf)
local PROG_TYPE='id pinned tag'
local PROG_TYPE='id pinned tag name'
local MAP_TYPE='id pinned'
case $command in
dump)
Expand Down Expand Up @@ -735,7 +745,7 @@ _bpftool()
connect6 sendmsg4 sendmsg6 recvmsg4 recvmsg6 sysctl \
getsockopt setsockopt'
local ATTACH_FLAGS='multi override'
local PROG_TYPE='id pinned tag'
local PROG_TYPE='id pinned tag name'
case $prev in
$command)
_filedir
Expand All @@ -760,7 +770,7 @@ _bpftool()
elif [[ "$command" == "attach" ]]; then
# We have an attach type on the command line,
# but it is not the previous word, or
# "id|pinned|tag" (we already checked for
# "id|pinned|tag|name" (we already checked for
# that). This should only leave the case when
# we need attach flags for "attach" commamnd.
_bpftool_one_of_list "$ATTACH_FLAGS"
Expand All @@ -786,7 +796,7 @@ _bpftool()
esac
;;
net)
local PROG_TYPE='id pinned tag'
local PROG_TYPE='id pinned tag name'
local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload'
case $command in
show|list)
Expand Down
2 changes: 1 addition & 1 deletion tools/bpf/bpftool/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
#define BPF_TAG_FMT "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"

#define HELP_SPEC_PROGRAM \
"PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }"
"PROG := { id PROG_ID | pinned FILE | tag PROG_TAG | name PROG_NAME }"
#define HELP_SPEC_OPTIONS \
"OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n" \
"\t {-m|--mapcompat} | {-n|--nomount} }"
Expand Down
22 changes: 18 additions & 4 deletions tools/bpf/bpftool/prog.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)
strftime(buf, size, "%FT%T%z", &load_tm);
}

static int prog_fd_by_tag(unsigned char *tag, int **fds)
static int prog_fd_by_nametag(void *nametag, int **fds, bool tag)
{
unsigned int id = 0;
int fd, nb_fds = 0;
Expand Down Expand Up @@ -116,7 +116,8 @@ static int prog_fd_by_tag(unsigned char *tag, int **fds)
goto err_close_fd;
}

if (memcmp(tag, info.tag, BPF_TAG_SIZE)) {
if ((tag && memcmp(nametag, info.tag, BPF_TAG_SIZE)) ||
(!tag && strncmp(nametag, info.name, BPF_OBJ_NAME_LEN))) {
close(fd);
continue;
}
Expand Down Expand Up @@ -174,7 +175,20 @@ static int prog_parse_fds(int *argc, char ***argv, int **fds)
}
NEXT_ARGP();

return prog_fd_by_tag(tag, fds);
return prog_fd_by_nametag(tag, fds, true);
} else if (is_prefix(**argv, "name")) {
char *name;

NEXT_ARGP();

name = **argv;
if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
p_err("can't parse name");
return -1;
}
NEXT_ARGP();

return prog_fd_by_nametag(name, fds, false);
} else if (is_prefix(**argv, "pinned")) {
char *path;

Expand All @@ -189,7 +203,7 @@ static int prog_parse_fds(int *argc, char ***argv, int **fds)
return 1;
}

p_err("expected 'id', 'tag' or 'pinned', got: '%s'?", **argv);
p_err("expected 'id', 'tag', 'name' or 'pinned', got: '%s'?", **argv);
return -1;
}

Expand Down

0 comments on commit a7d22ca

Please sign in to comment.