Commit Graph
18 Commits
Author SHA1 Message Date
Andrey Ignatov b8482d74a1 bpf: Introduce bpf_sk_{, ancestor_}cgroup_id helpers
With having ability to lookup sockets in cgroup skb programs it becomes
useful to access cgroup id of retrieved sockets so that policies can be
implemented based on origin cgroup of such socket.

For example, a container running in a cgroup can have cgroup skb ingress
program that can lookup peer socket that is sending packets to a process
inside the container and decide whether those packets should be allowed
or denied based on cgroup id of the peer.

More specifically such ingress program can implement intra-host policy
"allow incoming packets only from this same container and not from any
other container on same host" w/o relying on source IP addresses since
quite often it can be the case that containers share same IP address on
the host.

Introduce two new helpers for this use-case: bpf_sk_cgroup_id() and
bpf_sk_ancestor_cgroup_id().

These helpers are similar to existing bpf_skb_{,ancestor_}cgroup_id
helpers with the only difference that sk is used to get cgroup id
instead of skb, and share code with them.

See documentation in UAPI for more details.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/f5884981249ce911f63e9b57ecd5d7d19154ff39.1589486450.git.rdna@fb.com
2020-05-20 01:00:06 -07:00
Andrey Ignatov 3cd9cac8fb bpf: Support narrow loads from bpf_sock_addr.user_port
bpf_sock_addr.user_port supports only 4-byte load and it leads to ugly
code in BPF programs, like:

	volatile __u32 user_port = ctx->user_port;
	__u16 port = bpf_ntohs(user_port);

Since otherwise clang may optimize the load to be 2-byte and it's
rejected by verifier.

Add support for 1- and 2-byte loads same way as it's supported for other
fields in bpf_sock_addr like user_ip4, msg_src_ip4, etc.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/c1e983f4c17573032601d0b2b1f9d1274f24bc16.1589420814.git.rdna@fb.com
2020-05-20 01:00:06 -07:00
Andrey Ignatov 850293ba1c libbpf: Fix bpf_get_link_xdp_id flags handling
Currently if one of XDP_FLAGS_{DRV,HW,SKB}_MODE flags is passed to
bpf_get_link_xdp_id() and there is a single XDP program attached to
ifindex, that program's id will be returned by bpf_get_link_xdp_id() in
prog_id argument no matter what mode the program is attached in, i.e.
flags argument is not taken into account.

For example, if there is a single program attached with
XDP_FLAGS_SKB_MODE but user calls bpf_get_link_xdp_id() with flags =
XDP_FLAGS_DRV_MODE, that skb program will be returned.

Fix it by returning info->prog_id only if user didn't specify flags. If
flags is specified then return corresponding mode-specific-field from
struct xdp_link_info.

