Commit 0b9e3d54 authored by Daniel Borkmann's avatar Daniel Borkmann

Merge branch 'bpf-bpftool-libbpf-improvements'

Jakub Kicinski says:

====================
Set of random updates to bpftool and libbpf.  I'm preparing for
extending bpftool prog load, but there is a good number of
improvements that can be made before bpf -> bpf-next merge
helping to keep the later patch set to a manageable size as well.

First patch is a bpftool build speed improvement.  Next missing
program types are added to libbpf program type detection by section
name.  The ability to load programs from '.text' section is restored
when ELF file doesn't contain any pseudo calls.

In bpftool I remove my Author comments as unnecessary sign of vanity.
Last but not least missing option is added to bash completions and
processing of options in bash completions is improved.
====================
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parents 509fda10 121c58be
......@@ -23,7 +23,7 @@ endif
LIBBPF = $(BPF_PATH)libbpf.a
BPFTOOL_VERSION=$(shell make --no-print-directory -sC ../../.. kernelversion)
BPFTOOL_VERSION := $(shell make --no-print-directory -sC ../../.. kernelversion)
$(LIBBPF): FORCE
$(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(OUTPUT) $(OUTPUT)libbpf.a FEATURES_DUMP=$(FEATURE_DUMP_EXPORT)
......
......@@ -153,6 +153,13 @@ _bpftool()
local cur prev words objword
_init_completion || return
# Deal with options
if [[ ${words[cword]} == -* ]]; then
local c='--version --json --pretty --bpffs'
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
return 0
fi
# Deal with simplest keywords
case $prev in
help|hex|opcodes|visual)
......@@ -172,20 +179,23 @@ _bpftool()
;;
esac
# Search for object and command
local object command cmdword
for (( cmdword=1; cmdword < ${#words[@]}-1; cmdword++ )); do
[[ -n $object ]] && command=${words[cmdword]} && break
[[ ${words[cmdword]} != -* ]] && object=${words[cmdword]}
# Remove all options so completions don't have to deal with them.
local i
for (( i=1; i < ${#words[@]}; )); do
if [[ ${words[i]::1} == - ]]; then
words=( "${words[@]:0:i}" "${words[@]:i+1}" )
[[ $i -le $cword ]] && cword=$(( cword - 1 ))
else
i=$(( ++i ))
fi
done
cur=${words[cword]}
prev=${words[cword - 1]}
if [[ -z $object ]]; then
local object=${words[1]} command=${words[2]}
if [[ -z $object || $cword -eq 1 ]]; then
case $cur in
-*)
local c='--version --json --pretty'
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
return 0
;;
*)
COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
command sed \
......
......@@ -31,8 +31,6 @@
* SOFTWARE.
*/
/* Author: Jakub Kicinski <kubakici@wp.pl> */
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
......
/*
* Copyright (C) 2017 Netronome Systems, Inc.
* Copyright (C) 2017-2018 Netronome Systems, Inc.
*
* This software is dual licensed under the GNU General License Version 2,
* June 1991 as shown in the file COPYING in the top-level directory of this
......@@ -31,8 +31,6 @@
* SOFTWARE.
*/
/* Author: Jakub Kicinski <kubakici@wp.pl> */
#include <bfd.h>
#include <ctype.h>
#include <errno.h>
......
......@@ -31,8 +31,6 @@
* SOFTWARE.
*/
/* Author: Jakub Kicinski <kubakici@wp.pl> */
#ifndef __BPF_TOOL_H
#define __BPF_TOOL_H
......
......@@ -31,8 +31,6 @@
* SOFTWARE.
*/
/* Author: Jakub Kicinski <kubakici@wp.pl> */
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
......
/*
* Copyright (C) 2017 Netronome Systems, Inc.
* Copyright (C) 2017-2018 Netronome Systems, Inc.
*
* This software is dual licensed under the GNU General License Version 2,
* June 1991 as shown in the file COPYING in the top-level directory of this
......@@ -31,8 +31,6 @@
* SOFTWARE.
*/
/* Author: Jakub Kicinski <kubakici@wp.pl> */
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
......
......@@ -234,6 +234,7 @@ struct bpf_object {
size_t nr_maps;
bool loaded;
bool has_pseudo_calls;
/*
* Information when doing elf related work. Only valid if fd
......@@ -400,10 +401,6 @@ bpf_object__init_prog_names(struct bpf_object *obj)
const char *name = NULL;
prog = &obj->programs[pi];
if (prog->idx == obj->efile.text_shndx) {
name = ".text";
goto skip_search;
}
for (si = 0; si < symbols->d_size / sizeof(GElf_Sym) && !name;
si++) {
......@@ -426,12 +423,15 @@ bpf_object__init_prog_names(struct bpf_object *obj)
}
}
if (!name && prog->idx == obj->efile.text_shndx)
name = ".text";
if (!name) {
pr_warning("failed to find sym for prog %s\n",
prog->section_name);
return -EINVAL;
}
skip_search:
prog->name = strdup(name);
if (!prog->name) {
pr_warning("failed to allocate memory for prog sym %s\n",
......@@ -981,6 +981,7 @@ bpf_program__collect_reloc(struct bpf_program *prog, GElf_Shdr *shdr,
prog->reloc_desc[i].type = RELO_CALL;
prog->reloc_desc[i].insn_idx = insn_idx;
prog->reloc_desc[i].text_off = sym.st_value;
obj->has_pseudo_calls = true;
continue;
}
......@@ -1426,6 +1427,12 @@ bpf_program__load(struct bpf_program *prog,
return err;
}
static bool bpf_program__is_function_storage(struct bpf_program *prog,
struct bpf_object *obj)
{
return prog->idx == obj->efile.text_shndx && obj->has_pseudo_calls;
}
static int
bpf_object__load_progs(struct bpf_object *obj)
{
......@@ -1433,7 +1440,7 @@ bpf_object__load_progs(struct bpf_object *obj)
int err;
for (i = 0; i < obj->nr_programs; i++) {
if (obj->programs[i].idx == obj->efile.text_shndx)
if (bpf_program__is_function_storage(&obj->programs[i], obj))
continue;
err = bpf_program__load(&obj->programs[i],
obj->license,
......@@ -1858,8 +1865,8 @@ void *bpf_object__priv(struct bpf_object *obj)
return obj ? obj->priv : ERR_PTR(-EINVAL);
}
struct bpf_program *
bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
static struct bpf_program *
__bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
{
size_t idx;
......@@ -1880,6 +1887,18 @@ bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
return &obj->programs[idx];
}
struct bpf_program *
bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
{
struct bpf_program *prog = prev;
do {
prog = __bpf_program__next(prog, obj);
} while (prog && bpf_program__is_function_storage(prog, obj));
return prog;
}
int bpf_program__set_priv(struct bpf_program *prog, void *priv,
bpf_program_clear_priv_t clear_priv)
{
......@@ -1896,6 +1915,11 @@ void *bpf_program__priv(struct bpf_program *prog)
return prog ? prog->priv : ERR_PTR(-EINVAL);
}
void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex)
{
prog->prog_ifindex = ifindex;
}
const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
{
const char *title;
......@@ -2037,9 +2061,11 @@ static const struct {
BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN),
BPF_PROG_SEC("lwt_out", BPF_PROG_TYPE_LWT_OUT),
BPF_PROG_SEC("lwt_xmit", BPF_PROG_TYPE_LWT_XMIT),
BPF_PROG_SEC("lwt_seg6local", BPF_PROG_TYPE_LWT_SEG6LOCAL),
BPF_PROG_SEC("sockops", BPF_PROG_TYPE_SOCK_OPS),
BPF_PROG_SEC("sk_skb", BPF_PROG_TYPE_SK_SKB),
BPF_PROG_SEC("sk_msg", BPF_PROG_TYPE_SK_MSG),
BPF_PROG_SEC("lirc_mode2", BPF_PROG_TYPE_LIRC_MODE2),
BPF_SA_PROG_SEC("cgroup/bind4", BPF_CGROUP_INET4_BIND),
BPF_SA_PROG_SEC("cgroup/bind6", BPF_CGROUP_INET6_BIND),
BPF_SA_PROG_SEC("cgroup/connect4", BPF_CGROUP_INET4_CONNECT),
......@@ -2120,6 +2146,11 @@ void *bpf_map__priv(struct bpf_map *map)
return map ? map->priv : ERR_PTR(-EINVAL);
}
void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex)
{
map->map_ifindex = ifindex;
}
struct bpf_map *
bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
{
......@@ -2235,7 +2266,7 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
bpf_program__set_expected_attach_type(prog,
expected_attach_type);
if (prog->idx != obj->efile.text_shndx && !first_prog)
if (!bpf_program__is_function_storage(prog, obj) && !first_prog)
first_prog = prog;
}
......
......@@ -109,6 +109,7 @@ int bpf_program__set_priv(struct bpf_program *prog, void *priv,
bpf_program_clear_priv_t clear_priv);
void *bpf_program__priv(struct bpf_program *prog);
void bpf_program__set_ifindex(struct bpf_program *prog, __u32 ifindex);
const char *bpf_program__title(struct bpf_program *prog, bool needs_copy);
......@@ -251,6 +252,7 @@ typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
int bpf_map__set_priv(struct bpf_map *map, void *priv,
bpf_map_clear_priv_t clear_priv);
void *bpf_map__priv(struct bpf_map *map);
void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
int bpf_map__pin(struct bpf_map *map, const char *path);
long libbpf_get_error(const void *ptr);
......
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