The initial error was introduced in commit 50db9f073188 ("libbpf: Add a
support for getting xdp prog id on ifindex") and then refactored in
473f4e133a12 so 473f4e133a12 is used in the Fixes tag.

Fixes: 473f4e133a12 ("libbpf: Add bpf_get_link_xdp_info() function to get more XDP information")
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://lore.kernel.org/bpf/0e9e30490b44b447bb2bebc69c7135e7fe7e4e40.1586236080.git.rdna@fb.com
2020-04-17 15:31:03 -07:00
Andrey Ignatov d2100072b9 bpf: Document BPF_F_QUERY_EFFECTIVE flag
Document BPF_F_QUERY_EFFECTIVE flag, mostly to clarify how it affects
attach_flags what may not be obvious and what may lead to confision.

Specifically attach_flags is returned only for target_fd but if programs
are inherited from an ancestor cgroup then returned attach_flags for
current cgroup may be confusing. For example, two effective programs of
same attach_type can be returned but w/o BPF_F_ALLOW_MULTI in
attach_flags.

Simple repro:
  # bpftool c s /sys/fs/cgroup/path/to/task
  ID       AttachType      AttachFlags     Name
  # bpftool c s /sys/fs/cgroup/path/to/task effective
  ID       AttachType      AttachFlags     Name
  95043    ingress                         tw_ipt_ingress
  95048    ingress                         tw_ingress

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/bpf/20200108014006.938363-1-rdna@fb.com
2020-01-10 11:15:12 -08:00
Andrey Ignatov 8b20ffa4b9 libbpf: Introduce bpf_prog_attach_xattr
Introduce a new bpf_prog_attach_xattr function that, in addition to
program fd, target fd and attach type, accepts an extendable struct
bpf_prog_attach_opts.

bpf_prog_attach_opts relies on DECLARE_LIBBPF_OPTS macro to maintain
backward and forward compatibility and has the following "optional"
attach attributes:

* existing attach_flags, since it's not required when attaching in NONE
  mode. Even though it's quite often used in MULTI and OVERRIDE mode it
  seems to be a good idea to reduce number of arguments to
  bpf_prog_attach_xattr;

* newly introduced attribute of BPF_PROG_ATTACH command: replace_prog_fd
  that is fd of previously attached cgroup-bpf program to replace if
  BPF_F_REPLACE flag is used.

The new function is named to be consistent with other xattr-functions
(bpf_prog_test_run_xattr, bpf_create_map_xattr, bpf_load_program_xattr).

The struct bpf_prog_attach_opts is supposed to be used with
DECLARE_LIBBPF_OPTS macro.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/bd6e0732303eb14e4b79cb128268d9e9ad6db208.1576741281.git.rdna@fb.com
2019-12-30 12:05:19 -08:00
Andrey Ignatov 1b1e30679f bpf: Support replacing cgroup-bpf program in MULTI mode
The common use-case in production is to have multiple cgroup-bpf
programs per attach type that cover multiple use-cases. Such programs
are attached with BPF_F_ALLOW_MULTI and can be maintained by different
people.

Order of programs usually matters, for example imagine two egress
programs: the first one drops packets and the second one counts packets.
If they're swapped the result of counting program will be different.

It brings operational challenges with updating cgroup-bpf program(s)
attached with BPF_F_ALLOW_MULTI since there is no way to replace a
program:

* One way to update is to detach all programs first and then attach the
  new version(s) again in the right order. This introduces an
  interruption in the work a program is doing and may not be acceptable
  (e.g. if it's egress firewall);

* Another way is attach the new version of a program first and only then
  detach the old version. This introduces the time interval when two
  versions of same program are working, what may not be acceptable if a
  program is not idempotent. It also imposes additional burden on
  program developers to make sure that two versions of their program can
  co-exist.

Solve the problem by introducing a "replace" mode in BPF_PROG_ATTACH
command for cgroup-bpf programs being attached with BPF_F_ALLOW_MULTI
flag. This mode is enabled by newly introduced BPF_F_REPLACE attach flag
and bpf_attr.replace_bpf_fd attribute to pass fd of the old program to
replace

That way user can replace any program among those attached with
BPF_F_ALLOW_MULTI flag without the problems described above.

Details of the new API:

* If BPF_F_REPLACE is set but replace_bpf_fd doesn't have valid
  descriptor of BPF program, BPF_PROG_ATTACH will return corresponding
  error (EINVAL or EBADF).

* If replace_bpf_fd has valid descriptor of BPF program but such a
  program is not attached to specified cgroup, BPF_PROG_ATTACH will
  return ENOENT.

BPF_F_REPLACE is introduced to make the user intent clear, since
replace_bpf_fd alone can't be used for this (its default value, 0, is a
valid fd). BPF_F_REPLACE also makes it possible to extend the API in the
future (e.g. add BPF_F_BEFORE and BPF_F_AFTER if needed).

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Andrii Narkyiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/30cd850044a0057bdfcaaf154b7d2f39850ba813.1576741281.git.rdna@fb.com
2019-12-30 12:05:19 -08:00
Andrey Ignatov 6be72ba83c bpf: Sync bpf.h to tools/
Sync bpf_strtoX related bpf UAPI changes to tools/.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2019-04-19 09:52:37 -07:00
Andrey Ignatov 6cf6bed724 libbpf: Support sysctl hook
Support BPF_PROG_TYPE_CGROUP_SYSCTL program in libbpf: identifying
program and attach types by section name, probe.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2019-04-19 09:52:37 -07:00
Andrey Ignatov 805f4593af bpf: Sync bpf.h to tools/
Sync BPF_PROG_TYPE_CGROUP_SYSCTL related bpf UAPI changes to tools/.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2019-04-19 09:52:37 -07:00
Andrey Ignatov ac2254d0ea libbpf: Fix build with gcc-8
Reported in [1].

With gcc 8.3.0 the following error is issued:

  cc -Ibpf@sta -I. -I.. -I.././include -I.././include/uapi
  -fdiagnostics-color=always -fsanitize=address,undefined -fno-omit-frame-pointer
  -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Werror -g -fPIC -g -O2
  -Werror -Wall -Wno-pointer-arith -Wno-sign-compare  -MD -MQ
  'bpf@sta/src_libbpf.c.o' -MF 'bpf@sta/src_libbpf.c.o.d' -o
  'bpf@sta/src_libbpf.c.o' -c ../src/libbpf.c
  ../src/libbpf.c: In function 'bpf_object__elf_collect':
  ../src/libbpf.c:947:18: error: 'map_def_sz' may be used uninitialized in this
  function [-Werror=maybe-uninitialized]
     if (map_def_sz <= sizeof(struct bpf_map_def)) {
         ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  ../src/libbpf.c:827:18: note: 'map_def_sz' was declared here
    int i, map_idx, map_def_sz, nr_syms, nr_maps = 0, nr_maps_glob = 0;
                    ^~~~~~~~~~

According to [2] -Wmaybe-uninitialized is enabled by -Wall.
Same error is generated by clang's -Wconditional-uninitialized.

[1] https://github.com/libbpf/libbpf/pull/29#issuecomment-481902601
[2] https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

Fixes: d859900c4c56 ("bpf, libbpf: support global data/bss/rodata sections")
Reported-by: Evgeny Vereshchagin <evvers@ya.ru>
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2019-04-11 09:01:12 -07:00
Andrey Ignatov a6ce1c6423 libbpf: Ignore -Wformat-nonliteral warning
vsprintf() in __base_pr() uses nonliteral format string and it breaks
compilation for those who provide corresponding extra CFLAGS, e.g.:
https://github.com/libbpf/libbpf/issues/27

If libbpf is built with the flags from PR:

  libbpf.c:68:26: error: format string is not a string literal
  [-Werror,-Wformat-nonliteral]
          return vfprintf(stderr, format, args);
                                  ^~~~~~
  1 error generated.

Ignore this warning since the use case in libbpf.c is legit.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2019-04-10 14:27:33 -07:00
Andrey Ignatov 23a177a0ce Add SONAME to DSO
Adopting common practice that was adopted earlier in kernel tree.

Resulting DSO:

  % readelf -d root/usr/lib64/libbpf.so | grep SONAME
   0x000000000000000e (SONAME)             Library soname: [libbpf.so.0]

Signed-off-by: Andrey Ignatov <rdna@fb.com>
2019-04-02 18:43:14 -07:00
Andrey Ignatov db1adc8658 Add symlinks for DSO
Add symlinks with version suffix in a way similar to how it's done in
kernel tree.

The differences with kernel tree version:

* LIBS is used to handle both files and targets w/o separation;

* Version symlink is created in corresponding target as opposed to do
  everything in libbpf.so.$(LIBBPF_VERSION).

Example:

  % OBJDIR=build DESTDIR=root make install
  ...
  % find root/ ! -type d -exec ls -l {} +
  -rw-r--r--. 1 rdna users   6046 Apr  2 18:09 root/usr/include/bpf/bpf.h
  -rw-r--r--. 1 rdna users   3485 Apr  2 18:09 root/usr/include/bpf/btf.h
  -rw-r--r--. 1 rdna users  16454 Apr  2 18:09 root/usr/include/bpf/libbpf.h
  -rw-r--r--. 1 rdna users 602030 Apr  2 18:09 root/usr/lib64/libbpf.a
  lrwxrwxrwx. 1 rdna users     11 Apr  2 18:09 root/usr/lib64/libbpf.so -> libbpf.so.0
  lrwxrwxrwx. 1 rdna users     15 Apr  2 18:09 root/usr/lib64/libbpf.so.0 -> libbpf.so.0.0.2
  -rwxr-xr-x. 1 rdna users 377640 Apr  2 18:09 root/usr/lib64/libbpf.so.0.0.2
  -rw-r--r--. 1 rdna users    241 Apr  2 18:09 root/usr/lib64/pkgconfig/libbpf.pc

Signed-off-by: Andrey Ignatov <rdna@fb.com>
2019-04-02 18:37:19 -07:00
Andrey Ignatov c3b329c387 Add LIBBPF_VERSION
LIBBPF_VERSION is already used to generate libbpf.pc file but was not
actuall set.

Set it same way it's done in kernel tree. Version is in sync with
version script for DSO.

Before:
  % grep Version src/libbpf.pc
  Version:

After:
  % grep Version src/libbpf.pc
  Version: 0.0.2

Fixes: 93bc1d0 ("makefile: sync generate pkg-config file for libbpf")
Signed-off-by: Andrey Ignatov <rdna@fb.com>
2019-04-02 16:41:13 -07:00
Andrey Ignatov 8c091e4ffd Enable version script for DSO building
Version script was synced from kernel tree but not enabled in Makefile.
Enable it same way it's done in kernel tree.

  % readelf -s --wide src/libbpf.so | grep -Eo '[^ ]+@LIBBPF_.*' | \
      cut -d@ -f 3 | sort | uniq -c
    121 LIBBPF_0.0.1
     29 LIBBPF_0.0.2

Signed-off-by: Andrey Ignatov <rdna@fb.com>
2019-04-02 16:36:46 -07:00
Andrey Ignatov 2dd2a2d701 Fix libbpf.pc target
OBJDIR was not specified for libbpf.pc. It works by default since
default value of OBJDIR is current directory, but breaks as soon as
OBJDIR is set to some other directory:

  % OBJDIR=build DESTDIR=root make install
  ...
  ar rcs build/libbpf.a build/bpf.o build/btf.o build/libbpf.o
  build/libbpf_errno.o build/netlink.o build/nlattr.o build/str_error.o
  build/libbpf_probes.o build/bpf_prog_linfo.o build/xsk.o
  cc -shared  -lelf   build/bpf.o build/btf.o build/libbpf.o build/libbpf_errno.o
  build/netlink.o build/nlattr.o build/str_error.o build/libbpf_probes.o
  build/bpf_prog_linfo.o build/xsk.o -o build/libbpf.so
  make: *** No rule to make target `libbpf.pc', needed by `all'.  Stop.

Fix it.

Signed-off-by: Andrey Ignatov <rdna@fb.com>
2019-03-29 14:52:01 -07:00
Andrey Ignatov a82a66eda3 Extend build and add install rules to Makefile
Introduce multiple improvements to Makefile to make the build more
flexible and support install:

* Support overriding CFLAGS by user but keep required flags in place.
  ALL_FLAGS is used in Makefile as recommended in [1].

* Add additional BUILD_SHARED flag to build dynamically linked flavor of
  the library. If the flag is set, -fPIC is also passed to make it
  possible to build .so.

* Support building in a separate directory provided by OBJDIR variable.

* Add multiple install targets. By default the library itself and libbpf
  headers are installed (install target). UAPI headers can be optionally
  installed by user.

* All installation paths, including PREFIX, library and include
  directories can be overridden. UAPI can be made different from include
  directory for libbpf headers. That makes it possible to keep latest
  <linux/bpf.h> in a place that doesn't conflict with the one installed
  e.g. by kernel-headers package and use it in user's build system.

* Support DESTDIR (see [2]).

* Support overriding LDFLAGS.

* Use utilities such as rm directly as recommended in [3].

* Use compiler and related programs (such as ar) via make variables as
  recommended in [3].

* In clean rule remove all possible build artifacts not to rely on passed
  options (e.g. if build was done w/ BUILD_SHARED, but clean w/o it).

* Document new build options in README.

[1] https://www.gnu.org/software/make/manual/html_node/Command-Variables.html#Command-Variables
[2] https://www.gnu.org/prep/standards/html_node/DESTDIR.html
[3] https://www.gnu.org/software/make/manual/html_node/Utilities-in-Makefiles.html#Utilities-in-Makefiles

Signed-off-by: Andrey Ignatov <rdna@fb.com>
2018-10-11 15:45:50 -07:00
Andrey Ignatov c2015d0a65 Add if_link.h and netlink.h UAPI headers
Add more UAPI headers from kernel tree since libbpf relies on their
latest versions that may not be present on target system to use in
build.

if_link.h and netlink.h are synced to include/uapi/linux/ from [1]

[1]
https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/tree/tools/include/uapi/linux

Signed-off-by: Andrey Ignatov <rdna@fb.com>
2018-10-11 15:26:06 -07:00