mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-15 22:09:06 +08:00
Compare commits
3 Commits
v0.4.0
...
netdata-pa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
673424c561 | ||
|
|
d2feaff998 | ||
|
|
0d4b75d30e |
51
.travis.yml
51
.travis.yml
@@ -1,6 +1,6 @@
|
||||
sudo: required
|
||||
language: bash
|
||||
dist: focal
|
||||
dist: bionic
|
||||
services:
|
||||
- docker
|
||||
|
||||
@@ -35,23 +35,8 @@ stages:
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: Builds & Tests
|
||||
name: Kernel 5.5.0 + selftests
|
||||
language: bash
|
||||
env: KERNEL=5.5.0
|
||||
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
|
||||
|
||||
- name: Kernel LATEST + selftests
|
||||
language: bash
|
||||
env: KERNEL=LATEST
|
||||
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
|
||||
|
||||
- name: Kernel 4.9.0 + selftests
|
||||
language: bash
|
||||
env: KERNEL=4.9.0
|
||||
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
|
||||
|
||||
- name: Debian Build
|
||||
- stage: Build & Test
|
||||
name: Debian Build
|
||||
language: bash
|
||||
install: $CI_ROOT/managers/debian.sh SETUP
|
||||
script: $CI_ROOT/managers/debian.sh RUN || travis_terminate 1
|
||||
@@ -75,37 +60,47 @@ jobs:
|
||||
script: $CI_ROOT/managers/debian.sh RUN_CLANG_ASAN || travis_terminate 1
|
||||
after_script: $CI_ROOT/managers/debian.sh CLEANUP
|
||||
|
||||
- name: Debian Build (gcc-10)
|
||||
- name: Debian Build (gcc-8)
|
||||
language: bash
|
||||
install: $CI_ROOT/managers/debian.sh SETUP
|
||||
script: $CI_ROOT/managers/debian.sh RUN_GCC10 || travis_terminate 1
|
||||
script: $CI_ROOT/managers/debian.sh RUN_GCC8 || travis_terminate 1
|
||||
after_script: $CI_ROOT/managers/debian.sh CLEANUP
|
||||
|
||||
- name: Debian Build (gcc-10 ASan+UBSan)
|
||||
- name: Debian Build (gcc-8 ASan+UBSan)
|
||||
language: bash
|
||||
install: $CI_ROOT/managers/debian.sh SETUP
|
||||
script: $CI_ROOT/managers/debian.sh RUN_GCC10_ASAN || travis_terminate 1
|
||||
script: $CI_ROOT/managers/debian.sh RUN_GCC8_ASAN || travis_terminate 1
|
||||
after_script: $CI_ROOT/managers/debian.sh CLEANUP
|
||||
|
||||
- name: Ubuntu Focal Build
|
||||
- name: Ubuntu Bionic Build
|
||||
language: bash
|
||||
script: sudo $CI_ROOT/managers/ubuntu.sh || travis_terminate 1
|
||||
|
||||
- name: Ubuntu Focal Build (arm)
|
||||
- name: Ubuntu Bionic Build (arm)
|
||||
arch: arm64
|
||||
language: bash
|
||||
script: sudo $CI_ROOT/managers/ubuntu.sh || travis_terminate 1
|
||||
|
||||
- name: Ubuntu Focal Build (s390x)
|
||||
- name: Ubuntu Bionic Build (s390x)
|
||||
arch: s390x
|
||||
language: bash
|
||||
script: sudo $CI_ROOT/managers/ubuntu.sh || travis_terminate 1
|
||||
|
||||
- name: Ubuntu Focal Build (ppc64le)
|
||||
- name: Ubuntu Bionic Build (ppc64le)
|
||||
arch: ppc64le
|
||||
language: bash
|
||||
script: sudo $CI_ROOT/managers/ubuntu.sh || travis_terminate 1
|
||||
|
||||
- name: Kernel 5.5.0 + selftests
|
||||
language: bash
|
||||
env: KERNEL=5.5.0
|
||||
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
|
||||
|
||||
- name: Kernel LATEST + selftests
|
||||
language: bash
|
||||
env: KERNEL=LATEST
|
||||
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
|
||||
|
||||
- stage: Coverity
|
||||
language: bash
|
||||
env:
|
||||
@@ -120,11 +115,9 @@ jobs:
|
||||
- COVERITY_SCAN_BUILD_COMMAND_PREPEND="cd src/"
|
||||
- COVERITY_SCAN_BUILD_COMMAND="make"
|
||||
install:
|
||||
- sudo echo 'deb-src http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse' >>/etc/apt/sources.list
|
||||
- sudo echo 'deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted universe multiverse' >>/etc/apt/sources.list
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y build-dep libelf-dev
|
||||
- sudo apt-get install -y libelf-dev pkg-config
|
||||
script:
|
||||
- scripts/coverity.sh || travis_terminate 1
|
||||
allow_failures:
|
||||
- env: KERNEL=x.x.x
|
||||
|
||||
@@ -1 +1 @@
|
||||
d0c0fe10ce6d87734b65c18dc8f4bcae3f4dbea4
|
||||
4e15507fea70c0c312d79610efa46b6853ccf8e0
|
||||
|
||||
@@ -1 +1 @@
|
||||
f18ba26da88a89db9b50cb4ff47fadb159f2810b
|
||||
69119673bd50b176ded34032fadd41530fb5af21
|
||||
|
||||
82
README.md
82
README.md
@@ -1,26 +1,23 @@
|
||||
BPF/libbpf usage and questions
|
||||
==============================
|
||||
|
||||
Please check out [libbpf-bootstrap](https://github.com/libbpf/libbpf-bootstrap)
|
||||
and [the companion blog post](https://nakryiko.com/posts/libbpf-bootstrap/) for
|
||||
the examples of building BPF applications with libbpf.
|
||||
[libbpf-tools](https://github.com/iovisor/bcc/tree/master/libbpf-tools) are also
|
||||
a good source of the real-world libbpf-based tracing tools.
|
||||
This is a mirror of [bpf-next linux tree](https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next)'s
|
||||
`tools/lib/bpf` directory plus its supporting header files.
|
||||
|
||||
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||
their application, should be sent to bpf@vger.kernel.org mailing list. You can
|
||||
subscribe to it [here](http://vger.kernel.org/vger-lists.html#bpf) and search
|
||||
its archive [here](https://lore.kernel.org/bpf/). Please search the archive
|
||||
before asking new questions. It very well might be that this was already
|
||||
addressed or answered before.
|
||||
The following files will by sync'ed with bpf-next repo:
|
||||
- `src/` <-> `bpf-next/tools/lib/bpf/`
|
||||
- `include/uapi/linux/bpf_common.h` <-> `bpf-next/tools/include/uapi/linux/bpf_common.h`
|
||||
- `include/uapi/linux/bpf.h` <-> `bpf-next/tools/include/uapi/linux/bpf.h`
|
||||
- `include/uapi/linux/btf.h` <-> `bpf-next/tools/include/uapi/linux/btf.h`
|
||||
- `include/uapi/linux/if_link.h` <-> `bpf-next/tools/include/uapi/linux/if_link.h`
|
||||
- `include/uapi/linux/if_xdp.h` <-> `bpf-next/tools/include/uapi/linux/if_xdp.h`
|
||||
- `include/uapi/linux/netlink.h` <-> `bpf-next/tools/include/uapi/linux/netlink.h`
|
||||
- `include/tools/libc_compat.h` <-> `bpf-next/tools/include/tools/libc_compat.h`
|
||||
|
||||
bpf@vger.kernel.org is monitored by many more people and they will happily try
|
||||
to help you with whatever issue you have. This repository's PRs and issues
|
||||
should be opened only for dealing with issues pertaining to specific way this
|
||||
libbpf mirror repo is set up and organized.
|
||||
Other header files at this repo (`include/linux/*.h`) are reduced versions of
|
||||
their counterpart files at bpf-next's `tools/include/linux/*.h` to make compilation
|
||||
successful.
|
||||
|
||||
Build
|
||||
[](https://travis-ci.com/github/libbpf/libbpf)
|
||||
[](https://travis-ci.org/libbpf/libbpf)
|
||||
[](https://lgtm.com/projects/g/libbpf/libbpf/alerts/)
|
||||
[](https://scan.coverity.com/projects/libbpf)
|
||||
=====
|
||||
@@ -28,9 +25,8 @@ libelf is an internal dependency of libbpf and thus it is required to link
|
||||
against and must be installed on the system for applications to work.
|
||||
pkg-config is used by default to find libelf, and the program called can be
|
||||
overridden with `PKG_CONFIG`.
|
||||
|
||||
If using `pkg-config` at build time is not desired, it can be disabled by
|
||||
setting `NO_PKG_CONFIG=1` when calling make.
|
||||
If using `pkg-config` at build time is not desired, it can be disabled by setting
|
||||
`NO_PKG_CONFIG=1` when calling make.
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so:
|
||||
```bash
|
||||
@@ -61,23 +57,18 @@ Distributions
|
||||
Distributions packaging libbpf from this mirror:
|
||||
- [Fedora](https://src.fedoraproject.org/rpms/libbpf)
|
||||
- [Gentoo](https://packages.gentoo.org/packages/dev-libs/libbpf)
|
||||
- [Debian](https://packages.debian.org/source/sid/libbpf)
|
||||
- [Arch](https://www.archlinux.org/packages/extra/x86_64/libbpf/)
|
||||
- [Ubuntu](https://packages.ubuntu.com/source/groovy/libbpf)
|
||||
- [Alpine](https://pkgs.alpinelinux.org/packages?name=libbpf)
|
||||
- [Debian](https://packages.debian.org/sid/libbpf-dev)
|
||||
|
||||
Benefits of packaging from the mirror over packaging from kernel sources:
|
||||
- Consistent versioning across distributions.
|
||||
- No ties to any specific kernel, transparent handling of older kernels.
|
||||
Libbpf is designed to be kernel-agnostic and work across multitude of
|
||||
kernel versions. It has built-in mechanisms to gracefully handle older
|
||||
kernels, that are missing some of the features, by working around or
|
||||
gracefully degrading functionality. Thus libbpf is not tied to a specific
|
||||
kernel version and can/should be packaged and versioned independently.
|
||||
- Continuous integration testing via
|
||||
[TravisCI](https://travis-ci.org/libbpf/libbpf).
|
||||
- Static code analysis via [LGTM](https://lgtm.com/projects/g/libbpf/libbpf)
|
||||
and [Coverity](https://scan.coverity.com/projects/libbpf).
|
||||
Libbpf is designed to be kernel-agnostic and work across multitude of kernel
|
||||
versions. It has built-in mechanisms to gracefully handle older kernels,
|
||||
that are missing some of the features, by working around or gracefully
|
||||
degrading functionality. Thus libbpf is not tied to a specific kernel
|
||||
version and can/should be packaged and versioned independently.
|
||||
- Continuous integration testing via [TravisCI](https://travis-ci.org/libbpf/libbpf).
|
||||
- Static code analysis via [LGTM](https://lgtm.com/projects/g/libbpf/libbpf) and [Coverity](https://scan.coverity.com/projects/libbpf).
|
||||
|
||||
Package dependencies of libbpf, package names may vary across distros:
|
||||
- zlib
|
||||
@@ -98,8 +89,6 @@ Some major Linux distributions come with kernel BTF already built in:
|
||||
- RHEL 8.2+
|
||||
- OpenSUSE Tumbleweed (in the next release, as of 2020-06-04)
|
||||
- Arch Linux (from kernel 5.7.1.arch1-1)
|
||||
- Ubuntu 20.10
|
||||
- Debian 11 (amd64/arm64)
|
||||
|
||||
If your kernel doesn't come with BTF built-in, you'll need to build custom
|
||||
kernel. You'll need:
|
||||
@@ -119,34 +108,17 @@ distributions have Clang/LLVM 10+ packaged by default:
|
||||
- Fedora 32+
|
||||
- Ubuntu 20.04+
|
||||
- Arch Linux
|
||||
- Ubuntu 20.10 (LLVM 11)
|
||||
- Debian 11 (LLVM 11)
|
||||
- Alpine 3.13+
|
||||
|
||||
Otherwise, please make sure to update it on your system.
|
||||
|
||||
The following resources are useful to understand what BPF CO-RE is and how to
|
||||
use it:
|
||||
- [BPF Portability and CO-RE](https://nakryiko.com/posts/bpf-portability-and-co-re/)
|
||||
- [HOWTO: BCC to libbpf conversion](https://nakryiko.com/posts/bcc-to-libbpf-howto-guide/)
|
||||
- [BPF Portability and CO-RE](https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html)
|
||||
- [HOWTO: BCC to libbpf conversion](https://facebookmicrosites.github.io/bpf/blog/2020/02/20/bcc-to-libbpf-howto-guide.html)
|
||||
- [libbpf-tools in BCC repo](https://github.com/iovisor/bcc/tree/master/libbpf-tools)
|
||||
contain lots of real-world tools converted from BCC to BPF CO-RE. Consider
|
||||
converting some more to both contribute to the BPF community and gain some
|
||||
more experience with it.
|
||||
|
||||
Details
|
||||
=======
|
||||
This is a mirror of [bpf-next Linux source
|
||||
tree](https://kernel.googlesource.com/pub/scm/linux/kernel/git/bpf/bpf-next)'s
|
||||
`tools/lib/bpf` directory plus its supporting header files.
|
||||
|
||||
All the gory details of syncing can be found in `scripts/sync-kernel.sh`
|
||||
script.
|
||||
|
||||
Some header files in this repo (`include/linux/*.h`) are reduced versions of
|
||||
their counterpart files at
|
||||
[bpf-next](https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/)'s
|
||||
`tools/include/linux/*.h` to make compilation successful.
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
@@ -5,14 +5,6 @@
|
||||
|
||||
#include <linux/bpf.h>
|
||||
|
||||
#define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM) \
|
||||
((struct bpf_insn) { \
|
||||
.code = CODE, \
|
||||
.dst_reg = DST, \
|
||||
.src_reg = SRC, \
|
||||
.off = OFF, \
|
||||
.imm = IMM })
|
||||
|
||||
#define BPF_ALU64_IMM(OP, DST, IMM) \
|
||||
((struct bpf_insn) { \
|
||||
.code = BPF_ALU64 | BPF_OP(OP) | BPF_K, \
|
||||
|
||||
@@ -72,20 +72,11 @@ static inline void list_del(struct list_head *entry)
|
||||
entry->prev = LIST_POISON2;
|
||||
}
|
||||
|
||||
static inline int list_empty(const struct list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
#define list_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
#define list_first_entry(ptr, type, member) \
|
||||
list_entry((ptr)->next, type, member)
|
||||
#define list_next_entry(pos, member) \
|
||||
list_entry((pos)->member.next, typeof(*(pos)), member)
|
||||
#define list_for_each_entry(pos, head, member) \
|
||||
for (pos = list_first_entry(head, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_next_entry(pos, member))
|
||||
|
||||
#endif
|
||||
|
||||
20
include/tools/libc_compat.h
Normal file
20
include/tools/libc_compat.h
Normal file
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: (LGPL-2.0+ OR BSD-2-Clause)
|
||||
/* Copyright (C) 2018 Netronome Systems, Inc. */
|
||||
|
||||
#ifndef __TOOLS_LIBC_COMPAT_H
|
||||
#define __TOOLS_LIBC_COMPAT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
#ifdef COMPAT_NEED_REALLOCARRAY
|
||||
static inline void *reallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
size_t bytes;
|
||||
|
||||
if (unlikely(check_mul_overflow(nmemb, size, &bytes)))
|
||||
return NULL;
|
||||
return realloc(ptr, bytes);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,7 +52,7 @@ struct btf_type {
|
||||
};
|
||||
};
|
||||
|
||||
#define BTF_INFO_KIND(info) (((info) >> 24) & 0x1f)
|
||||
#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
|
||||
#define BTF_INFO_VLEN(info) ((info) & 0xffff)
|
||||
#define BTF_INFO_KFLAG(info) ((info) >> 31)
|
||||
|
||||
@@ -72,8 +72,7 @@ struct btf_type {
|
||||
#define BTF_KIND_FUNC_PROTO 13 /* Function Proto */
|
||||
#define BTF_KIND_VAR 14 /* Variable */
|
||||
#define BTF_KIND_DATASEC 15 /* Section */
|
||||
#define BTF_KIND_FLOAT 16 /* Floating point */
|
||||
#define BTF_KIND_MAX BTF_KIND_FLOAT
|
||||
#define BTF_KIND_MAX BTF_KIND_DATASEC
|
||||
#define NR_BTF_KINDS (BTF_KIND_MAX + 1)
|
||||
|
||||
/* For some specific BTF_KIND, "struct btf_type" is immediately
|
||||
|
||||
@@ -344,7 +344,6 @@ enum {
|
||||
IFLA_BRPORT_ISOLATED,
|
||||
IFLA_BRPORT_BACKUP_PORT,
|
||||
IFLA_BRPORT_MRP_RING_OPEN,
|
||||
IFLA_BRPORT_MRP_IN_OPEN,
|
||||
__IFLA_BRPORT_MAX
|
||||
};
|
||||
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
|
||||
@@ -409,8 +408,6 @@ enum {
|
||||
IFLA_MACVLAN_MACADDR,
|
||||
IFLA_MACVLAN_MACADDR_DATA,
|
||||
IFLA_MACVLAN_MACADDR_COUNT,
|
||||
IFLA_MACVLAN_BC_QUEUE_LEN,
|
||||
IFLA_MACVLAN_BC_QUEUE_LEN_USED,
|
||||
__IFLA_MACVLAN_MAX,
|
||||
};
|
||||
|
||||
|
||||
@@ -73,12 +73,9 @@ struct xdp_umem_reg {
|
||||
};
|
||||
|
||||
struct xdp_statistics {
|
||||
__u64 rx_dropped; /* Dropped for other reasons */
|
||||
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
||||
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 rx_ring_full; /* Dropped due to rx ring being full */
|
||||
__u64 rx_fill_ring_empty_descs; /* Failed to retrieve item from fill ring */
|
||||
__u64 tx_ring_empty_descs; /* Failed to retrieve item from tx ring */
|
||||
};
|
||||
|
||||
struct xdp_options {
|
||||
|
||||
18
scripts/check-reallocarray.sh
Executable file
18
scripts/check-reallocarray.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
tfile=$(mktemp /tmp/test_reallocarray_XXXXXXXX.c)
|
||||
ofile=${tfile%.c}.o
|
||||
|
||||
cat > $tfile <<EOL
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return !!reallocarray(NULL, 1, 1);
|
||||
}
|
||||
EOL
|
||||
|
||||
gcc $tfile -o $ofile >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then echo "FAIL"; fi
|
||||
/bin/rm -f $tfile $ofile
|
||||
@@ -6,6 +6,7 @@ usage () {
|
||||
echo "Set BPF_NEXT_BASELINE to override bpf-next tree commit, otherwise read from <libbpf-repo>/CHECKPOINT-COMMIT."
|
||||
echo "Set BPF_BASELINE to override bpf tree commit, otherwise read from <libbpf-repo>/BPF-CHECKPOINT-COMMIT."
|
||||
echo "Set MANUAL_MODE to 1 to manually control every cherry-picked commits."
|
||||
echo "Set IGNORE_CONSISTENCY to 1 to ignore failed contents consistency check."
|
||||
exit 1
|
||||
}
|
||||
|
||||
@@ -45,12 +46,12 @@ PATH_MAP=( \
|
||||
[tools/include/uapi/linux/if_link.h]=include/uapi/linux/if_link.h \
|
||||
[tools/include/uapi/linux/if_xdp.h]=include/uapi/linux/if_xdp.h \
|
||||
[tools/include/uapi/linux/netlink.h]=include/uapi/linux/netlink.h \
|
||||
[tools/include/tools/libc_compat.h]=include/tools/libc_compat.h \
|
||||
)
|
||||
|
||||
LIBBPF_PATHS="${!PATH_MAP[@]} :^tools/lib/bpf/Makefile :^tools/lib/bpf/Build :^tools/lib/bpf/.gitignore :^tools/include/tools/libc_compat.h"
|
||||
LIBBPF_PATHS="${!PATH_MAP[@]} :^tools/lib/bpf/Makefile :^tools/lib/bpf/Build :^tools/lib/bpf/.gitignore"
|
||||
LIBBPF_VIEW_PATHS="${PATH_MAP[@]}"
|
||||
LIBBPF_VIEW_EXCLUDE_REGEX='^src/(Makefile|Build|test_libbpf\.c|bpf_helper_defs\.h|\.gitignore)$'
|
||||
LINUX_VIEW_EXCLUDE_REGEX='^include/tools/libc_compat.h$'
|
||||
|
||||
LIBBPF_TREE_FILTER="mkdir -p __libbpf/include/uapi/linux __libbpf/include/tools && "$'\\\n'
|
||||
for p in "${!PATH_MAP[@]}"; do
|
||||
@@ -136,7 +137,6 @@ cherry_pick_commits()
|
||||
echo "Warning! Cherry-picking '${desc} failed, checking if it's non-libbpf files causing problems..."
|
||||
libbpf_conflict_cnt=$(git diff --name-only --diff-filter=U -- ${LIBBPF_PATHS[@]} | wc -l)
|
||||
conflict_cnt=$(git diff --name-only | wc -l)
|
||||
prompt_resolution=1
|
||||
|
||||
if ((${libbpf_conflict_cnt} == 0)); then
|
||||
echo "Looks like only non-libbpf files have conflicts, ignoring..."
|
||||
@@ -152,37 +152,15 @@ cherry_pick_commits()
|
||||
echo "Error! That still failed! Please resolve manually."
|
||||
else
|
||||
echo "Success! All cherry-pick conflicts were resolved for '${desc}'!"
|
||||
prompt_resolution=0
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
|
||||
if ((${prompt_resolution} == 1)); then
|
||||
read -p "Error! Cherry-picking '${desc}' failed, please fix manually and press <return> to proceed..."
|
||||
fi
|
||||
read -p "Error! Cherry-picking '${desc}' failed, please fix manually and press <return> to proceed..."
|
||||
fi
|
||||
# Append signature of just cherry-picked commit to avoid
|
||||
# potentially cherry-picking the same commit twice later when
|
||||
# processing bpf tree commits. At this point we don't know yet
|
||||
# the final commit sha in libbpf repo, so we record Linux SHA
|
||||
# instead as LINUX_<sha>.
|
||||
echo LINUX_$(git log --pretty='%h' -n1) "${signature}" >> ${TMP_DIR}/libbpf_commits.txt
|
||||
done
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
echo "Cleaning up..."
|
||||
rm -r ${TMP_DIR}
|
||||
cd_to ${LINUX_REPO}
|
||||
git checkout ${TIP_SYM_REF}
|
||||
git branch -D ${BASELINE_TAG} ${TIP_TAG} ${BPF_BASELINE_TAG} ${BPF_TIP_TAG} \
|
||||
${SQUASH_BASE_TAG} ${SQUASH_TIP_TAG} ${VIEW_TAG} || true
|
||||
|
||||
cd_to .
|
||||
echo "DONE."
|
||||
}
|
||||
|
||||
|
||||
cd_to ${LIBBPF_REPO}
|
||||
GITHUB_ABS_DIR=$(pwd)
|
||||
echo "Dumping existing libbpf commit signatures..."
|
||||
@@ -248,7 +226,6 @@ FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch --prune-empty -f --subdirector
|
||||
COMMIT_CNT=$(git rev-list --count ${SQUASH_BASE_TAG}..${SQUASH_TIP_TAG})
|
||||
if ((${COMMIT_CNT} <= 0)); then
|
||||
echo "No new changes to apply, we are done!"
|
||||
cleanup
|
||||
exit 2
|
||||
fi
|
||||
|
||||
@@ -260,18 +237,18 @@ cd_to ${LIBBPF_REPO}
|
||||
git checkout -b ${LIBBPF_SYNC_TAG}
|
||||
|
||||
for patch in $(ls -1 ${TMP_DIR}/patches | tail -n +2); do
|
||||
if ! git am --3way --committer-date-is-author-date "${TMP_DIR}/patches/${patch}"; then
|
||||
if ! git am --committer-date-is-author-date "${TMP_DIR}/patches/${patch}"; then
|
||||
read -p "Applying ${TMP_DIR}/patches/${patch} failed, please resolve manually and press <return> to proceed..."
|
||||
fi
|
||||
done
|
||||
|
||||
# Generate bpf_helper_defs.h and commit, if anything changed
|
||||
# restore Linux tip to use bpf_doc.py
|
||||
# restore Linux tip to use bpf_helpers_doc.py
|
||||
cd_to ${LINUX_REPO}
|
||||
git checkout ${TIP_TAG}
|
||||
# re-generate bpf_helper_defs.h
|
||||
cd_to ${LIBBPF_REPO}
|
||||
"${LINUX_ABS_DIR}/scripts/bpf_doc.py" --header \
|
||||
"${LINUX_ABS_DIR}/scripts/bpf_helpers_doc.py" --header \
|
||||
--file include/uapi/linux/bpf.h > src/bpf_helper_defs.h
|
||||
# if anything changed, commit it
|
||||
helpers_changes=$(git status --porcelain src/bpf_helper_defs.h | wc -l)
|
||||
@@ -309,7 +286,7 @@ cd_to ${LINUX_REPO}
|
||||
git checkout -b ${VIEW_TAG} ${TIP_COMMIT}
|
||||
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --tree-filter "${LIBBPF_TREE_FILTER}" ${VIEW_TAG}^..${VIEW_TAG}
|
||||
FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --subdirectory-filter __libbpf ${VIEW_TAG}^..${VIEW_TAG}
|
||||
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} | grep -v -E "${LINUX_VIEW_EXCLUDE_REGEX}" > ${TMP_DIR}/linux-view.ls
|
||||
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} > ${TMP_DIR}/linux-view.ls
|
||||
|
||||
cd_to ${LIBBPF_REPO}
|
||||
git ls-files -- ${LIBBPF_VIEW_PATHS[@]} | grep -v -E "${LIBBPF_VIEW_EXCLUDE_REGEX}" > ${TMP_DIR}/github-view.ls
|
||||
@@ -327,17 +304,19 @@ done
|
||||
if ((${CONSISTENT} == 1)); then
|
||||
echo "Great! Content is identical!"
|
||||
else
|
||||
ignore_inconsistency=n
|
||||
echo "Unfortunately, there are some inconsistencies, please double check."
|
||||
read -p "Does everything look good? [y/N]: " ignore_inconsistency
|
||||
case "${ignore_inconsistency}" in
|
||||
"y" | "Y")
|
||||
echo "Ok, proceeding..."
|
||||
;;
|
||||
*)
|
||||
echo "Oops, exiting with error..."
|
||||
exit 4
|
||||
esac
|
||||
echo "Unfortunately, there are consistency problems!"
|
||||
if ((${IGNORE_CONSISTENCY-0} != 1)); then
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
|
||||
cleanup
|
||||
echo "Cleaning up..."
|
||||
rm -r ${TMP_DIR}
|
||||
cd_to ${LINUX_REPO}
|
||||
git checkout ${TIP_SYM_REF}
|
||||
git branch -D ${BASELINE_TAG} ${TIP_TAG} ${BPF_BASELINE_TAG} ${BPF_TIP_TAG} \
|
||||
${SQUASH_BASE_TAG} ${SQUASH_TIP_TAG} ${VIEW_TAG}
|
||||
|
||||
cd_to .
|
||||
echo "DONE."
|
||||
|
||||
|
||||
87
src/Makefile
87
src/Makefile
@@ -1,13 +1,5 @@
|
||||
# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
ifeq ($(V),1)
|
||||
Q =
|
||||
msg =
|
||||
else
|
||||
Q = @
|
||||
msg = @printf ' %-8s %s%s\n' "$(1)" "$(notdir $(2))" "$(if $(3), $(3))";
|
||||
endif
|
||||
|
||||
LIBBPF_VERSION := $(shell \
|
||||
grep -oE '^LIBBPF_([0-9.]+)' libbpf.map | \
|
||||
sort -rV | head -n1 | cut -d'_' -f2)
|
||||
@@ -18,6 +10,11 @@ TOPDIR = ..
|
||||
INCLUDES := -I. -I$(TOPDIR)/include -I$(TOPDIR)/include/uapi
|
||||
ALL_CFLAGS := $(INCLUDES)
|
||||
|
||||
FEATURE_REALLOCARRAY := $(shell $(TOPDIR)/scripts/check-reallocarray.sh)
|
||||
ifneq ($(FEATURE_REALLOCARRAY),)
|
||||
ALL_CFLAGS += -DCOMPAT_NEED_REALLOCARRAY
|
||||
endif
|
||||
|
||||
SHARED_CFLAGS += -fPIC -fvisibility=hidden -DSHARED
|
||||
|
||||
CFLAGS ?= -g -O2 -Werror -Wall
|
||||
@@ -27,8 +24,8 @@ ifdef NO_PKG_CONFIG
|
||||
ALL_LDFLAGS += -lelf -lz
|
||||
else
|
||||
PKG_CONFIG ?= pkg-config
|
||||
ALL_CFLAGS += $(shell $(PKG_CONFIG) --cflags libelf zlib)
|
||||
ALL_LDFLAGS += $(shell $(PKG_CONFIG) --libs libelf zlib)
|
||||
ALL_CFLAGS += $(shell $(PKG_CONFIG) --cflags libelf)
|
||||
ALL_LDFLAGS += $(shell $(PKG_CONFIG) --libs libelf)
|
||||
endif
|
||||
|
||||
OBJDIR ?= .
|
||||
@@ -36,7 +33,7 @@ SHARED_OBJDIR := $(OBJDIR)/sharedobjs
|
||||
STATIC_OBJDIR := $(OBJDIR)/staticobjs
|
||||
OBJS := bpf.o btf.o libbpf.o libbpf_errno.o netlink.o \
|
||||
nlattr.o str_error.o libbpf_probes.o bpf_prog_linfo.o xsk.o \
|
||||
btf_dump.o hashmap.o ringbuf.o strset.o linker.o
|
||||
btf_dump.o hashmap.o ringbuf.o
|
||||
SHARED_OBJS := $(addprefix $(SHARED_OBJDIR)/,$(OBJS))
|
||||
STATIC_OBJS := $(addprefix $(STATIC_OBJDIR)/,$(OBJS))
|
||||
|
||||
@@ -48,7 +45,7 @@ ifndef BUILD_STATIC_ONLY
|
||||
VERSION_SCRIPT := libbpf.map
|
||||
endif
|
||||
|
||||
HEADERS := bpf.h libbpf.h btf.h xsk.h \
|
||||
HEADERS := bpf.h libbpf.h btf.h xsk.h libbpf_util.h \
|
||||
bpf_helpers.h bpf_helper_defs.h bpf_tracing.h \
|
||||
bpf_endian.h bpf_core_read.h libbpf_common.h
|
||||
UAPI_HEADERS := $(addprefix $(TOPDIR)/include/uapi/linux/,\
|
||||
@@ -66,13 +63,6 @@ else
|
||||
LIBSUBDIR := lib
|
||||
endif
|
||||
|
||||
# By default let the pc file itself use ${prefix} in includedir/libdir so that
|
||||
# the prefix can be overridden at runtime (eg: --define-prefix)
|
||||
ifndef LIBDIR
|
||||
LIBDIR_PC := $$\{prefix\}/$(LIBSUBDIR)
|
||||
else
|
||||
LIBDIR_PC := $(LIBDIR)
|
||||
endif
|
||||
PREFIX ?= /usr
|
||||
LIBDIR ?= $(PREFIX)/$(LIBSUBDIR)
|
||||
INCLUDEDIR ?= $(PREFIX)/include
|
||||
@@ -83,54 +73,50 @@ TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags)
|
||||
all: $(STATIC_LIBS) $(SHARED_LIBS) $(PC_FILE)
|
||||
|
||||
$(OBJDIR)/libbpf.a: $(STATIC_OBJS)
|
||||
$(call msg,AR,$@)
|
||||
$(Q)$(AR) rcs $@ $^
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
$(OBJDIR)/libbpf.so: $(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION)
|
||||
$(Q)ln -sf $(^F) $@
|
||||
ln -sf $(^F) $@
|
||||
|
||||
$(OBJDIR)/libbpf.so.$(LIBBPF_MAJOR_VERSION): $(OBJDIR)/libbpf.so.$(LIBBPF_VERSION)
|
||||
$(Q)ln -sf $(^F) $@
|
||||
ln -sf $(^F) $@
|
||||
|
||||
$(OBJDIR)/libbpf.so.$(LIBBPF_VERSION): $(SHARED_OBJS)
|
||||
$(call msg,CC,$@)
|
||||
$(Q)$(CC) -shared -Wl,--version-script=$(VERSION_SCRIPT) \
|
||||
-Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \
|
||||
$^ $(ALL_LDFLAGS) -o $@
|
||||
$(CC) -shared -Wl,--version-script=$(VERSION_SCRIPT) \
|
||||
-Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \
|
||||
$^ $(ALL_LDFLAGS) -o $@
|
||||
|
||||
$(OBJDIR)/libbpf.pc:
|
||||
$(Q)sed -e "s|@PREFIX@|$(PREFIX)|" \
|
||||
-e "s|@LIBDIR@|$(LIBDIR_PC)|" \
|
||||
sed -e "s|@PREFIX@|$(PREFIX)|" \
|
||||
-e "s|@LIBDIR@|$(LIBDIR)|" \
|
||||
-e "s|@VERSION@|$(LIBBPF_VERSION)|" \
|
||||
< libbpf.pc.template > $@
|
||||
|
||||
$(STATIC_OBJDIR) $(SHARED_OBJDIR):
|
||||
$(call msg,MKDIR,$@)
|
||||
$(Q)mkdir -p $@
|
||||
$(STATIC_OBJDIR):
|
||||
mkdir -p $(STATIC_OBJDIR)
|
||||
|
||||
$(SHARED_OBJDIR):
|
||||
mkdir -p $(SHARED_OBJDIR)
|
||||
|
||||
$(STATIC_OBJDIR)/%.o: %.c | $(STATIC_OBJDIR)
|
||||
$(call msg,CC,$@)
|
||||
$(Q)$(CC) $(ALL_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
$(CC) $(ALL_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
$(SHARED_OBJDIR)/%.o: %.c | $(SHARED_OBJDIR)
|
||||
$(call msg,CC,$@)
|
||||
$(Q)$(CC) $(ALL_CFLAGS) $(SHARED_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
$(CC) $(ALL_CFLAGS) $(SHARED_CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
define do_install
|
||||
$(call msg,INSTALL,$1)
|
||||
$(Q)if [ ! -d '$(DESTDIR)$2' ]; then \
|
||||
if [ ! -d '$(DESTDIR)$2' ]; then \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR)$2'; \
|
||||
fi;
|
||||
$(Q)$(INSTALL) $(if $3,-m $3,) $1 '$(DESTDIR)$2'
|
||||
fi; \
|
||||
$(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR)$2'
|
||||
endef
|
||||
|
||||
# Preserve symlinks at installation.
|
||||
define do_s_install
|
||||
$(call msg,INSTALL,$1)
|
||||
$(Q)if [ ! -d '$(DESTDIR)$2' ]; then \
|
||||
if [ ! -d '$(DESTDIR)$2' ]; then \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR)$2'; \
|
||||
fi;
|
||||
$(Q)cp -fR $1 '$(DESTDIR)$2'
|
||||
fi; \
|
||||
cp -fpR $1 '$(DESTDIR)$2'
|
||||
endef
|
||||
|
||||
install: all install_headers install_pkgconfig
|
||||
@@ -148,16 +134,13 @@ install_pkgconfig: $(PC_FILE)
|
||||
$(call do_install,$(PC_FILE),$(LIBDIR)/pkgconfig,644)
|
||||
|
||||
clean:
|
||||
$(call msg,CLEAN)
|
||||
$(Q)rm -rf *.o *.a *.so *.so.* *.pc $(SHARED_OBJDIR) $(STATIC_OBJDIR)
|
||||
rm -rf *.o *.a *.so *.so.* *.pc $(SHARED_OBJDIR) $(STATIC_OBJDIR)
|
||||
|
||||
.PHONY: cscope tags
|
||||
cscope:
|
||||
$(call msg,CSCOPE)
|
||||
$(Q)ls *.c *.h > cscope.files
|
||||
$(Q)cscope -b -q -f cscope.out
|
||||
ls *.c *.h > cscope.files
|
||||
cscope -b -q -f cscope.out
|
||||
|
||||
tags:
|
||||
$(call msg,CTAGS)
|
||||
$(Q)rm -f TAGS tags
|
||||
$(Q)ls *.c *.h | xargs $(TAGS_PROG) -a
|
||||
rm -f TAGS tags
|
||||
ls *.c *.h | xargs $(TAGS_PROG) -a
|
||||
|
||||
182
src/bpf.c
182
src/bpf.c
@@ -32,6 +32,9 @@
|
||||
#include "libbpf.h"
|
||||
#include "libbpf_internal.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
/*
|
||||
* When building perf, unistd.h is overridden. __NR_bpf is
|
||||
* required to be defined explicitly.
|
||||
@@ -67,12 +70,11 @@ static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
|
||||
|
||||
static inline int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size)
|
||||
{
|
||||
int retries = 5;
|
||||
int fd;
|
||||
|
||||
do {
|
||||
fd = sys_bpf(BPF_PROG_LOAD, attr, size);
|
||||
} while (fd < 0 && errno == EAGAIN && retries-- > 0);
|
||||
} while (fd < 0 && errno == EAGAIN);
|
||||
|
||||
return fd;
|
||||
}
|
||||
@@ -215,55 +217,59 @@ alloc_zero_tailing_info(const void *orecord, __u32 cnt,
|
||||
return info;
|
||||
}
|
||||
|
||||
int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr)
|
||||
int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
|
||||
char *log_buf, size_t log_buf_sz)
|
||||
{
|
||||
void *finfo = NULL, *linfo = NULL;
|
||||
union bpf_attr attr;
|
||||
__u32 log_level;
|
||||
int fd;
|
||||
|
||||
if (!load_attr->log_buf != !load_attr->log_buf_sz)
|
||||
if (!load_attr || !log_buf != !log_buf_sz)
|
||||
return -EINVAL;
|
||||
|
||||
if (load_attr->log_level > (4 | 2 | 1) || (load_attr->log_level && !load_attr->log_buf))
|
||||
log_level = load_attr->log_level;
|
||||
if (log_level > (4 | 2 | 1) || (log_level && !log_buf))
|
||||
return -EINVAL;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.prog_type = load_attr->prog_type;
|
||||
attr.expected_attach_type = load_attr->expected_attach_type;
|
||||
|
||||
if (load_attr->attach_prog_fd)
|
||||
if (attr.prog_type == BPF_PROG_TYPE_STRUCT_OPS ||
|
||||
attr.prog_type == BPF_PROG_TYPE_LSM) {
|
||||
attr.attach_btf_id = load_attr->attach_btf_id;
|
||||
} else if (attr.prog_type == BPF_PROG_TYPE_TRACING ||
|
||||
attr.prog_type == BPF_PROG_TYPE_EXT) {
|
||||
attr.attach_btf_id = load_attr->attach_btf_id;
|
||||
attr.attach_prog_fd = load_attr->attach_prog_fd;
|
||||
else
|
||||
attr.attach_btf_obj_fd = load_attr->attach_btf_obj_fd;
|
||||
attr.attach_btf_id = load_attr->attach_btf_id;
|
||||
|
||||
attr.prog_ifindex = load_attr->prog_ifindex;
|
||||
attr.kern_version = load_attr->kern_version;
|
||||
|
||||
attr.insn_cnt = (__u32)load_attr->insn_cnt;
|
||||
} else {
|
||||
attr.prog_ifindex = load_attr->prog_ifindex;
|
||||
attr.kern_version = load_attr->kern_version;
|
||||
}
|
||||
attr.insn_cnt = (__u32)load_attr->insns_cnt;
|
||||
attr.insns = ptr_to_u64(load_attr->insns);
|
||||
attr.license = ptr_to_u64(load_attr->license);
|
||||
|
||||
attr.log_level = load_attr->log_level;
|
||||
if (attr.log_level) {
|
||||
attr.log_buf = ptr_to_u64(load_attr->log_buf);
|
||||
attr.log_size = load_attr->log_buf_sz;
|
||||
attr.log_level = log_level;
|
||||
if (log_level) {
|
||||
attr.log_buf = ptr_to_u64(log_buf);
|
||||
attr.log_size = log_buf_sz;
|
||||
} else {
|
||||
attr.log_buf = ptr_to_u64(NULL);
|
||||
attr.log_size = 0;
|
||||
}
|
||||
|
||||
attr.prog_btf_fd = load_attr->prog_btf_fd;
|
||||
attr.prog_flags = load_attr->prog_flags;
|
||||
|
||||
attr.func_info_rec_size = load_attr->func_info_rec_size;
|
||||
attr.func_info_cnt = load_attr->func_info_cnt;
|
||||
attr.func_info = ptr_to_u64(load_attr->func_info);
|
||||
|
||||
attr.line_info_rec_size = load_attr->line_info_rec_size;
|
||||
attr.line_info_cnt = load_attr->line_info_cnt;
|
||||
attr.line_info = ptr_to_u64(load_attr->line_info);
|
||||
|
||||
if (load_attr->name)
|
||||
memcpy(attr.prog_name, load_attr->name,
|
||||
min(strlen(load_attr->name), (size_t)BPF_OBJ_NAME_LEN - 1));
|
||||
min(strlen(load_attr->name), BPF_OBJ_NAME_LEN - 1));
|
||||
attr.prog_flags = load_attr->prog_flags;
|
||||
|
||||
fd = sys_bpf_prog_load(&attr, sizeof(attr));
|
||||
if (fd >= 0)
|
||||
@@ -303,19 +309,19 @@ int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr)
|
||||
}
|
||||
|
||||
fd = sys_bpf_prog_load(&attr, sizeof(attr));
|
||||
|
||||
if (fd >= 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (load_attr->log_level || !load_attr->log_buf)
|
||||
if (log_level || !log_buf)
|
||||
goto done;
|
||||
|
||||
/* Try again with log */
|
||||
attr.log_buf = ptr_to_u64(load_attr->log_buf);
|
||||
attr.log_size = load_attr->log_buf_sz;
|
||||
attr.log_buf = ptr_to_u64(log_buf);
|
||||
attr.log_size = log_buf_sz;
|
||||
attr.log_level = 1;
|
||||
load_attr->log_buf[0] = 0;
|
||||
|
||||
log_buf[0] = 0;
|
||||
fd = sys_bpf_prog_load(&attr, sizeof(attr));
|
||||
done:
|
||||
free(finfo);
|
||||
@@ -323,49 +329,6 @@ done:
|
||||
return fd;
|
||||
}
|
||||
|
||||
int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr,
|
||||
char *log_buf, size_t log_buf_sz)
|
||||
{
|
||||
struct bpf_prog_load_params p = {};
|
||||
|
||||
if (!load_attr || !log_buf != !log_buf_sz)
|
||||
return -EINVAL;
|
||||
|
||||
p.prog_type = load_attr->prog_type;
|
||||
p.expected_attach_type = load_attr->expected_attach_type;
|
||||
switch (p.prog_type) {
|
||||
case BPF_PROG_TYPE_STRUCT_OPS:
|
||||
case BPF_PROG_TYPE_LSM:
|
||||
p.attach_btf_id = load_attr->attach_btf_id;
|
||||
break;
|
||||
case BPF_PROG_TYPE_TRACING:
|
||||
case BPF_PROG_TYPE_EXT:
|
||||
p.attach_btf_id = load_attr->attach_btf_id;
|
||||
p.attach_prog_fd = load_attr->attach_prog_fd;
|
||||
break;
|
||||
default:
|
||||
p.prog_ifindex = load_attr->prog_ifindex;
|
||||
p.kern_version = load_attr->kern_version;
|
||||
}
|
||||
p.insn_cnt = load_attr->insns_cnt;
|
||||
p.insns = load_attr->insns;
|
||||
p.license = load_attr->license;
|
||||
p.log_level = load_attr->log_level;
|
||||
p.log_buf = log_buf;
|
||||
p.log_buf_sz = log_buf_sz;
|
||||
p.prog_btf_fd = load_attr->prog_btf_fd;
|
||||
p.func_info_rec_size = load_attr->func_info_rec_size;
|
||||
p.func_info_cnt = load_attr->func_info_cnt;
|
||||
p.func_info = load_attr->func_info;
|
||||
p.line_info_rec_size = load_attr->line_info_rec_size;
|
||||
p.line_info_cnt = load_attr->line_info_cnt;
|
||||
p.line_info = load_attr->line_info;
|
||||
p.name = load_attr->name;
|
||||
p.prog_flags = load_attr->prog_flags;
|
||||
|
||||
return libbpf__bpf_prog_load(&p);
|
||||
}
|
||||
|
||||
int bpf_load_program(enum bpf_prog_type type, const struct bpf_insn *insns,
|
||||
size_t insns_cnt, const char *license,
|
||||
__u32 kern_version, char *log_buf,
|
||||
@@ -626,45 +589,19 @@ int bpf_link_create(int prog_fd, int target_fd,
|
||||
enum bpf_attach_type attach_type,
|
||||
const struct bpf_link_create_opts *opts)
|
||||
{
|
||||
__u32 target_btf_id, iter_info_len;
|
||||
union bpf_attr attr;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_link_create_opts))
|
||||
return -EINVAL;
|
||||
|
||||
iter_info_len = OPTS_GET(opts, iter_info_len, 0);
|
||||
target_btf_id = OPTS_GET(opts, target_btf_id, 0);
|
||||
|
||||
if (iter_info_len && target_btf_id)
|
||||
return -EINVAL;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.link_create.prog_fd = prog_fd;
|
||||
attr.link_create.target_fd = target_fd;
|
||||
attr.link_create.attach_type = attach_type;
|
||||
attr.link_create.flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
if (iter_info_len) {
|
||||
attr.link_create.iter_info =
|
||||
ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0));
|
||||
attr.link_create.iter_info_len = iter_info_len;
|
||||
} else if (target_btf_id) {
|
||||
attr.link_create.target_btf_id = target_btf_id;
|
||||
}
|
||||
|
||||
return sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_link_detach(int link_fd)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.link_detach.link_fd = link_fd;
|
||||
|
||||
return sys_bpf(BPF_LINK_DETACH, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_link_update(int link_fd, int new_prog_fd,
|
||||
const struct bpf_link_update_opts *opts)
|
||||
{
|
||||
@@ -764,37 +701,6 @@ int bpf_prog_test_run_xattr(struct bpf_prog_test_run_attr *test_attr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bpf_prog_test_run_opts(int prog_fd, struct bpf_test_run_opts *opts)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
int ret;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_test_run_opts))
|
||||
return -EINVAL;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.test.prog_fd = prog_fd;
|
||||
attr.test.cpu = OPTS_GET(opts, cpu, 0);
|
||||
attr.test.flags = OPTS_GET(opts, flags, 0);
|
||||
attr.test.repeat = OPTS_GET(opts, repeat, 0);
|
||||
attr.test.duration = OPTS_GET(opts, duration, 0);
|
||||
attr.test.ctx_size_in = OPTS_GET(opts, ctx_size_in, 0);
|
||||
attr.test.ctx_size_out = OPTS_GET(opts, ctx_size_out, 0);
|
||||
attr.test.data_size_in = OPTS_GET(opts, data_size_in, 0);
|
||||
attr.test.data_size_out = OPTS_GET(opts, data_size_out, 0);
|
||||
attr.test.ctx_in = ptr_to_u64(OPTS_GET(opts, ctx_in, NULL));
|
||||
attr.test.ctx_out = ptr_to_u64(OPTS_GET(opts, ctx_out, NULL));
|
||||
attr.test.data_in = ptr_to_u64(OPTS_GET(opts, data_in, NULL));
|
||||
attr.test.data_out = ptr_to_u64(OPTS_GET(opts, data_out, NULL));
|
||||
|
||||
ret = sys_bpf(BPF_PROG_TEST_RUN, &attr, sizeof(attr));
|
||||
OPTS_SET(opts, data_size_out, attr.test.data_size_out);
|
||||
OPTS_SET(opts, ctx_size_out, attr.test.ctx_size_out);
|
||||
OPTS_SET(opts, duration, attr.test.duration);
|
||||
OPTS_SET(opts, retval, attr.test.retval);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bpf_obj_get_next_id(__u32 start_id, __u32 *next_id, int cmd)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
@@ -898,7 +804,7 @@ int bpf_raw_tracepoint_open(const char *name, int prog_fd)
|
||||
return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
|
||||
int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
|
||||
bool do_log)
|
||||
{
|
||||
union bpf_attr attr = {};
|
||||
@@ -955,19 +861,3 @@ int bpf_enable_stats(enum bpf_stats_type type)
|
||||
|
||||
return sys_bpf(BPF_ENABLE_STATS, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
int bpf_prog_bind_map(int prog_fd, int map_fd,
|
||||
const struct bpf_prog_bind_opts *opts)
|
||||
{
|
||||
union bpf_attr attr;
|
||||
|
||||
if (!OPTS_VALID(opts, bpf_prog_bind_opts))
|
||||
return -EINVAL;
|
||||
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.prog_bind_map.prog_fd = prog_fd;
|
||||
attr.prog_bind_map.map_fd = map_fd;
|
||||
attr.prog_bind_map.flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
return sys_bpf(BPF_PROG_BIND_MAP, &attr, sizeof(attr));
|
||||
}
|
||||
|
||||
45
src/bpf.h
45
src/bpf.h
@@ -168,22 +168,15 @@ LIBBPF_API int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type);
|
||||
LIBBPF_API int bpf_prog_detach2(int prog_fd, int attachable_fd,
|
||||
enum bpf_attach_type type);
|
||||
|
||||
union bpf_iter_link_info; /* defined in up-to-date linux/bpf.h */
|
||||
struct bpf_link_create_opts {
|
||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||
__u32 flags;
|
||||
union bpf_iter_link_info *iter_info;
|
||||
__u32 iter_info_len;
|
||||
__u32 target_btf_id;
|
||||
};
|
||||
#define bpf_link_create_opts__last_field target_btf_id
|
||||
#define bpf_link_create_opts__last_field sz
|
||||
|
||||
LIBBPF_API int bpf_link_create(int prog_fd, int target_fd,
|
||||
enum bpf_attach_type attach_type,
|
||||
const struct bpf_link_create_opts *opts);
|
||||
|
||||
LIBBPF_API int bpf_link_detach(int link_fd);
|
||||
|
||||
struct bpf_link_update_opts {
|
||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||
__u32 flags; /* extra flags */
|
||||
@@ -235,7 +228,7 @@ LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type,
|
||||
__u32 query_flags, __u32 *attach_flags,
|
||||
__u32 *prog_ids, __u32 *prog_cnt);
|
||||
LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
|
||||
LIBBPF_API int bpf_load_btf(const void *btf, __u32 btf_size, char *log_buf,
|
||||
LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
|
||||
__u32 log_buf_size, bool do_log);
|
||||
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
|
||||
__u32 *buf_len, __u32 *prog_id, __u32 *fd_type,
|
||||
@@ -244,40 +237,6 @@ LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
|
||||
enum bpf_stats_type; /* defined in up-to-date linux/bpf.h */
|
||||
LIBBPF_API int bpf_enable_stats(enum bpf_stats_type type);
|
||||
|
||||
struct bpf_prog_bind_opts {
|
||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||
__u32 flags;
|
||||
};
|
||||
#define bpf_prog_bind_opts__last_field flags
|
||||
|
||||
LIBBPF_API int bpf_prog_bind_map(int prog_fd, int map_fd,
|
||||
const struct bpf_prog_bind_opts *opts);
|
||||
|
||||
struct bpf_test_run_opts {
|
||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||
const void *data_in; /* optional */
|
||||
void *data_out; /* optional */
|
||||
__u32 data_size_in;
|
||||
__u32 data_size_out; /* in: max length of data_out
|
||||
* out: length of data_out
|
||||
*/
|
||||
const void *ctx_in; /* optional */
|
||||
void *ctx_out; /* optional */
|
||||
__u32 ctx_size_in;
|
||||
__u32 ctx_size_out; /* in: max length of ctx_out
|
||||
* out: length of cxt_out
|
||||
*/
|
||||
__u32 retval; /* out: return code of the BPF program */
|
||||
int repeat;
|
||||
__u32 duration; /* out: average per repetition in ns */
|
||||
__u32 flags;
|
||||
__u32 cpu;
|
||||
};
|
||||
#define bpf_test_run_opts__last_field cpu
|
||||
|
||||
LIBBPF_API int bpf_prog_test_run_opts(int prog_fd,
|
||||
struct bpf_test_run_opts *opts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -19,52 +19,32 @@ enum bpf_field_info_kind {
|
||||
BPF_FIELD_RSHIFT_U64 = 5,
|
||||
};
|
||||
|
||||
/* second argument to __builtin_btf_type_id() built-in */
|
||||
enum bpf_type_id_kind {
|
||||
BPF_TYPE_ID_LOCAL = 0, /* BTF type ID in local program */
|
||||
BPF_TYPE_ID_TARGET = 1, /* BTF type ID in target kernel */
|
||||
};
|
||||
|
||||
/* second argument to __builtin_preserve_type_info() built-in */
|
||||
enum bpf_type_info_kind {
|
||||
BPF_TYPE_EXISTS = 0, /* type existence in target kernel */
|
||||
BPF_TYPE_SIZE = 1, /* type size in target kernel */
|
||||
};
|
||||
|
||||
/* second argument to __builtin_preserve_enum_value() built-in */
|
||||
enum bpf_enum_value_kind {
|
||||
BPF_ENUMVAL_EXISTS = 0, /* enum value existence in kernel */
|
||||
BPF_ENUMVAL_VALUE = 1, /* enum value value relocation */
|
||||
};
|
||||
|
||||
#define __CORE_RELO(src, field, info) \
|
||||
__builtin_preserve_field_info((src)->field, BPF_FIELD_##info)
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
|
||||
bpf_probe_read_kernel( \
|
||||
(void *)dst, \
|
||||
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||
bpf_probe_read((void *)dst, \
|
||||
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||
#else
|
||||
/* semantics of LSHIFT_64 assumes loading values into low-ordered bytes, so
|
||||
* for big-endian we need to adjust destination pointer accordingly, based on
|
||||
* field byte size
|
||||
*/
|
||||
#define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \
|
||||
bpf_probe_read_kernel( \
|
||||
(void *)dst + (8 - __CORE_RELO(src, fld, BYTE_SIZE)), \
|
||||
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||
bpf_probe_read((void *)dst + (8 - __CORE_RELO(src, fld, BYTE_SIZE)), \
|
||||
__CORE_RELO(src, fld, BYTE_SIZE), \
|
||||
(const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Extract bitfield, identified by s->field, and return its value as u64.
|
||||
* All this is done in relocatable manner, so bitfield changes such as
|
||||
* signedness, bit size, offset changes, this will be handled automatically.
|
||||
* This version of macro is using bpf_probe_read_kernel() to read underlying
|
||||
* integer storage. Macro functions as an expression and its return type is
|
||||
* bpf_probe_read_kernel()'s return value: 0, on success, <0 on error.
|
||||
* This version of macro is using bpf_probe_read() to read underlying integer
|
||||
* storage. Macro functions as an expression and its return type is
|
||||
* bpf_probe_read()'s return value: 0, on success, <0 on error.
|
||||
*/
|
||||
#define BPF_CORE_READ_BITFIELD_PROBED(s, field) ({ \
|
||||
unsigned long long val = 0; \
|
||||
@@ -88,19 +68,11 @@ enum bpf_enum_value_kind {
|
||||
const void *p = (const void *)s + __CORE_RELO(s, field, BYTE_OFFSET); \
|
||||
unsigned long long val; \
|
||||
\
|
||||
/* This is a so-called barrier_var() operation that makes specified \
|
||||
* variable "a black box" for optimizing compiler. \
|
||||
* It forces compiler to perform BYTE_OFFSET relocation on p and use \
|
||||
* its calculated value in the switch below, instead of applying \
|
||||
* the same relocation 4 times for each individual memory load. \
|
||||
*/ \
|
||||
asm volatile("" : "=r"(p) : "0"(p)); \
|
||||
\
|
||||
switch (__CORE_RELO(s, field, BYTE_SIZE)) { \
|
||||
case 1: val = *(const unsigned char *)p; break; \
|
||||
case 2: val = *(const unsigned short *)p; break; \
|
||||
case 4: val = *(const unsigned int *)p; break; \
|
||||
case 8: val = *(const unsigned long long *)p; break; \
|
||||
case 1: val = *(const unsigned char *)p; \
|
||||
case 2: val = *(const unsigned short *)p; \
|
||||
case 4: val = *(const unsigned int *)p; \
|
||||
case 8: val = *(const unsigned long long *)p; \
|
||||
} \
|
||||
val <<= __CORE_RELO(s, field, LSHIFT_U64); \
|
||||
if (__CORE_RELO(s, field, SIGNED)) \
|
||||
@@ -120,75 +92,15 @@ enum bpf_enum_value_kind {
|
||||
__builtin_preserve_field_info(field, BPF_FIELD_EXISTS)
|
||||
|
||||
/*
|
||||
* Convenience macro to get the byte size of a field. Works for integers,
|
||||
* Convenience macro to get byte size of a field. Works for integers,
|
||||
* struct/unions, pointers, arrays, and enums.
|
||||
*/
|
||||
#define bpf_core_field_size(field) \
|
||||
__builtin_preserve_field_info(field, BPF_FIELD_BYTE_SIZE)
|
||||
|
||||
/*
|
||||
* Convenience macro to get BTF type ID of a specified type, using a local BTF
|
||||
* information. Return 32-bit unsigned integer with type ID from program's own
|
||||
* BTF. Always succeeds.
|
||||
*/
|
||||
#define bpf_core_type_id_local(type) \
|
||||
__builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_LOCAL)
|
||||
|
||||
/*
|
||||
* Convenience macro to get BTF type ID of a target kernel's type that matches
|
||||
* specified local type.
|
||||
* Returns:
|
||||
* - valid 32-bit unsigned type ID in kernel BTF;
|
||||
* - 0, if no matching type was found in a target kernel BTF.
|
||||
*/
|
||||
#define bpf_core_type_id_kernel(type) \
|
||||
__builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_TARGET)
|
||||
|
||||
/*
|
||||
* Convenience macro to check that provided named type
|
||||
* (struct/union/enum/typedef) exists in a target kernel.
|
||||
* Returns:
|
||||
* 1, if such type is present in target kernel's BTF;
|
||||
* 0, if no matching type is found.
|
||||
*/
|
||||
#define bpf_core_type_exists(type) \
|
||||
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_EXISTS)
|
||||
|
||||
/*
|
||||
* Convenience macro to get the byte size of a provided named type
|
||||
* (struct/union/enum/typedef) in a target kernel.
|
||||
* Returns:
|
||||
* >= 0 size (in bytes), if type is present in target kernel's BTF;
|
||||
* 0, if no matching type is found.
|
||||
*/
|
||||
#define bpf_core_type_size(type) \
|
||||
__builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_SIZE)
|
||||
|
||||
/*
|
||||
* Convenience macro to check that provided enumerator value is defined in
|
||||
* a target kernel.
|
||||
* Returns:
|
||||
* 1, if specified enum type and its enumerator value are present in target
|
||||
* kernel's BTF;
|
||||
* 0, if no matching enum and/or enum value within that enum is found.
|
||||
*/
|
||||
#define bpf_core_enum_value_exists(enum_type, enum_value) \
|
||||
__builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_EXISTS)
|
||||
|
||||
/*
|
||||
* Convenience macro to get the integer value of an enumerator value in
|
||||
* a target kernel.
|
||||
* Returns:
|
||||
* 64-bit value, if specified enum type and its enumerator value are
|
||||
* present in target kernel's BTF;
|
||||
* 0, if no matching enum and/or enum value within that enum is found.
|
||||
*/
|
||||
#define bpf_core_enum_value(enum_type, enum_value) \
|
||||
__builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_VALUE)
|
||||
|
||||
/*
|
||||
* bpf_core_read() abstracts away bpf_probe_read_kernel() call and captures
|
||||
* offset relocation for source address using __builtin_preserve_access_index()
|
||||
* bpf_core_read() abstracts away bpf_probe_read() call and captures offset
|
||||
* relocation for source address using __builtin_preserve_access_index()
|
||||
* built-in, provided by Clang.
|
||||
*
|
||||
* __builtin_preserve_access_index() takes as an argument an expression of
|
||||
@@ -203,22 +115,17 @@ enum bpf_enum_value_kind {
|
||||
* (local) BTF, used to record relocation.
|
||||
*/
|
||||
#define bpf_core_read(dst, sz, src) \
|
||||
bpf_probe_read_kernel(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||
bpf_probe_read(dst, sz, \
|
||||
(const void *)__builtin_preserve_access_index(src))
|
||||
|
||||
/* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use. */
|
||||
#define bpf_core_read_user(dst, sz, src) \
|
||||
bpf_probe_read_user(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||
/*
|
||||
* bpf_core_read_str() is a thin wrapper around bpf_probe_read_str()
|
||||
* additionally emitting BPF CO-RE field relocation for specified source
|
||||
* argument.
|
||||
*/
|
||||
#define bpf_core_read_str(dst, sz, src) \
|
||||
bpf_probe_read_kernel_str(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||
|
||||
/* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use. */
|
||||
#define bpf_core_read_user_str(dst, sz, src) \
|
||||
bpf_probe_read_user_str(dst, sz, (const void *)__builtin_preserve_access_index(src))
|
||||
bpf_probe_read_str(dst, sz, \
|
||||
(const void *)__builtin_preserve_access_index(src))
|
||||
|
||||
#define ___concat(a, b) a ## b
|
||||
#define ___apply(fn, n) ___concat(fn, n)
|
||||
@@ -277,29 +184,30 @@ enum bpf_enum_value_kind {
|
||||
read_fn((void *)(dst), sizeof(*(dst)), &((src_type)(src))->accessor)
|
||||
|
||||
/* "recursively" read a sequence of inner pointers using local __t var */
|
||||
#define ___rd_first(fn, src, a) ___read(fn, &__t, ___type(src), src, a);
|
||||
#define ___rd_last(fn, ...) \
|
||||
___read(fn, &__t, ___type(___nolast(__VA_ARGS__)), __t, ___last(__VA_ARGS__));
|
||||
#define ___rd_p1(fn, ...) const void *__t; ___rd_first(fn, __VA_ARGS__)
|
||||
#define ___rd_p2(fn, ...) ___rd_p1(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p3(fn, ...) ___rd_p2(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p4(fn, ...) ___rd_p3(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p5(fn, ...) ___rd_p4(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p6(fn, ...) ___rd_p5(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p7(fn, ...) ___rd_p6(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p8(fn, ...) ___rd_p7(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___rd_p9(fn, ...) ___rd_p8(fn, ___nolast(__VA_ARGS__)) ___rd_last(fn, __VA_ARGS__)
|
||||
#define ___read_ptrs(fn, src, ...) \
|
||||
___apply(___rd_p, ___narg(__VA_ARGS__))(fn, src, __VA_ARGS__)
|
||||
#define ___rd_first(src, a) ___read(bpf_core_read, &__t, ___type(src), src, a);
|
||||
#define ___rd_last(...) \
|
||||
___read(bpf_core_read, &__t, \
|
||||
___type(___nolast(__VA_ARGS__)), __t, ___last(__VA_ARGS__));
|
||||
#define ___rd_p1(...) const void *__t; ___rd_first(__VA_ARGS__)
|
||||
#define ___rd_p2(...) ___rd_p1(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p3(...) ___rd_p2(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p4(...) ___rd_p3(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p5(...) ___rd_p4(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p6(...) ___rd_p5(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p7(...) ___rd_p6(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p8(...) ___rd_p7(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___rd_p9(...) ___rd_p8(___nolast(__VA_ARGS__)) ___rd_last(__VA_ARGS__)
|
||||
#define ___read_ptrs(src, ...) \
|
||||
___apply(___rd_p, ___narg(__VA_ARGS__))(src, __VA_ARGS__)
|
||||
|
||||
#define ___core_read0(fn, fn_ptr, dst, src, a) \
|
||||
#define ___core_read0(fn, dst, src, a) \
|
||||
___read(fn, dst, ___type(src), src, a);
|
||||
#define ___core_readN(fn, fn_ptr, dst, src, ...) \
|
||||
___read_ptrs(fn_ptr, src, ___nolast(__VA_ARGS__)) \
|
||||
#define ___core_readN(fn, dst, src, ...) \
|
||||
___read_ptrs(src, ___nolast(__VA_ARGS__)) \
|
||||
___read(fn, dst, ___type(src, ___nolast(__VA_ARGS__)), __t, \
|
||||
___last(__VA_ARGS__));
|
||||
#define ___core_read(fn, fn_ptr, dst, src, a, ...) \
|
||||
___apply(___core_read, ___empty(__VA_ARGS__))(fn, fn_ptr, dst, \
|
||||
#define ___core_read(fn, dst, src, a, ...) \
|
||||
___apply(___core_read, ___empty(__VA_ARGS__))(fn, dst, \
|
||||
src, a, ##__VA_ARGS__)
|
||||
|
||||
/*
|
||||
@@ -307,73 +215,20 @@ enum bpf_enum_value_kind {
|
||||
* BPF_CORE_READ(), in which final field is read into user-provided storage.
|
||||
* See BPF_CORE_READ() below for more details on general usage.
|
||||
*/
|
||||
#define BPF_CORE_READ_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_core_read, bpf_core_read, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/*
|
||||
* Variant of BPF_CORE_READ_INTO() for reading from user-space memory.
|
||||
*
|
||||
* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use.
|
||||
*/
|
||||
#define BPF_CORE_READ_USER_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_core_read_user, bpf_core_read_user, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/* Non-CO-RE variant of BPF_CORE_READ_INTO() */
|
||||
#define BPF_PROBE_READ_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_probe_read, bpf_probe_read, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/* Non-CO-RE variant of BPF_CORE_READ_USER_INTO().
|
||||
*
|
||||
* As no CO-RE relocations are emitted, source types can be arbitrary and are
|
||||
* not restricted to kernel types only.
|
||||
*/
|
||||
#define BPF_PROBE_READ_USER_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_probe_read_user, bpf_probe_read_user, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
#define BPF_CORE_READ_INTO(dst, src, a, ...) \
|
||||
({ \
|
||||
___core_read(bpf_core_read, dst, src, a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/*
|
||||
* BPF_CORE_READ_STR_INTO() does same "pointer chasing" as
|
||||
* BPF_CORE_READ() for intermediate pointers, but then executes (and returns
|
||||
* corresponding error code) bpf_core_read_str() for final string read.
|
||||
*/
|
||||
#define BPF_CORE_READ_STR_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_core_read_str, bpf_core_read, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/*
|
||||
* Variant of BPF_CORE_READ_STR_INTO() for reading from user-space memory.
|
||||
*
|
||||
* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use.
|
||||
*/
|
||||
#define BPF_CORE_READ_USER_STR_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_core_read_user_str, bpf_core_read_user, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/* Non-CO-RE variant of BPF_CORE_READ_STR_INTO() */
|
||||
#define BPF_PROBE_READ_STR_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_probe_read_str, bpf_probe_read, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/*
|
||||
* Non-CO-RE variant of BPF_CORE_READ_USER_STR_INTO().
|
||||
*
|
||||
* As no CO-RE relocations are emitted, source types can be arbitrary and are
|
||||
* not restricted to kernel types only.
|
||||
*/
|
||||
#define BPF_PROBE_READ_USER_STR_INTO(dst, src, a, ...) ({ \
|
||||
___core_read(bpf_probe_read_user_str, bpf_probe_read_user, \
|
||||
dst, (src), a, ##__VA_ARGS__) \
|
||||
})
|
||||
#define BPF_CORE_READ_STR_INTO(dst, src, a, ...) \
|
||||
({ \
|
||||
___core_read(bpf_core_read_str, dst, src, a, ##__VA_ARGS__) \
|
||||
})
|
||||
|
||||
/*
|
||||
* BPF_CORE_READ() is used to simplify BPF CO-RE relocatable read, especially
|
||||
@@ -384,61 +239,25 @@ enum bpf_enum_value_kind {
|
||||
* int x = BPF_CORE_READ(s, a.b.c, d.e, f, g);
|
||||
*
|
||||
* BPF_CORE_READ will decompose above statement into 4 bpf_core_read (BPF
|
||||
* CO-RE relocatable bpf_probe_read_kernel() wrapper) calls, logically
|
||||
* equivalent to:
|
||||
* CO-RE relocatable bpf_probe_read() wrapper) calls, logically equivalent to:
|
||||
* 1. const void *__t = s->a.b.c;
|
||||
* 2. __t = __t->d.e;
|
||||
* 3. __t = __t->f;
|
||||
* 4. return __t->g;
|
||||
*
|
||||
* Equivalence is logical, because there is a heavy type casting/preservation
|
||||
* involved, as well as all the reads are happening through
|
||||
* bpf_probe_read_kernel() calls using __builtin_preserve_access_index() to
|
||||
* emit CO-RE relocations.
|
||||
* involved, as well as all the reads are happening through bpf_probe_read()
|
||||
* calls using __builtin_preserve_access_index() to emit CO-RE relocations.
|
||||
*
|
||||
* N.B. Only up to 9 "field accessors" are supported, which should be more
|
||||
* than enough for any practical purpose.
|
||||
*/
|
||||
#define BPF_CORE_READ(src, a, ...) ({ \
|
||||
___type((src), a, ##__VA_ARGS__) __r; \
|
||||
BPF_CORE_READ_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||
__r; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Variant of BPF_CORE_READ() for reading from user-space memory.
|
||||
*
|
||||
* NOTE: all the source types involved are still *kernel types* and need to
|
||||
* exist in kernel (or kernel module) BTF, otherwise CO-RE relocation will
|
||||
* fail. Custom user types are not relocatable with CO-RE.
|
||||
* The typical situation in which BPF_CORE_READ_USER() might be used is to
|
||||
* read kernel UAPI types from the user-space memory passed in as a syscall
|
||||
* input argument.
|
||||
*/
|
||||
#define BPF_CORE_READ_USER(src, a, ...) ({ \
|
||||
___type((src), a, ##__VA_ARGS__) __r; \
|
||||
BPF_CORE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||
__r; \
|
||||
})
|
||||
|
||||
/* Non-CO-RE variant of BPF_CORE_READ() */
|
||||
#define BPF_PROBE_READ(src, a, ...) ({ \
|
||||
___type((src), a, ##__VA_ARGS__) __r; \
|
||||
BPF_PROBE_READ_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||
__r; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Non-CO-RE variant of BPF_CORE_READ_USER().
|
||||
*
|
||||
* As no CO-RE relocations are emitted, source types can be arbitrary and are
|
||||
* not restricted to kernel types only.
|
||||
*/
|
||||
#define BPF_PROBE_READ_USER(src, a, ...) ({ \
|
||||
___type((src), a, ##__VA_ARGS__) __r; \
|
||||
BPF_PROBE_READ_USER_INTO(&__r, (src), a, ##__VA_ARGS__); \
|
||||
__r; \
|
||||
})
|
||||
#define BPF_CORE_READ(src, a, ...) \
|
||||
({ \
|
||||
___type(src, a, ##__VA_ARGS__) __r; \
|
||||
BPF_CORE_READ_INTO(&__r, src, a, ##__VA_ARGS__); \
|
||||
__r; \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,35 +2,8 @@
|
||||
#ifndef __BPF_ENDIAN__
|
||||
#define __BPF_ENDIAN__
|
||||
|
||||
/*
|
||||
* Isolate byte #n and put it into byte #m, for __u##b type.
|
||||
* E.g., moving byte #6 (nnnnnnnn) into byte #1 (mmmmmmmm) for __u64:
|
||||
* 1) xxxxxxxx nnnnnnnn xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx mmmmmmmm xxxxxxxx
|
||||
* 2) nnnnnnnn xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx mmmmmmmm xxxxxxxx 00000000
|
||||
* 3) 00000000 00000000 00000000 00000000 00000000 00000000 00000000 nnnnnnnn
|
||||
* 4) 00000000 00000000 00000000 00000000 00000000 00000000 nnnnnnnn 00000000
|
||||
*/
|
||||
#define ___bpf_mvb(x, b, n, m) ((__u##b)(x) << (b-(n+1)*8) >> (b-8) << (m*8))
|
||||
|
||||
#define ___bpf_swab16(x) ((__u16)( \
|
||||
___bpf_mvb(x, 16, 0, 1) | \
|
||||
___bpf_mvb(x, 16, 1, 0)))
|
||||
|
||||
#define ___bpf_swab32(x) ((__u32)( \
|
||||
___bpf_mvb(x, 32, 0, 3) | \
|
||||
___bpf_mvb(x, 32, 1, 2) | \
|
||||
___bpf_mvb(x, 32, 2, 1) | \
|
||||
___bpf_mvb(x, 32, 3, 0)))
|
||||
|
||||
#define ___bpf_swab64(x) ((__u64)( \
|
||||
___bpf_mvb(x, 64, 0, 7) | \
|
||||
___bpf_mvb(x, 64, 1, 6) | \
|
||||
___bpf_mvb(x, 64, 2, 5) | \
|
||||
___bpf_mvb(x, 64, 3, 4) | \
|
||||
___bpf_mvb(x, 64, 4, 3) | \
|
||||
___bpf_mvb(x, 64, 5, 2) | \
|
||||
___bpf_mvb(x, 64, 6, 1) | \
|
||||
___bpf_mvb(x, 64, 7, 0)))
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/swab.h>
|
||||
|
||||
/* LLVM's BPF target selects the endianness of the CPU
|
||||
* it compiles on, or the user specifies (bpfel/bpfeb),
|
||||
@@ -50,16 +23,16 @@
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define __bpf_ntohs(x) __builtin_bswap16(x)
|
||||
# define __bpf_htons(x) __builtin_bswap16(x)
|
||||
# define __bpf_constant_ntohs(x) ___bpf_swab16(x)
|
||||
# define __bpf_constant_htons(x) ___bpf_swab16(x)
|
||||
# define __bpf_constant_ntohs(x) ___constant_swab16(x)
|
||||
# define __bpf_constant_htons(x) ___constant_swab16(x)
|
||||
# define __bpf_ntohl(x) __builtin_bswap32(x)
|
||||
# define __bpf_htonl(x) __builtin_bswap32(x)
|
||||
# define __bpf_constant_ntohl(x) ___bpf_swab32(x)
|
||||
# define __bpf_constant_htonl(x) ___bpf_swab32(x)
|
||||
# define __bpf_constant_ntohl(x) ___constant_swab32(x)
|
||||
# define __bpf_constant_htonl(x) ___constant_swab32(x)
|
||||
# define __bpf_be64_to_cpu(x) __builtin_bswap64(x)
|
||||
# define __bpf_cpu_to_be64(x) __builtin_bswap64(x)
|
||||
# define __bpf_constant_be64_to_cpu(x) ___bpf_swab64(x)
|
||||
# define __bpf_constant_cpu_to_be64(x) ___bpf_swab64(x)
|
||||
# define __bpf_constant_be64_to_cpu(x) ___constant_swab64(x)
|
||||
# define __bpf_constant_cpu_to_be64(x) ___constant_swab64(x)
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
# define __bpf_ntohs(x) (x)
|
||||
# define __bpf_htons(x) (x)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,55 +25,22 @@
|
||||
/*
|
||||
* Helper macro to place programs, maps, license in
|
||||
* different sections in elf_bpf file. Section names
|
||||
* are interpreted by libbpf depending on the context (BPF programs, BPF maps,
|
||||
* extern variables, etc).
|
||||
* To allow use of SEC() with externs (e.g., for extern .maps declarations),
|
||||
* make sure __attribute__((unused)) doesn't trigger compilation warning.
|
||||
* are interpreted by elf_bpf loader
|
||||
*/
|
||||
#define SEC(name) \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wignored-attributes\"") \
|
||||
__attribute__((section(name), used)) \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
#define SEC(NAME) __attribute__((section(NAME), used))
|
||||
|
||||
/* Avoid 'linux/stddef.h' definition of '__always_inline'. */
|
||||
#undef __always_inline
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
|
||||
#ifndef __noinline
|
||||
#define __noinline __attribute__((noinline))
|
||||
#ifndef __always_inline
|
||||
#define __always_inline __attribute__((always_inline))
|
||||
#endif
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use __hidden attribute to mark a non-static BPF subprogram effectively
|
||||
* static for BPF verifier's verification algorithm purposes, allowing more
|
||||
* extensive and permissive BPF verification process, taking into account
|
||||
* subprogram's caller context.
|
||||
*/
|
||||
#define __hidden __attribute__((visibility("hidden")))
|
||||
|
||||
/* When utilizing vmlinux.h with BPF CO-RE, user BPF programs can't include
|
||||
* any system-level headers (such as stddef.h, linux/version.h, etc), and
|
||||
* commonly-used macros like NULL and KERNEL_VERSION aren't available through
|
||||
* vmlinux.h. This just adds unnecessary hurdles and forces users to re-define
|
||||
* them on their own. So as a convenience, provide such definitions here.
|
||||
*/
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef KERNEL_VERSION
|
||||
#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper macros to manipulate data structures
|
||||
* Helper macro to manipulate data structures
|
||||
*/
|
||||
#ifndef offsetof
|
||||
#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
|
||||
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
#ifndef container_of
|
||||
#define container_of(ptr, type, member) \
|
||||
@@ -83,54 +50,6 @@
|
||||
})
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper macro to throw a compilation error if __bpf_unreachable() gets
|
||||
* built into the resulting code. This works given BPF back end does not
|
||||
* implement __builtin_trap(). This is useful to assert that certain paths
|
||||
* of the program code are never used and hence eliminated by the compiler.
|
||||
*
|
||||
* For example, consider a switch statement that covers known cases used by
|
||||
* the program. __bpf_unreachable() can then reside in the default case. If
|
||||
* the program gets extended such that a case is not covered in the switch
|
||||
* statement, then it will throw a build error due to the default case not
|
||||
* being compiled out.
|
||||
*/
|
||||
#ifndef __bpf_unreachable
|
||||
# define __bpf_unreachable() __builtin_trap()
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper function to perform a tail call with a constant/immediate map slot.
|
||||
*/
|
||||
#if __clang_major__ >= 8 && defined(__bpf__)
|
||||
static __always_inline void
|
||||
bpf_tail_call_static(void *ctx, const void *map, const __u32 slot)
|
||||
{
|
||||
if (!__builtin_constant_p(slot))
|
||||
__bpf_unreachable();
|
||||
|
||||
/*
|
||||
* Provide a hard guarantee that LLVM won't optimize setting r2 (map
|
||||
* pointer) and r3 (constant map index) from _different paths_ ending
|
||||
* up at the _same_ call insn as otherwise we won't be able to use the
|
||||
* jmpq/nopl retpoline-free patching by the x86-64 JIT in the kernel
|
||||
* given they mismatch. See also d2e4c1e6c294 ("bpf: Constant map key
|
||||
* tracking for prog array pokes") for details on verifier tracking.
|
||||
*
|
||||
* Note on clobber list: we need to stay in-line with BPF calling
|
||||
* convention, so even if we don't end up using r0, r4, r5, we need
|
||||
* to mark them as clobber so that LLVM doesn't end up using them
|
||||
* before / after the call.
|
||||
*/
|
||||
asm volatile("r1 = %[ctx]\n\t"
|
||||
"r2 = %[map]\n\t"
|
||||
"r3 = %[slot]\n\t"
|
||||
"call 12"
|
||||
:: [ctx]"r"(ctx), [map]"r"(map), [slot]"i"(slot)
|
||||
: "r0", "r1", "r2", "r3", "r4", "r5");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Helper structure used by eBPF C program
|
||||
* to describe BPF map attributes to libbpf loader
|
||||
@@ -156,6 +75,5 @@ enum libbpf_tristate {
|
||||
};
|
||||
|
||||
#define __kconfig __attribute__((section(".kconfig")))
|
||||
#define __ksym __attribute__((section(".ksyms")))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "libbpf.h"
|
||||
#include "libbpf_internal.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
struct bpf_prog_linfo {
|
||||
void *raw_linfo;
|
||||
void *raw_jited_linfo;
|
||||
|
||||
@@ -215,7 +215,7 @@ struct pt_regs;
|
||||
#define PT_REGS_PARM5(x) ((x)->regs[8])
|
||||
#define PT_REGS_RET(x) ((x)->regs[31])
|
||||
#define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */
|
||||
#define PT_REGS_RC(x) ((x)->regs[2])
|
||||
#define PT_REGS_RC(x) ((x)->regs[1])
|
||||
#define PT_REGS_SP(x) ((x)->regs[29])
|
||||
#define PT_REGS_IP(x) ((x)->cp0_epc)
|
||||
|
||||
@@ -226,7 +226,7 @@ struct pt_regs;
|
||||
#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), regs[8])
|
||||
#define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), regs[31])
|
||||
#define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), regs[30])
|
||||
#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), regs[2])
|
||||
#define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), regs[1])
|
||||
#define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), regs[29])
|
||||
#define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), cp0_epc)
|
||||
|
||||
@@ -289,9 +289,9 @@ struct pt_regs;
|
||||
#define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP
|
||||
#else
|
||||
#define BPF_KPROBE_READ_RET_IP(ip, ctx) \
|
||||
({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
|
||||
({ bpf_probe_read(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
|
||||
#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) \
|
||||
({ bpf_probe_read_kernel(&(ip), sizeof(ip), \
|
||||
({ bpf_probe_read(&(ip), sizeof(ip), \
|
||||
(void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
|
||||
#endif
|
||||
|
||||
@@ -413,56 +413,20 @@ typeof(name(0)) name(struct pt_regs *ctx) \
|
||||
} \
|
||||
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
|
||||
|
||||
#define ___bpf_fill0(arr, p, x) do {} while (0)
|
||||
#define ___bpf_fill1(arr, p, x) arr[p] = x
|
||||
#define ___bpf_fill2(arr, p, x, args...) arr[p] = x; ___bpf_fill1(arr, p + 1, args)
|
||||
#define ___bpf_fill3(arr, p, x, args...) arr[p] = x; ___bpf_fill2(arr, p + 1, args)
|
||||
#define ___bpf_fill4(arr, p, x, args...) arr[p] = x; ___bpf_fill3(arr, p + 1, args)
|
||||
#define ___bpf_fill5(arr, p, x, args...) arr[p] = x; ___bpf_fill4(arr, p + 1, args)
|
||||
#define ___bpf_fill6(arr, p, x, args...) arr[p] = x; ___bpf_fill5(arr, p + 1, args)
|
||||
#define ___bpf_fill7(arr, p, x, args...) arr[p] = x; ___bpf_fill6(arr, p + 1, args)
|
||||
#define ___bpf_fill8(arr, p, x, args...) arr[p] = x; ___bpf_fill7(arr, p + 1, args)
|
||||
#define ___bpf_fill9(arr, p, x, args...) arr[p] = x; ___bpf_fill8(arr, p + 1, args)
|
||||
#define ___bpf_fill10(arr, p, x, args...) arr[p] = x; ___bpf_fill9(arr, p + 1, args)
|
||||
#define ___bpf_fill11(arr, p, x, args...) arr[p] = x; ___bpf_fill10(arr, p + 1, args)
|
||||
#define ___bpf_fill12(arr, p, x, args...) arr[p] = x; ___bpf_fill11(arr, p + 1, args)
|
||||
#define ___bpf_fill(arr, args...) \
|
||||
___bpf_apply(___bpf_fill, ___bpf_narg(args))(arr, 0, args)
|
||||
|
||||
/*
|
||||
* BPF_SEQ_PRINTF to wrap bpf_seq_printf to-be-printed values
|
||||
* in a structure.
|
||||
*/
|
||||
#define BPF_SEQ_PRINTF(seq, fmt, args...) \
|
||||
({ \
|
||||
static const char ___fmt[] = fmt; \
|
||||
unsigned long long ___param[___bpf_narg(args)]; \
|
||||
\
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||
___bpf_fill(___param, args); \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
\
|
||||
bpf_seq_printf(seq, ___fmt, sizeof(___fmt), \
|
||||
___param, sizeof(___param)); \
|
||||
})
|
||||
|
||||
/*
|
||||
* BPF_SNPRINTF wraps the bpf_snprintf helper with variadic arguments instead of
|
||||
* an array of u64.
|
||||
*/
|
||||
#define BPF_SNPRINTF(out, out_size, fmt, args...) \
|
||||
({ \
|
||||
static const char ___fmt[] = fmt; \
|
||||
unsigned long long ___param[___bpf_narg(args)]; \
|
||||
\
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||
___bpf_fill(___param, args); \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
\
|
||||
bpf_snprintf(out, out_size, ___fmt, \
|
||||
___param, sizeof(___param)); \
|
||||
})
|
||||
#define BPF_SEQ_PRINTF(seq, fmt, args...) \
|
||||
({ \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
||||
static const char ___fmt[] = fmt; \
|
||||
unsigned long long ___param[] = { args }; \
|
||||
_Pragma("GCC diagnostic pop") \
|
||||
int ___ret = bpf_seq_printf(seq, ___fmt, sizeof(___fmt), \
|
||||
___param, sizeof(___param)); \
|
||||
___ret; \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
140
src/btf.h
140
src/btf.h
@@ -5,7 +5,6 @@
|
||||
#define __LIBBPF_BTF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <linux/btf.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
@@ -25,25 +24,48 @@ struct btf_type;
|
||||
|
||||
struct bpf_object;
|
||||
|
||||
enum btf_endianness {
|
||||
BTF_LITTLE_ENDIAN = 0,
|
||||
BTF_BIG_ENDIAN = 1,
|
||||
/*
|
||||
* The .BTF.ext ELF section layout defined as
|
||||
* struct btf_ext_header
|
||||
* func_info subsection
|
||||
*
|
||||
* The func_info subsection layout:
|
||||
* record size for struct bpf_func_info in the func_info subsection
|
||||
* struct btf_sec_func_info for section #1
|
||||
* a list of bpf_func_info records for section #1
|
||||
* where struct bpf_func_info mimics one in include/uapi/linux/bpf.h
|
||||
* but may not be identical
|
||||
* struct btf_sec_func_info for section #2
|
||||
* a list of bpf_func_info records for section #2
|
||||
* ......
|
||||
*
|
||||
* Note that the bpf_func_info record size in .BTF.ext may not
|
||||
* be the same as the one defined in include/uapi/linux/bpf.h.
|
||||
* The loader should ensure that record_size meets minimum
|
||||
* requirement and pass the record as is to the kernel. The
|
||||
* kernel will handle the func_info properly based on its contents.
|
||||
*/
|
||||
struct btf_ext_header {
|
||||
__u16 magic;
|
||||
__u8 version;
|
||||
__u8 flags;
|
||||
__u32 hdr_len;
|
||||
|
||||
/* All offsets are in bytes relative to the end of this header */
|
||||
__u32 func_info_off;
|
||||
__u32 func_info_len;
|
||||
__u32 line_info_off;
|
||||
__u32 line_info_len;
|
||||
|
||||
/* optional part of .BTF.ext header */
|
||||
__u32 field_reloc_off;
|
||||
__u32 field_reloc_len;
|
||||
};
|
||||
|
||||
LIBBPF_API void btf__free(struct btf *btf);
|
||||
|
||||
LIBBPF_API struct btf *btf__new(const void *data, __u32 size);
|
||||
LIBBPF_API struct btf *btf__new_split(const void *data, __u32 size, struct btf *base_btf);
|
||||
LIBBPF_API struct btf *btf__new_empty(void);
|
||||
LIBBPF_API struct btf *btf__new_empty_split(struct btf *base_btf);
|
||||
|
||||
LIBBPF_API struct btf *btf__parse(const char *path, struct btf_ext **btf_ext);
|
||||
LIBBPF_API struct btf *btf__parse_split(const char *path, struct btf *base_btf);
|
||||
LIBBPF_API struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext);
|
||||
LIBBPF_API struct btf *btf__parse_elf_split(const char *path, struct btf *base_btf);
|
||||
LIBBPF_API struct btf *btf__parse_raw(const char *path);
|
||||
LIBBPF_API struct btf *btf__parse_raw_split(const char *path, struct btf *base_btf);
|
||||
|
||||
LIBBPF_API struct btf *btf__new(__u8 *data, __u32 size);
|
||||
LIBBPF_API struct btf *btf__parse_elf(const char *path,
|
||||
struct btf_ext **btf_ext);
|
||||
LIBBPF_API int btf__finalize_data(struct bpf_object *obj, struct btf *btf);
|
||||
LIBBPF_API int btf__load(struct btf *btf);
|
||||
LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
|
||||
@@ -51,21 +73,14 @@ LIBBPF_API __s32 btf__find_by_name(const struct btf *btf,
|
||||
LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
|
||||
const char *type_name, __u32 kind);
|
||||
LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf);
|
||||
LIBBPF_API const struct btf *btf__base_btf(const struct btf *btf);
|
||||
LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
|
||||
__u32 id);
|
||||
LIBBPF_API size_t btf__pointer_size(const struct btf *btf);
|
||||
LIBBPF_API int btf__set_pointer_size(struct btf *btf, size_t ptr_sz);
|
||||
LIBBPF_API enum btf_endianness btf__endianness(const struct btf *btf);
|
||||
LIBBPF_API int btf__set_endianness(struct btf *btf, enum btf_endianness endian);
|
||||
LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
|
||||
LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
|
||||
LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id);
|
||||
LIBBPF_API int btf__fd(const struct btf *btf);
|
||||
LIBBPF_API void btf__set_fd(struct btf *btf, int fd);
|
||||
LIBBPF_API const void *btf__get_raw_data(const struct btf *btf, __u32 *size);
|
||||
LIBBPF_API const char *btf__name_by_offset(const struct btf *btf, __u32 offset);
|
||||
LIBBPF_API const char *btf__str_by_offset(const struct btf *btf, __u32 offset);
|
||||
LIBBPF_API int btf__get_from_id(__u32 id, struct btf **btf);
|
||||
LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
|
||||
__u32 expected_key_size,
|
||||
@@ -76,65 +91,19 @@ LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size);
|
||||
LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext);
|
||||
LIBBPF_API const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext,
|
||||
__u32 *size);
|
||||
LIBBPF_API LIBBPF_DEPRECATED("btf_ext__reloc_func_info was never meant as a public API and has wrong assumptions embedded in it; it will be removed in the future libbpf versions")
|
||||
int btf_ext__reloc_func_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **func_info, __u32 *cnt);
|
||||
LIBBPF_API LIBBPF_DEPRECATED("btf_ext__reloc_line_info was never meant as a public API and has wrong assumptions embedded in it; it will be removed in the future libbpf versions")
|
||||
int btf_ext__reloc_line_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **line_info, __u32 *cnt);
|
||||
LIBBPF_API int btf_ext__reloc_func_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **func_info, __u32 *cnt);
|
||||
LIBBPF_API int btf_ext__reloc_line_info(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
const char *sec_name, __u32 insns_cnt,
|
||||
void **line_info, __u32 *cnt);
|
||||
LIBBPF_API __u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext);
|
||||
LIBBPF_API __u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext);
|
||||
|
||||
LIBBPF_API struct btf *libbpf_find_kernel_btf(void);
|
||||
|
||||
LIBBPF_API int btf__find_str(struct btf *btf, const char *s);
|
||||
LIBBPF_API int btf__add_str(struct btf *btf, const char *s);
|
||||
LIBBPF_API int btf__add_type(struct btf *btf, const struct btf *src_btf,
|
||||
const struct btf_type *src_type);
|
||||
|
||||
LIBBPF_API int btf__add_int(struct btf *btf, const char *name, size_t byte_sz, int encoding);
|
||||
LIBBPF_API int btf__add_float(struct btf *btf, const char *name, size_t byte_sz);
|
||||
LIBBPF_API int btf__add_ptr(struct btf *btf, int ref_type_id);
|
||||
LIBBPF_API int btf__add_array(struct btf *btf,
|
||||
int index_type_id, int elem_type_id, __u32 nr_elems);
|
||||
/* struct/union construction APIs */
|
||||
LIBBPF_API int btf__add_struct(struct btf *btf, const char *name, __u32 sz);
|
||||
LIBBPF_API int btf__add_union(struct btf *btf, const char *name, __u32 sz);
|
||||
LIBBPF_API int btf__add_field(struct btf *btf, const char *name, int field_type_id,
|
||||
__u32 bit_offset, __u32 bit_size);
|
||||
|
||||
/* enum construction APIs */
|
||||
LIBBPF_API int btf__add_enum(struct btf *btf, const char *name, __u32 bytes_sz);
|
||||
LIBBPF_API int btf__add_enum_value(struct btf *btf, const char *name, __s64 value);
|
||||
|
||||
enum btf_fwd_kind {
|
||||
BTF_FWD_STRUCT = 0,
|
||||
BTF_FWD_UNION = 1,
|
||||
BTF_FWD_ENUM = 2,
|
||||
};
|
||||
|
||||
LIBBPF_API int btf__add_fwd(struct btf *btf, const char *name, enum btf_fwd_kind fwd_kind);
|
||||
LIBBPF_API int btf__add_typedef(struct btf *btf, const char *name, int ref_type_id);
|
||||
LIBBPF_API int btf__add_volatile(struct btf *btf, int ref_type_id);
|
||||
LIBBPF_API int btf__add_const(struct btf *btf, int ref_type_id);
|
||||
LIBBPF_API int btf__add_restrict(struct btf *btf, int ref_type_id);
|
||||
|
||||
/* func and func_proto construction APIs */
|
||||
LIBBPF_API int btf__add_func(struct btf *btf, const char *name,
|
||||
enum btf_func_linkage linkage, int proto_type_id);
|
||||
LIBBPF_API int btf__add_func_proto(struct btf *btf, int ret_type_id);
|
||||
LIBBPF_API int btf__add_func_param(struct btf *btf, const char *name, int type_id);
|
||||
|
||||
/* var & datasec construction APIs */
|
||||
LIBBPF_API int btf__add_var(struct btf *btf, const char *name, int linkage, int type_id);
|
||||
LIBBPF_API int btf__add_datasec(struct btf *btf, const char *name, __u32 byte_sz);
|
||||
LIBBPF_API int btf__add_datasec_var_info(struct btf *btf, int var_type_id,
|
||||
__u32 offset, __u32 byte_sz);
|
||||
|
||||
struct btf_dedup_opts {
|
||||
unsigned int dedup_table_size;
|
||||
bool dont_resolve_fwds;
|
||||
@@ -174,11 +143,8 @@ struct btf_dump_emit_type_decl_opts {
|
||||
* necessary indentation already
|
||||
*/
|
||||
int indent_level;
|
||||
/* strip all the const/volatile/restrict mods */
|
||||
bool strip_mods;
|
||||
size_t :0;
|
||||
};
|
||||
#define btf_dump_emit_type_decl_opts__last_field strip_mods
|
||||
#define btf_dump_emit_type_decl_opts__last_field indent_level
|
||||
|
||||
LIBBPF_API int
|
||||
btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
|
||||
@@ -202,11 +168,6 @@ static inline bool btf_kflag(const struct btf_type *t)
|
||||
return BTF_INFO_KFLAG(t->info);
|
||||
}
|
||||
|
||||
static inline bool btf_is_void(const struct btf_type *t)
|
||||
{
|
||||
return btf_kind(t) == BTF_KIND_UNKN;
|
||||
}
|
||||
|
||||
static inline bool btf_is_int(const struct btf_type *t)
|
||||
{
|
||||
return btf_kind(t) == BTF_KIND_INT;
|
||||
@@ -298,11 +259,6 @@ static inline bool btf_is_datasec(const struct btf_type *t)
|
||||
return btf_kind(t) == BTF_KIND_DATASEC;
|
||||
}
|
||||
|
||||
static inline bool btf_is_float(const struct btf_type *t)
|
||||
{
|
||||
return btf_kind(t) == BTF_KIND_FLOAT;
|
||||
}
|
||||
|
||||
static inline __u8 btf_int_encoding(const struct btf_type *t)
|
||||
{
|
||||
return BTF_INT_ENCODING(*(__u32 *)(t + 1));
|
||||
|
||||
144
src/btf_dump.c
144
src/btf_dump.c
@@ -13,12 +13,14 @@
|
||||
#include <errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/btf.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "btf.h"
|
||||
#include "hashmap.h"
|
||||
#include "libbpf.h"
|
||||
#include "libbpf_internal.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
static const char PREFIXES[] = "\t\t\t\t\t\t\t\t\t\t\t\t\t";
|
||||
static const size_t PREFIX_CNT = sizeof(PREFIXES) - 1;
|
||||
|
||||
@@ -58,16 +60,11 @@ struct btf_dump {
|
||||
const struct btf_ext *btf_ext;
|
||||
btf_dump_printf_fn_t printf_fn;
|
||||
struct btf_dump_opts opts;
|
||||
int ptr_sz;
|
||||
bool strip_mods;
|
||||
int last_id;
|
||||
|
||||
/* per-type auxiliary state */
|
||||
struct btf_dump_type_aux_state *type_states;
|
||||
size_t type_states_cap;
|
||||
/* per-type optional cached unique name, must be freed, if present */
|
||||
const char **cached_names;
|
||||
size_t cached_names_cap;
|
||||
|
||||
/* topo-sorted list of dependent type definitions */
|
||||
__u32 *emit_queue;
|
||||
@@ -93,7 +90,14 @@ struct btf_dump {
|
||||
|
||||
static size_t str_hash_fn(const void *key, void *ctx)
|
||||
{
|
||||
return str_hash(key);
|
||||
const char *s = key;
|
||||
size_t h = 0;
|
||||
|
||||
while (*s) {
|
||||
h = h * 31 + *s;
|
||||
s++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static bool str_equal_fn(const void *a, const void *b, void *ctx)
|
||||
@@ -116,7 +120,6 @@ static void btf_dump_printf(const struct btf_dump *d, const char *fmt, ...)
|
||||
}
|
||||
|
||||
static int btf_dump_mark_referenced(struct btf_dump *d);
|
||||
static int btf_dump_resize(struct btf_dump *d);
|
||||
|
||||
struct btf_dump *btf_dump__new(const struct btf *btf,
|
||||
const struct btf_ext *btf_ext,
|
||||
@@ -134,7 +137,6 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
|
||||
d->btf_ext = btf_ext;
|
||||
d->printf_fn = printf_fn;
|
||||
d->opts.ctx = opts ? opts->ctx : NULL;
|
||||
d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *);
|
||||
|
||||
d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
|
||||
if (IS_ERR(d->type_names)) {
|
||||
@@ -148,8 +150,25 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
|
||||
d->ident_names = NULL;
|
||||
goto err;
|
||||
}
|
||||
d->type_states = calloc(1 + btf__get_nr_types(d->btf),
|
||||
sizeof(d->type_states[0]));
|
||||
if (!d->type_states) {
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
d->cached_names = calloc(1 + btf__get_nr_types(d->btf),
|
||||
sizeof(d->cached_names[0]));
|
||||
if (!d->cached_names) {
|
||||
err = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = btf_dump_resize(d);
|
||||
/* VOID is special */
|
||||
d->type_states[0].order_state = ORDERED;
|
||||
d->type_states[0].emit_state = EMITTED;
|
||||
|
||||
/* eagerly determine referenced types for anon enums */
|
||||
err = btf_dump_mark_referenced(d);
|
||||
if (err)
|
||||
goto err;
|
||||
|
||||
@@ -159,46 +178,17 @@ err:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
static int btf_dump_resize(struct btf_dump *d)
|
||||
{
|
||||
int err, last_id = btf__get_nr_types(d->btf);
|
||||
|
||||
if (last_id <= d->last_id)
|
||||
return 0;
|
||||
|
||||
if (libbpf_ensure_mem((void **)&d->type_states, &d->type_states_cap,
|
||||
sizeof(*d->type_states), last_id + 1))
|
||||
return -ENOMEM;
|
||||
if (libbpf_ensure_mem((void **)&d->cached_names, &d->cached_names_cap,
|
||||
sizeof(*d->cached_names), last_id + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
if (d->last_id == 0) {
|
||||
/* VOID is special */
|
||||
d->type_states[0].order_state = ORDERED;
|
||||
d->type_states[0].emit_state = EMITTED;
|
||||
}
|
||||
|
||||
/* eagerly determine referenced types for anon enums */
|
||||
err = btf_dump_mark_referenced(d);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
d->last_id = last_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btf_dump__free(struct btf_dump *d)
|
||||
{
|
||||
int i;
|
||||
int i, cnt;
|
||||
|
||||
if (IS_ERR_OR_NULL(d))
|
||||
if (!d)
|
||||
return;
|
||||
|
||||
free(d->type_states);
|
||||
if (d->cached_names) {
|
||||
/* any set cached name is owned by us and should be freed */
|
||||
for (i = 0; i <= d->last_id; i++) {
|
||||
for (i = 0, cnt = btf__get_nr_types(d->btf); i <= cnt; i++) {
|
||||
if (d->cached_names[i])
|
||||
free((void *)d->cached_names[i]);
|
||||
}
|
||||
@@ -238,10 +228,6 @@ int btf_dump__dump_type(struct btf_dump *d, __u32 id)
|
||||
if (id > btf__get_nr_types(d->btf))
|
||||
return -EINVAL;
|
||||
|
||||
err = btf_dump_resize(d);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
d->emit_queue_cnt = 0;
|
||||
err = btf_dump_order_type(d, id, false);
|
||||
if (err < 0)
|
||||
@@ -271,7 +257,7 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
|
||||
const struct btf_type *t;
|
||||
__u16 vlen;
|
||||
|
||||
for (i = d->last_id + 1; i <= n; i++) {
|
||||
for (i = 1; i <= n; i++) {
|
||||
t = btf__type_by_id(d->btf, i);
|
||||
vlen = btf_vlen(t);
|
||||
|
||||
@@ -279,7 +265,6 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
|
||||
case BTF_KIND_INT:
|
||||
case BTF_KIND_ENUM:
|
||||
case BTF_KIND_FWD:
|
||||
case BTF_KIND_FLOAT:
|
||||
break;
|
||||
|
||||
case BTF_KIND_VOLATILE:
|
||||
@@ -327,7 +312,6 @@ static int btf_dump_mark_referenced(struct btf_dump *d)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
|
||||
{
|
||||
__u32 *new_queue;
|
||||
@@ -335,7 +319,8 @@ static int btf_dump_add_emit_queue_id(struct btf_dump *d, __u32 id)
|
||||
|
||||
if (d->emit_queue_cnt >= d->emit_queue_cap) {
|
||||
new_cap = max(16, d->emit_queue_cap * 3 / 2);
|
||||
new_queue = libbpf_reallocarray(d->emit_queue, new_cap, sizeof(new_queue[0]));
|
||||
new_queue = realloc(d->emit_queue,
|
||||
new_cap * sizeof(new_queue[0]));
|
||||
if (!new_queue)
|
||||
return -ENOMEM;
|
||||
d->emit_queue = new_queue;
|
||||
@@ -454,7 +439,6 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
|
||||
|
||||
switch (btf_kind(t)) {
|
||||
case BTF_KIND_INT:
|
||||
case BTF_KIND_FLOAT:
|
||||
tstate->order_state = ORDERED;
|
||||
return 0;
|
||||
|
||||
@@ -464,7 +448,7 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
|
||||
return err;
|
||||
|
||||
case BTF_KIND_ARRAY:
|
||||
return btf_dump_order_type(d, btf_array(t)->type, false);
|
||||
return btf_dump_order_type(d, btf_array(t)->type, through_ptr);
|
||||
|
||||
case BTF_KIND_STRUCT:
|
||||
case BTF_KIND_UNION: {
|
||||
@@ -564,9 +548,6 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
|
||||
const struct btf_type *t);
|
||||
|
||||
static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
|
||||
const struct btf_type *t);
|
||||
static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
|
||||
@@ -689,9 +670,6 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
|
||||
|
||||
switch (kind) {
|
||||
case BTF_KIND_INT:
|
||||
/* Emit type alias definitions if necessary */
|
||||
btf_dump_emit_missing_aliases(d, id, t);
|
||||
|
||||
tstate->emit_state = EMITTED;
|
||||
break;
|
||||
case BTF_KIND_ENUM:
|
||||
@@ -818,7 +796,7 @@ static void btf_dump_emit_bit_padding(const struct btf_dump *d,
|
||||
int align, int lvl)
|
||||
{
|
||||
int off_diff = m_off - cur_off;
|
||||
int ptr_bits = d->ptr_sz * 8;
|
||||
int ptr_bits = sizeof(void *) * 8;
|
||||
|
||||
if (off_diff <= 0)
|
||||
/* no gap */
|
||||
@@ -891,7 +869,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
|
||||
btf_dump_printf(d, ": %d", m_sz);
|
||||
off = m_off + m_sz;
|
||||
} else {
|
||||
m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));
|
||||
m_sz = max(0, btf__resolve_size(d->btf, m->type));
|
||||
off = m_off + m_sz * 8;
|
||||
}
|
||||
btf_dump_printf(d, ";");
|
||||
@@ -911,32 +889,6 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
|
||||
btf_dump_printf(d, " __attribute__((packed))");
|
||||
}
|
||||
|
||||
static const char *missing_base_types[][2] = {
|
||||
/*
|
||||
* GCC emits typedefs to its internal __PolyX_t types when compiling Arm
|
||||
* SIMD intrinsics. Alias them to standard base types.
|
||||
*/
|
||||
{ "__Poly8_t", "unsigned char" },
|
||||
{ "__Poly16_t", "unsigned short" },
|
||||
{ "__Poly64_t", "unsigned long long" },
|
||||
{ "__Poly128_t", "unsigned __int128" },
|
||||
};
|
||||
|
||||
static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
|
||||
const struct btf_type *t)
|
||||
{
|
||||
const char *name = btf_dump_type_name(d, id);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(missing_base_types); i++) {
|
||||
if (strcmp(name, missing_base_types[i][0]) == 0) {
|
||||
btf_dump_printf(d, "typedef %s %s;\n\n",
|
||||
missing_base_types[i][1], name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
|
||||
const struct btf_type *t)
|
||||
{
|
||||
@@ -1015,7 +967,8 @@ static int btf_dump_push_decl_stack_id(struct btf_dump *d, __u32 id)
|
||||
|
||||
if (d->decl_stack_cnt >= d->decl_stack_cap) {
|
||||
new_cap = max(16, d->decl_stack_cap * 3 / 2);
|
||||
new_stack = libbpf_reallocarray(d->decl_stack, new_cap, sizeof(new_stack[0]));
|
||||
new_stack = realloc(d->decl_stack,
|
||||
new_cap * sizeof(new_stack[0]));
|
||||
if (!new_stack)
|
||||
return -ENOMEM;
|
||||
d->decl_stack = new_stack;
|
||||
@@ -1072,20 +1025,14 @@ int btf_dump__emit_type_decl(struct btf_dump *d, __u32 id,
|
||||
const struct btf_dump_emit_type_decl_opts *opts)
|
||||
{
|
||||
const char *fname;
|
||||
int lvl, err;
|
||||
int lvl;
|
||||
|
||||
if (!OPTS_VALID(opts, btf_dump_emit_type_decl_opts))
|
||||
return -EINVAL;
|
||||
|
||||
err = btf_dump_resize(d);
|
||||
if (err)
|
||||
return -EINVAL;
|
||||
|
||||
fname = OPTS_GET(opts, field_name, "");
|
||||
lvl = OPTS_GET(opts, indent_level, 0);
|
||||
d->strip_mods = OPTS_GET(opts, strip_mods, false);
|
||||
btf_dump_emit_type_decl(d, id, fname, lvl);
|
||||
d->strip_mods = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1098,10 +1045,6 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
|
||||
|
||||
stack_start = d->decl_stack_cnt;
|
||||
for (;;) {
|
||||
t = btf__type_by_id(d->btf, id);
|
||||
if (d->strip_mods && btf_is_mod(t))
|
||||
goto skip_mod;
|
||||
|
||||
err = btf_dump_push_decl_stack_id(d, id);
|
||||
if (err < 0) {
|
||||
/*
|
||||
@@ -1113,11 +1056,12 @@ static void btf_dump_emit_type_decl(struct btf_dump *d, __u32 id,
|
||||
d->decl_stack_cnt = stack_start;
|
||||
return;
|
||||
}
|
||||
skip_mod:
|
||||
|
||||
/* VOID */
|
||||
if (id == 0)
|
||||
break;
|
||||
|
||||
t = btf__type_by_id(d->btf, id);
|
||||
switch (btf_kind(t)) {
|
||||
case BTF_KIND_PTR:
|
||||
case BTF_KIND_VOLATILE:
|
||||
@@ -1135,7 +1079,6 @@ skip_mod:
|
||||
case BTF_KIND_STRUCT:
|
||||
case BTF_KIND_UNION:
|
||||
case BTF_KIND_TYPEDEF:
|
||||
case BTF_KIND_FLOAT:
|
||||
goto done;
|
||||
default:
|
||||
pr_warn("unexpected type in decl chain, kind:%u, id:[%u]\n",
|
||||
@@ -1250,7 +1193,6 @@ static void btf_dump_emit_type_chain(struct btf_dump *d,
|
||||
|
||||
switch (kind) {
|
||||
case BTF_KIND_INT:
|
||||
case BTF_KIND_FLOAT:
|
||||
btf_dump_emit_mods(d, decls);
|
||||
name = btf_name_of(d, t->name_off);
|
||||
btf_dump_printf(d, "%s", name);
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
/* prevent accidental re-addition of reallocarray() */
|
||||
#pragma GCC poison reallocarray
|
||||
|
||||
/* start with 4 buckets */
|
||||
#define HASHMAP_MIN_CAP_BITS 2
|
||||
|
||||
|
||||
@@ -11,33 +11,14 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#ifndef __WORDSIZE
|
||||
#define __WORDSIZE (__SIZEOF_LONG__ * 8)
|
||||
#endif
|
||||
|
||||
static inline size_t hash_bits(size_t h, int bits)
|
||||
{
|
||||
/* shuffle bits and return requested number of upper bits */
|
||||
if (bits == 0)
|
||||
return 0;
|
||||
|
||||
#if (__SIZEOF_SIZE_T__ == __SIZEOF_LONG_LONG__)
|
||||
/* LP64 case */
|
||||
return (h * 11400714819323198485llu) >> (__SIZEOF_LONG_LONG__ * 8 - bits);
|
||||
#elif (__SIZEOF_SIZE_T__ <= __SIZEOF_LONG__)
|
||||
return (h * 2654435769lu) >> (__SIZEOF_LONG__ * 8 - bits);
|
||||
#else
|
||||
# error "Unsupported size_t size"
|
||||
#endif
|
||||
}
|
||||
|
||||
/* generic C-string hashing function */
|
||||
static inline size_t str_hash(const char *s)
|
||||
{
|
||||
size_t h = 0;
|
||||
|
||||
while (*s) {
|
||||
h = h * 31 + *s;
|
||||
s++;
|
||||
}
|
||||
return h;
|
||||
return (h * 11400714819323198485llu) >> (__WORDSIZE - bits);
|
||||
}
|
||||
|
||||
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||
@@ -177,17 +158,17 @@ bool hashmap__find(const struct hashmap *map, const void *key, void **value);
|
||||
* @key: key to iterate entries for
|
||||
*/
|
||||
#define hashmap__for_each_key_entry(map, cur, _key) \
|
||||
for (cur = map->buckets \
|
||||
? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||
: NULL; \
|
||||
for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
map->cap_bits); \
|
||||
map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
cur; \
|
||||
cur = cur->next) \
|
||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
|
||||
#define hashmap__for_each_key_entry_safe(map, cur, tmp, _key) \
|
||||
for (cur = map->buckets \
|
||||
? map->buckets[hash_bits(map->hash_fn((_key), map->ctx), map->cap_bits)] \
|
||||
: NULL; \
|
||||
for (cur = ({ size_t bkt = hash_bits(map->hash_fn((_key), map->ctx),\
|
||||
map->cap_bits); \
|
||||
cur = map->buckets ? map->buckets[bkt] : NULL; }); \
|
||||
cur && ({ tmp = cur->next; true; }); \
|
||||
cur = tmp) \
|
||||
if (map->equal_fn(cur->key, (_key), map->ctx))
|
||||
|
||||
5861
src/libbpf.c
5861
src/libbpf.c
File diff suppressed because it is too large
Load Diff
126
src/libbpf.h
126
src/libbpf.h
@@ -143,7 +143,6 @@ LIBBPF_API int bpf_object__unload(struct bpf_object *obj);
|
||||
|
||||
LIBBPF_API const char *bpf_object__name(const struct bpf_object *obj);
|
||||
LIBBPF_API unsigned int bpf_object__kversion(const struct bpf_object *obj);
|
||||
LIBBPF_API int bpf_object__set_kversion(struct bpf_object *obj, __u32 kern_version);
|
||||
|
||||
struct btf;
|
||||
LIBBPF_API struct btf *bpf_object__btf(const struct bpf_object *obj);
|
||||
@@ -199,11 +198,8 @@ LIBBPF_API void bpf_program__set_ifindex(struct bpf_program *prog,
|
||||
__u32 ifindex);
|
||||
|
||||
LIBBPF_API const char *bpf_program__name(const struct bpf_program *prog);
|
||||
LIBBPF_API const char *bpf_program__section_name(const struct bpf_program *prog);
|
||||
LIBBPF_API LIBBPF_DEPRECATED("BPF program title is confusing term; please use bpf_program__section_name() instead")
|
||||
const char *bpf_program__title(const struct bpf_program *prog, bool needs_copy);
|
||||
LIBBPF_API bool bpf_program__autoload(const struct bpf_program *prog);
|
||||
LIBBPF_API int bpf_program__set_autoload(struct bpf_program *prog, bool autoload);
|
||||
LIBBPF_API const char *bpf_program__title(const struct bpf_program *prog,
|
||||
bool needs_copy);
|
||||
|
||||
/* returns program size in bytes */
|
||||
LIBBPF_API size_t bpf_program__size(const struct bpf_program *prog);
|
||||
@@ -231,7 +227,6 @@ LIBBPF_API int bpf_link__unpin(struct bpf_link *link);
|
||||
LIBBPF_API int bpf_link__update_program(struct bpf_link *link,
|
||||
struct bpf_program *prog);
|
||||
LIBBPF_API void bpf_link__disconnect(struct bpf_link *link);
|
||||
LIBBPF_API int bpf_link__detach(struct bpf_link *link);
|
||||
LIBBPF_API int bpf_link__destroy(struct bpf_link *link);
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
@@ -260,11 +255,6 @@ LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_cgroup(struct bpf_program *prog, int cgroup_fd);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_netns(struct bpf_program *prog, int netns_fd);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_xdp(struct bpf_program *prog, int ifindex);
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_freplace(struct bpf_program *prog,
|
||||
int target_fd, const char *attach_func_name);
|
||||
|
||||
struct bpf_map;
|
||||
|
||||
@@ -272,10 +262,8 @@ LIBBPF_API struct bpf_link *bpf_map__attach_struct_ops(struct bpf_map *map);
|
||||
|
||||
struct bpf_iter_attach_opts {
|
||||
size_t sz; /* size of this struct for forward/backward compatibility */
|
||||
union bpf_iter_link_info *link_info;
|
||||
__u32 link_info_len;
|
||||
};
|
||||
#define bpf_iter_attach_opts__last_field link_info_len
|
||||
#define bpf_iter_attach_opts__last_field sz
|
||||
|
||||
LIBBPF_API struct bpf_link *
|
||||
bpf_program__attach_iter(struct bpf_program *prog,
|
||||
@@ -360,14 +348,13 @@ LIBBPF_API int bpf_program__set_perf_event(struct bpf_program *prog);
|
||||
LIBBPF_API int bpf_program__set_tracing(struct bpf_program *prog);
|
||||
LIBBPF_API int bpf_program__set_struct_ops(struct bpf_program *prog);
|
||||
LIBBPF_API int bpf_program__set_extension(struct bpf_program *prog);
|
||||
LIBBPF_API int bpf_program__set_sk_lookup(struct bpf_program *prog);
|
||||
|
||||
LIBBPF_API enum bpf_prog_type bpf_program__get_type(const struct bpf_program *prog);
|
||||
LIBBPF_API enum bpf_prog_type bpf_program__get_type(struct bpf_program *prog);
|
||||
LIBBPF_API void bpf_program__set_type(struct bpf_program *prog,
|
||||
enum bpf_prog_type type);
|
||||
|
||||
LIBBPF_API enum bpf_attach_type
|
||||
bpf_program__get_expected_attach_type(const struct bpf_program *prog);
|
||||
bpf_program__get_expected_attach_type(struct bpf_program *prog);
|
||||
LIBBPF_API void
|
||||
bpf_program__set_expected_attach_type(struct bpf_program *prog,
|
||||
enum bpf_attach_type type);
|
||||
@@ -388,7 +375,6 @@ LIBBPF_API bool bpf_program__is_perf_event(const struct bpf_program *prog);
|
||||
LIBBPF_API bool bpf_program__is_tracing(const struct bpf_program *prog);
|
||||
LIBBPF_API bool bpf_program__is_struct_ops(const struct bpf_program *prog);
|
||||
LIBBPF_API bool bpf_program__is_extension(const struct bpf_program *prog);
|
||||
LIBBPF_API bool bpf_program__is_sk_lookup(const struct bpf_program *prog);
|
||||
|
||||
/*
|
||||
* No need for __attribute__((packed)), all members of 'bpf_map_def'
|
||||
@@ -432,38 +418,11 @@ bpf_map__next(const struct bpf_map *map, const struct bpf_object *obj);
|
||||
LIBBPF_API struct bpf_map *
|
||||
bpf_map__prev(const struct bpf_map *map, const struct bpf_object *obj);
|
||||
|
||||
/* get/set map FD */
|
||||
LIBBPF_API int bpf_map__fd(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd);
|
||||
/* get map definition */
|
||||
LIBBPF_API const struct bpf_map_def *bpf_map__def(const struct bpf_map *map);
|
||||
/* get map name */
|
||||
LIBBPF_API const char *bpf_map__name(const struct bpf_map *map);
|
||||
/* get/set map type */
|
||||
LIBBPF_API enum bpf_map_type bpf_map__type(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_type(struct bpf_map *map, enum bpf_map_type type);
|
||||
/* get/set map size (max_entries) */
|
||||
LIBBPF_API __u32 bpf_map__max_entries(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_max_entries(struct bpf_map *map, __u32 max_entries);
|
||||
LIBBPF_API int bpf_map__resize(struct bpf_map *map, __u32 max_entries);
|
||||
/* get/set map flags */
|
||||
LIBBPF_API __u32 bpf_map__map_flags(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_map_flags(struct bpf_map *map, __u32 flags);
|
||||
/* get/set map NUMA node */
|
||||
LIBBPF_API __u32 bpf_map__numa_node(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_numa_node(struct bpf_map *map, __u32 numa_node);
|
||||
/* get/set map key size */
|
||||
LIBBPF_API __u32 bpf_map__key_size(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_key_size(struct bpf_map *map, __u32 size);
|
||||
/* get/set map value size */
|
||||
LIBBPF_API __u32 bpf_map__value_size(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_value_size(struct bpf_map *map, __u32 size);
|
||||
/* get map key/value BTF type IDs */
|
||||
LIBBPF_API __u32 bpf_map__btf_key_type_id(const struct bpf_map *map);
|
||||
LIBBPF_API __u32 bpf_map__btf_value_type_id(const struct bpf_map *map);
|
||||
/* get/set map if_index */
|
||||
LIBBPF_API __u32 bpf_map__ifindex(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
|
||||
|
||||
typedef void (*bpf_map_clear_priv_t)(struct bpf_map *, void *);
|
||||
LIBBPF_API int bpf_map__set_priv(struct bpf_map *map, void *priv,
|
||||
@@ -471,8 +430,11 @@ LIBBPF_API int bpf_map__set_priv(struct bpf_map *map, void *priv,
|
||||
LIBBPF_API void *bpf_map__priv(const struct bpf_map *map);
|
||||
LIBBPF_API int bpf_map__set_initial_value(struct bpf_map *map,
|
||||
const void *data, size_t size);
|
||||
LIBBPF_API int bpf_map__reuse_fd(struct bpf_map *map, int fd);
|
||||
LIBBPF_API int bpf_map__resize(struct bpf_map *map, __u32 max_entries);
|
||||
LIBBPF_API bool bpf_map__is_offload_neutral(const struct bpf_map *map);
|
||||
LIBBPF_API bool bpf_map__is_internal(const struct bpf_map *map);
|
||||
LIBBPF_API void bpf_map__set_ifindex(struct bpf_map *map, __u32 ifindex);
|
||||
LIBBPF_API int bpf_map__set_pin_path(struct bpf_map *map, const char *path);
|
||||
LIBBPF_API const char *bpf_map__get_pin_path(const struct bpf_map *map);
|
||||
LIBBPF_API bool bpf_map__is_pinned(const struct bpf_map *map);
|
||||
@@ -480,7 +442,6 @@ 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 int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd);
|
||||
LIBBPF_API struct bpf_map *bpf_map__inner_map(struct bpf_map *map);
|
||||
|
||||
LIBBPF_API long libbpf_get_error(const void *ptr);
|
||||
|
||||
@@ -498,7 +459,6 @@ LIBBPF_API int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr,
|
||||
LIBBPF_API int bpf_prog_load(const char *file, enum bpf_prog_type type,
|
||||
struct bpf_object **pobj, int *prog_fd);
|
||||
|
||||
/* XDP related API */
|
||||
struct xdp_link_info {
|
||||
__u32 prog_id;
|
||||
__u32 drv_prog_id;
|
||||
@@ -510,7 +470,6 @@ struct xdp_link_info {
|
||||
struct bpf_xdp_set_link_opts {
|
||||
size_t sz;
|
||||
int old_fd;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_xdp_set_link_opts__last_field old_fd
|
||||
|
||||
@@ -521,49 +480,6 @@ LIBBPF_API int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags);
|
||||
LIBBPF_API int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
|
||||
size_t info_size, __u32 flags);
|
||||
|
||||
/* TC related API */
|
||||
enum bpf_tc_attach_point {
|
||||
BPF_TC_INGRESS = 1 << 0,
|
||||
BPF_TC_EGRESS = 1 << 1,
|
||||
BPF_TC_CUSTOM = 1 << 2,
|
||||
};
|
||||
|
||||
#define BPF_TC_PARENT(a, b) \
|
||||
((((a) << 16) & 0xFFFF0000U) | ((b) & 0x0000FFFFU))
|
||||
|
||||
enum bpf_tc_flags {
|
||||
BPF_TC_F_REPLACE = 1 << 0,
|
||||
};
|
||||
|
||||
struct bpf_tc_hook {
|
||||
size_t sz;
|
||||
int ifindex;
|
||||
enum bpf_tc_attach_point attach_point;
|
||||
__u32 parent;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_tc_hook__last_field parent
|
||||
|
||||
struct bpf_tc_opts {
|
||||
size_t sz;
|
||||
int prog_fd;
|
||||
__u32 flags;
|
||||
__u32 prog_id;
|
||||
__u32 handle;
|
||||
__u32 priority;
|
||||
size_t :0;
|
||||
};
|
||||
#define bpf_tc_opts__last_field priority
|
||||
|
||||
LIBBPF_API int bpf_tc_hook_create(struct bpf_tc_hook *hook);
|
||||
LIBBPF_API int bpf_tc_hook_destroy(struct bpf_tc_hook *hook);
|
||||
LIBBPF_API int bpf_tc_attach(const struct bpf_tc_hook *hook,
|
||||
struct bpf_tc_opts *opts);
|
||||
LIBBPF_API int bpf_tc_detach(const struct bpf_tc_hook *hook,
|
||||
const struct bpf_tc_opts *opts);
|
||||
LIBBPF_API int bpf_tc_query(const struct bpf_tc_hook *hook,
|
||||
struct bpf_tc_opts *opts);
|
||||
|
||||
/* Ring buffer APIs */
|
||||
struct ring_buffer;
|
||||
|
||||
@@ -583,7 +499,6 @@ LIBBPF_API int ring_buffer__add(struct ring_buffer *rb, int map_fd,
|
||||
ring_buffer_sample_fn sample_cb, void *ctx);
|
||||
LIBBPF_API int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms);
|
||||
LIBBPF_API int ring_buffer__consume(struct ring_buffer *rb);
|
||||
LIBBPF_API int ring_buffer__epoll_fd(const struct ring_buffer *rb);
|
||||
|
||||
/* Perf buffer APIs */
|
||||
struct perf_buffer;
|
||||
@@ -640,12 +555,8 @@ perf_buffer__new_raw(int map_fd, size_t page_cnt,
|
||||
const struct perf_buffer_raw_opts *opts);
|
||||
|
||||
LIBBPF_API void perf_buffer__free(struct perf_buffer *pb);
|
||||
LIBBPF_API int perf_buffer__epoll_fd(const struct perf_buffer *pb);
|
||||
LIBBPF_API int perf_buffer__poll(struct perf_buffer *pb, int timeout_ms);
|
||||
LIBBPF_API int perf_buffer__consume(struct perf_buffer *pb);
|
||||
LIBBPF_API int perf_buffer__consume_buffer(struct perf_buffer *pb, size_t buf_idx);
|
||||
LIBBPF_API size_t perf_buffer__buffer_cnt(const struct perf_buffer *pb);
|
||||
LIBBPF_API int perf_buffer__buffer_fd(const struct perf_buffer *pb, size_t buf_idx);
|
||||
|
||||
typedef enum bpf_perf_event_ret
|
||||
(*bpf_perf_event_print_t)(struct perf_event_header *hdr,
|
||||
@@ -806,27 +717,6 @@ enum libbpf_tristate {
|
||||
TRI_MODULE = 2,
|
||||
};
|
||||
|
||||
struct bpf_linker_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
};
|
||||
#define bpf_linker_opts__last_field sz
|
||||
|
||||
struct bpf_linker_file_opts {
|
||||
/* size of this struct, for forward/backward compatiblity */
|
||||
size_t sz;
|
||||
};
|
||||
#define bpf_linker_file_opts__last_field sz
|
||||
|
||||
struct bpf_linker;
|
||||
|
||||
LIBBPF_API struct bpf_linker *bpf_linker__new(const char *filename, struct bpf_linker_opts *opts);
|
||||
LIBBPF_API int bpf_linker__add_file(struct bpf_linker *linker,
|
||||
const char *filename,
|
||||
const struct bpf_linker_file_opts *opts);
|
||||
LIBBPF_API int bpf_linker__finalize(struct bpf_linker *linker);
|
||||
LIBBPF_API void bpf_linker__free(struct bpf_linker *linker);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
@@ -270,100 +270,3 @@ LIBBPF_0.0.9 {
|
||||
ring_buffer__new;
|
||||
ring_buffer__poll;
|
||||
} LIBBPF_0.0.8;
|
||||
|
||||
LIBBPF_0.1.0 {
|
||||
global:
|
||||
bpf_link__detach;
|
||||
bpf_link_detach;
|
||||
bpf_map__ifindex;
|
||||
bpf_map__key_size;
|
||||
bpf_map__map_flags;
|
||||
bpf_map__max_entries;
|
||||
bpf_map__numa_node;
|
||||
bpf_map__set_key_size;
|
||||
bpf_map__set_map_flags;
|
||||
bpf_map__set_max_entries;
|
||||
bpf_map__set_numa_node;
|
||||
bpf_map__set_type;
|
||||
bpf_map__set_value_size;
|
||||
bpf_map__type;
|
||||
bpf_map__value_size;
|
||||
bpf_program__attach_xdp;
|
||||
bpf_program__autoload;
|
||||
bpf_program__is_sk_lookup;
|
||||
bpf_program__set_autoload;
|
||||
bpf_program__set_sk_lookup;
|
||||
btf__parse;
|
||||
btf__parse_raw;
|
||||
btf__pointer_size;
|
||||
btf__set_fd;
|
||||
btf__set_pointer_size;
|
||||
} LIBBPF_0.0.9;
|
||||
|
||||
LIBBPF_0.2.0 {
|
||||
global:
|
||||
bpf_prog_bind_map;
|
||||
bpf_prog_test_run_opts;
|
||||
bpf_program__attach_freplace;
|
||||
bpf_program__section_name;
|
||||
btf__add_array;
|
||||
btf__add_const;
|
||||
btf__add_enum;
|
||||
btf__add_enum_value;
|
||||
btf__add_datasec;
|
||||
btf__add_datasec_var_info;
|
||||
btf__add_field;
|
||||
btf__add_func;
|
||||
btf__add_func_param;
|
||||
btf__add_func_proto;
|
||||
btf__add_fwd;
|
||||
btf__add_int;
|
||||
btf__add_ptr;
|
||||
btf__add_restrict;
|
||||
btf__add_str;
|
||||
btf__add_struct;
|
||||
btf__add_typedef;
|
||||
btf__add_union;
|
||||
btf__add_var;
|
||||
btf__add_volatile;
|
||||
btf__endianness;
|
||||
btf__find_str;
|
||||
btf__new_empty;
|
||||
btf__set_endianness;
|
||||
btf__str_by_offset;
|
||||
perf_buffer__buffer_cnt;
|
||||
perf_buffer__buffer_fd;
|
||||
perf_buffer__epoll_fd;
|
||||
perf_buffer__consume_buffer;
|
||||
xsk_socket__create_shared;
|
||||
} LIBBPF_0.1.0;
|
||||
|
||||
LIBBPF_0.3.0 {
|
||||
global:
|
||||
btf__base_btf;
|
||||
btf__parse_elf_split;
|
||||
btf__parse_raw_split;
|
||||
btf__parse_split;
|
||||
btf__new_empty_split;
|
||||
btf__new_split;
|
||||
ring_buffer__epoll_fd;
|
||||
xsk_setup_xdp_prog;
|
||||
xsk_socket__update_xskmap;
|
||||
} LIBBPF_0.2.0;
|
||||
|
||||
LIBBPF_0.4.0 {
|
||||
global:
|
||||
btf__add_float;
|
||||
btf__add_type;
|
||||
bpf_linker__add_file;
|
||||
bpf_linker__finalize;
|
||||
bpf_linker__free;
|
||||
bpf_linker__new;
|
||||
bpf_map__inner_map;
|
||||
bpf_object__set_kversion;
|
||||
bpf_tc_attach;
|
||||
bpf_tc_detach;
|
||||
bpf_tc_hook_create;
|
||||
bpf_tc_hook_destroy;
|
||||
bpf_tc_query;
|
||||
} LIBBPF_0.3.0;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#define LIBBPF_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#define LIBBPF_DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
|
||||
/* Helper macro to declare and initialize libbpf options struct
|
||||
*
|
||||
* This dance with uninitialized declaration, followed by memset to zero,
|
||||
|
||||
@@ -9,48 +9,7 @@
|
||||
#ifndef __LIBBPF_LIBBPF_INTERNAL_H
|
||||
#define __LIBBPF_LIBBPF_INTERNAL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
/* prevent accidental re-addition of reallocarray() */
|
||||
#pragma GCC poison reallocarray
|
||||
|
||||
#include "libbpf.h"
|
||||
#include "btf.h"
|
||||
|
||||
#ifndef EM_BPF
|
||||
#define EM_BPF 247
|
||||
#endif
|
||||
|
||||
#ifndef R_BPF_64_64
|
||||
#define R_BPF_64_64 1
|
||||
#endif
|
||||
#ifndef R_BPF_64_ABS64
|
||||
#define R_BPF_64_ABS64 2
|
||||
#endif
|
||||
#ifndef R_BPF_64_ABS32
|
||||
#define R_BPF_64_ABS32 3
|
||||
#endif
|
||||
#ifndef R_BPF_64_32
|
||||
#define R_BPF_64_32 10
|
||||
#endif
|
||||
|
||||
#ifndef SHT_LLVM_ADDRSIG
|
||||
#define SHT_LLVM_ADDRSIG 0x6FFF4C03
|
||||
#endif
|
||||
|
||||
/* if libelf is old and doesn't support mmap(), fall back to read() */
|
||||
#ifndef ELF_C_READ_MMAP
|
||||
#define ELF_C_READ_MMAP ELF_C_READ
|
||||
#endif
|
||||
|
||||
/* Older libelf all end up in this expression, for both 32 and 64 bit */
|
||||
#ifndef GELF_ST_VISIBILITY
|
||||
#define GELF_ST_VISIBILITY(o) ((o) & 0x03)
|
||||
#endif
|
||||
|
||||
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
|
||||
((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
|
||||
@@ -63,15 +22,7 @@
|
||||
#define BTF_MEMBER_ENC(name, type, bits_offset) (name), (type), (bits_offset)
|
||||
#define BTF_PARAM_ENC(name, type) (name), (type)
|
||||
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
|
||||
#define BTF_TYPE_FLOAT_ENC(name, sz) \
|
||||
BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_FLOAT, 0, 0), sz)
|
||||
|
||||
#ifndef likely
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#endif
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
#ifndef min
|
||||
# define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
@@ -112,86 +63,6 @@ do { \
|
||||
#define pr_info(fmt, ...) __pr(LIBBPF_INFO, fmt, ##__VA_ARGS__)
|
||||
#define pr_debug(fmt, ...) __pr(LIBBPF_DEBUG, fmt, ##__VA_ARGS__)
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
/*
|
||||
* Re-implement glibc's reallocarray() for libbpf internal-only use.
|
||||
* reallocarray(), unfortunately, is not available in all versions of glibc,
|
||||
* so requires extra feature detection and using reallocarray() stub from
|
||||
* <tools/libc_compat.h> and COMPAT_NEED_REALLOCARRAY. All this complicates
|
||||
* build of libbpf unnecessarily and is just a maintenance burden. Instead,
|
||||
* it's trivial to implement libbpf-specific internal version and use it
|
||||
* throughout libbpf.
|
||||
*/
|
||||
static inline void *libbpf_reallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
size_t total;
|
||||
|
||||
#if __has_builtin(__builtin_mul_overflow)
|
||||
if (unlikely(__builtin_mul_overflow(nmemb, size, &total)))
|
||||
return NULL;
|
||||
#else
|
||||
if (size == 0 || nmemb > ULONG_MAX / size)
|
||||
return NULL;
|
||||
total = nmemb * size;
|
||||
#endif
|
||||
return realloc(ptr, total);
|
||||
}
|
||||
|
||||
struct btf;
|
||||
struct btf_type;
|
||||
|
||||
struct btf_type *btf_type_by_id(struct btf *btf, __u32 type_id);
|
||||
const char *btf_kind_str(const struct btf_type *t);
|
||||
const struct btf_type *skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id);
|
||||
|
||||
static inline enum btf_func_linkage btf_func_linkage(const struct btf_type *t)
|
||||
{
|
||||
return (enum btf_func_linkage)(int)btf_vlen(t);
|
||||
}
|
||||
|
||||
static inline __u32 btf_type_info(int kind, int vlen, int kflag)
|
||||
{
|
||||
return (kflag << 31) | (kind << 24) | vlen;
|
||||
}
|
||||
|
||||
enum map_def_parts {
|
||||
MAP_DEF_MAP_TYPE = 0x001,
|
||||
MAP_DEF_KEY_TYPE = 0x002,
|
||||
MAP_DEF_KEY_SIZE = 0x004,
|
||||
MAP_DEF_VALUE_TYPE = 0x008,
|
||||
MAP_DEF_VALUE_SIZE = 0x010,
|
||||
MAP_DEF_MAX_ENTRIES = 0x020,
|
||||
MAP_DEF_MAP_FLAGS = 0x040,
|
||||
MAP_DEF_NUMA_NODE = 0x080,
|
||||
MAP_DEF_PINNING = 0x100,
|
||||
MAP_DEF_INNER_MAP = 0x200,
|
||||
|
||||
MAP_DEF_ALL = 0x3ff, /* combination of all above */
|
||||
};
|
||||
|
||||
struct btf_map_def {
|
||||
enum map_def_parts parts;
|
||||
__u32 map_type;
|
||||
__u32 key_type_id;
|
||||
__u32 key_size;
|
||||
__u32 value_type_id;
|
||||
__u32 value_size;
|
||||
__u32 max_entries;
|
||||
__u32 map_flags;
|
||||
__u32 numa_node;
|
||||
__u32 pinning;
|
||||
};
|
||||
|
||||
int parse_btf_map_def(const char *map_name, struct btf *btf,
|
||||
const struct btf_type *def_t, bool strict,
|
||||
struct btf_map_def *map_def, struct btf_map_def *inner_def);
|
||||
|
||||
void *libbpf_add_mem(void **data, size_t *cap_cnt, size_t elem_sz,
|
||||
size_t cur_cnt, size_t max_cnt, size_t add_cnt);
|
||||
int libbpf_ensure_mem(void **data, size_t *cap_cnt, size_t elem_sz, size_t need_cnt);
|
||||
|
||||
static inline bool libbpf_validate_opts(const char *opts,
|
||||
size_t opts_sz, size_t user_sz,
|
||||
const char *type_name)
|
||||
@@ -223,52 +94,28 @@ static inline bool libbpf_validate_opts(const char *opts,
|
||||
((opts) && opts->sz >= offsetofend(typeof(*(opts)), field))
|
||||
#define OPTS_GET(opts, field, fallback_value) \
|
||||
(OPTS_HAS(opts, field) ? (opts)->field : fallback_value)
|
||||
#define OPTS_SET(opts, field, value) \
|
||||
do { \
|
||||
if (OPTS_HAS(opts, field)) \
|
||||
(opts)->field = value; \
|
||||
} while (0)
|
||||
|
||||
int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
|
||||
int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
|
||||
int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||
const char *str_sec, size_t str_len);
|
||||
|
||||
struct bpf_prog_load_params {
|
||||
enum bpf_prog_type prog_type;
|
||||
enum bpf_attach_type expected_attach_type;
|
||||
const char *name;
|
||||
const struct bpf_insn *insns;
|
||||
size_t insn_cnt;
|
||||
const char *license;
|
||||
__u32 kern_version;
|
||||
__u32 attach_prog_fd;
|
||||
__u32 attach_btf_obj_fd;
|
||||
__u32 attach_btf_id;
|
||||
__u32 prog_ifindex;
|
||||
__u32 prog_btf_fd;
|
||||
__u32 prog_flags;
|
||||
|
||||
__u32 func_info_rec_size;
|
||||
const void *func_info;
|
||||
__u32 func_info_cnt;
|
||||
|
||||
__u32 line_info_rec_size;
|
||||
const void *line_info;
|
||||
__u32 line_info_cnt;
|
||||
|
||||
__u32 log_level;
|
||||
char *log_buf;
|
||||
size_t log_buf_sz;
|
||||
};
|
||||
|
||||
int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
|
||||
|
||||
int bpf_object__section_size(const struct bpf_object *obj, const char *name,
|
||||
__u32 *size);
|
||||
int bpf_object__variable_offset(const struct bpf_object *obj, const char *name,
|
||||
__u32 *off);
|
||||
struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
|
||||
|
||||
struct nlattr;
|
||||
typedef int (*libbpf_dump_nlmsg_t)(void *cookie, void *msg, struct nlattr **tb);
|
||||
int libbpf_netlink_open(unsigned int *nl_pid);
|
||||
int libbpf_nl_get_link(int sock, unsigned int nl_pid,
|
||||
libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie);
|
||||
int libbpf_nl_get_class(int sock, unsigned int nl_pid, int ifindex,
|
||||
libbpf_dump_nlmsg_t dump_class_nlmsg, void *cookie);
|
||||
int libbpf_nl_get_qdisc(int sock, unsigned int nl_pid, int ifindex,
|
||||
libbpf_dump_nlmsg_t dump_qdisc_nlmsg, void *cookie);
|
||||
int libbpf_nl_get_filter(int sock, unsigned int nl_pid, int ifindex, int handle,
|
||||
libbpf_dump_nlmsg_t dump_filter_nlmsg, void *cookie);
|
||||
|
||||
struct btf_ext_info {
|
||||
/*
|
||||
@@ -291,44 +138,6 @@ struct btf_ext_info {
|
||||
i < (sec)->num_info; \
|
||||
i++, rec = (void *)rec + (seg)->rec_size)
|
||||
|
||||
/*
|
||||
* The .BTF.ext ELF section layout defined as
|
||||
* struct btf_ext_header
|
||||
* func_info subsection
|
||||
*
|
||||
* The func_info subsection layout:
|
||||
* record size for struct bpf_func_info in the func_info subsection
|
||||
* struct btf_sec_func_info for section #1
|
||||
* a list of bpf_func_info records for section #1
|
||||
* where struct bpf_func_info mimics one in include/uapi/linux/bpf.h
|
||||
* but may not be identical
|
||||
* struct btf_sec_func_info for section #2
|
||||
* a list of bpf_func_info records for section #2
|
||||
* ......
|
||||
*
|
||||
* Note that the bpf_func_info record size in .BTF.ext may not
|
||||
* be the same as the one defined in include/uapi/linux/bpf.h.
|
||||
* The loader should ensure that record_size meets minimum
|
||||
* requirement and pass the record as is to the kernel. The
|
||||
* kernel will handle the func_info properly based on its contents.
|
||||
*/
|
||||
struct btf_ext_header {
|
||||
__u16 magic;
|
||||
__u8 version;
|
||||
__u8 flags;
|
||||
__u32 hdr_len;
|
||||
|
||||
/* All offsets are in bytes relative to the end of this header */
|
||||
__u32 func_info_off;
|
||||
__u32 func_info_len;
|
||||
__u32 line_info_off;
|
||||
__u32 line_info_len;
|
||||
|
||||
/* optional part of .BTF.ext header */
|
||||
__u32 core_relo_off;
|
||||
__u32 core_relo_len;
|
||||
};
|
||||
|
||||
struct btf_ext {
|
||||
union {
|
||||
struct btf_ext_header *hdr;
|
||||
@@ -336,7 +145,7 @@ struct btf_ext {
|
||||
};
|
||||
struct btf_ext_info func_info;
|
||||
struct btf_ext_info line_info;
|
||||
struct btf_ext_info core_relo_info;
|
||||
struct btf_ext_info field_reloc_info;
|
||||
__u32 data_size;
|
||||
};
|
||||
|
||||
@@ -361,40 +170,32 @@ struct bpf_line_info_min {
|
||||
__u32 line_col;
|
||||
};
|
||||
|
||||
/* bpf_core_relo_kind encodes which aspect of captured field/type/enum value
|
||||
* has to be adjusted by relocations.
|
||||
/* bpf_field_info_kind encodes which aspect of captured field has to be
|
||||
* adjusted by relocations. Currently supported values are:
|
||||
* - BPF_FIELD_BYTE_OFFSET: field offset (in bytes);
|
||||
* - BPF_FIELD_EXISTS: field existence (1, if field exists; 0, otherwise);
|
||||
*/
|
||||
enum bpf_core_relo_kind {
|
||||
enum bpf_field_info_kind {
|
||||
BPF_FIELD_BYTE_OFFSET = 0, /* field byte offset */
|
||||
BPF_FIELD_BYTE_SIZE = 1, /* field size in bytes */
|
||||
BPF_FIELD_BYTE_SIZE = 1,
|
||||
BPF_FIELD_EXISTS = 2, /* field existence in target kernel */
|
||||
BPF_FIELD_SIGNED = 3, /* field signedness (0 - unsigned, 1 - signed) */
|
||||
BPF_FIELD_LSHIFT_U64 = 4, /* bitfield-specific left bitshift */
|
||||
BPF_FIELD_RSHIFT_U64 = 5, /* bitfield-specific right bitshift */
|
||||
BPF_TYPE_ID_LOCAL = 6, /* type ID in local BPF object */
|
||||
BPF_TYPE_ID_TARGET = 7, /* type ID in target kernel */
|
||||
BPF_TYPE_EXISTS = 8, /* type existence in target kernel */
|
||||
BPF_TYPE_SIZE = 9, /* type size in bytes */
|
||||
BPF_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */
|
||||
BPF_ENUMVAL_VALUE = 11, /* enum value integer value */
|
||||
BPF_FIELD_SIGNED = 3,
|
||||
BPF_FIELD_LSHIFT_U64 = 4,
|
||||
BPF_FIELD_RSHIFT_U64 = 5,
|
||||
};
|
||||
|
||||
/* The minimum bpf_core_relo checked by the loader
|
||||
/* The minimum bpf_field_reloc checked by the loader
|
||||
*
|
||||
* CO-RE relocation captures the following data:
|
||||
* Field relocation captures the following data:
|
||||
* - insn_off - instruction offset (in bytes) within a BPF program that needs
|
||||
* its insn->imm field to be relocated with actual field info;
|
||||
* - type_id - BTF type ID of the "root" (containing) entity of a relocatable
|
||||
* type or field;
|
||||
* field;
|
||||
* - access_str_off - offset into corresponding .BTF string section. String
|
||||
* interpretation depends on specific relocation kind:
|
||||
* - for field-based relocations, string encodes an accessed field using
|
||||
* a sequence of field and array indices, separated by colon (:). It's
|
||||
* conceptually very close to LLVM's getelementptr ([0]) instruction's
|
||||
* arguments for identifying offset to a field.
|
||||
* - for type-based relocations, strings is expected to be just "0";
|
||||
* - for enum value-based relocations, string contains an index of enum
|
||||
* value within its enum type;
|
||||
* itself encodes an accessed field using a sequence of field and array
|
||||
* indicies, separated by colon (:). It's conceptually very close to LLVM's
|
||||
* getelementptr ([0]) instruction's arguments for identifying offset to
|
||||
* a field.
|
||||
*
|
||||
* Example to provide a better feel.
|
||||
*
|
||||
@@ -425,18 +226,11 @@ enum bpf_core_relo_kind {
|
||||
*
|
||||
* [0] https://llvm.org/docs/LangRef.html#getelementptr-instruction
|
||||
*/
|
||||
struct bpf_core_relo {
|
||||
struct bpf_field_reloc {
|
||||
__u32 insn_off;
|
||||
__u32 type_id;
|
||||
__u32 access_str_off;
|
||||
enum bpf_core_relo_kind kind;
|
||||
enum bpf_field_info_kind kind;
|
||||
};
|
||||
|
||||
typedef int (*type_id_visit_fn)(__u32 *type_id, void *ctx);
|
||||
typedef int (*str_off_visit_fn)(__u32 *str_off, void *ctx);
|
||||
int btf_type_visit_type_ids(struct btf_type *t, type_id_visit_fn visit, void *ctx);
|
||||
int btf_type_visit_str_offs(struct btf_type *t, str_off_visit_fn visit, void *ctx);
|
||||
int btf_ext_visit_type_ids(struct btf_ext *btf_ext, type_id_visit_fn visit, void *ctx);
|
||||
int btf_ext_visit_str_offs(struct btf_ext *btf_ext, str_off_visit_fn visit, void *ctx);
|
||||
|
||||
#endif /* __LIBBPF_LIBBPF_INTERNAL_H */
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
#include "libbpf.h"
|
||||
#include "libbpf_internal.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
static bool grep(const char *buffer, const char *pattern)
|
||||
{
|
||||
return !!strstr(buffer, pattern);
|
||||
@@ -75,9 +78,6 @@ probe_load(enum bpf_prog_type prog_type, const struct bpf_insn *insns,
|
||||
case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
|
||||
xattr.expected_attach_type = BPF_CGROUP_INET4_CONNECT;
|
||||
break;
|
||||
case BPF_PROG_TYPE_SK_LOOKUP:
|
||||
xattr.expected_attach_type = BPF_SK_LOOKUP;
|
||||
break;
|
||||
case BPF_PROG_TYPE_KPROBE:
|
||||
xattr.kern_version = get_kernel_version();
|
||||
break;
|
||||
@@ -170,7 +170,7 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
|
||||
return btf_fd;
|
||||
}
|
||||
|
||||
static int load_local_storage_btf(void)
|
||||
static int load_sk_storage_btf(void)
|
||||
{
|
||||
const char strs[] = "\0bpf_spin_lock\0val\0cnt\0l";
|
||||
/* struct bpf_spin_lock {
|
||||
@@ -229,14 +229,12 @@ bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex)
|
||||
key_size = 0;
|
||||
break;
|
||||
case BPF_MAP_TYPE_SK_STORAGE:
|
||||
case BPF_MAP_TYPE_INODE_STORAGE:
|
||||
case BPF_MAP_TYPE_TASK_STORAGE:
|
||||
btf_key_type_id = 1;
|
||||
btf_value_type_id = 3;
|
||||
value_size = 8;
|
||||
max_entries = 0;
|
||||
map_flags = BPF_F_NO_PREALLOC;
|
||||
btf_fd = load_local_storage_btf();
|
||||
btf_fd = load_sk_storage_btf();
|
||||
if (btf_fd < 0)
|
||||
return false;
|
||||
break;
|
||||
|
||||
47
src/libbpf_util.h
Normal file
47
src/libbpf_util.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||
/* Copyright (c) 2019 Facebook */
|
||||
|
||||
#ifndef __LIBBPF_LIBBPF_UTIL_H
|
||||
#define __LIBBPF_LIBBPF_UTIL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Use these barrier functions instead of smp_[rw]mb() when they are
|
||||
* used in a libbpf header file. That way they can be built into the
|
||||
* application that uses libbpf.
|
||||
*/
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define libbpf_smp_rmb() asm volatile("" : : : "memory")
|
||||
# define libbpf_smp_wmb() asm volatile("" : : : "memory")
|
||||
# define libbpf_smp_mb() \
|
||||
asm volatile("lock; addl $0,-4(%%rsp)" : : : "memory", "cc")
|
||||
/* Hinders stores to be observed before older loads. */
|
||||
# define libbpf_smp_rwmb() asm volatile("" : : : "memory")
|
||||
#elif defined(__aarch64__)
|
||||
# define libbpf_smp_rmb() asm volatile("dmb ishld" : : : "memory")
|
||||
# define libbpf_smp_wmb() asm volatile("dmb ishst" : : : "memory")
|
||||
# define libbpf_smp_mb() asm volatile("dmb ish" : : : "memory")
|
||||
# define libbpf_smp_rwmb() libbpf_smp_mb()
|
||||
#elif defined(__arm__)
|
||||
/* These are only valid for armv7 and above */
|
||||
# define libbpf_smp_rmb() asm volatile("dmb ish" : : : "memory")
|
||||
# define libbpf_smp_wmb() asm volatile("dmb ishst" : : : "memory")
|
||||
# define libbpf_smp_mb() asm volatile("dmb ish" : : : "memory")
|
||||
# define libbpf_smp_rwmb() libbpf_smp_mb()
|
||||
#else
|
||||
/* Architecture missing native barrier functions. */
|
||||
# define libbpf_smp_rmb() __sync_synchronize()
|
||||
# define libbpf_smp_wmb() __sync_synchronize()
|
||||
# define libbpf_smp_mb() __sync_synchronize()
|
||||
# define libbpf_smp_rwmb() __sync_synchronize()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2892
src/linker.c
2892
src/linker.c
File diff suppressed because it is too large
Load Diff
654
src/netlink.c
654
src/netlink.c
@@ -4,10 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/bpf.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/pkt_cls.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
@@ -18,12 +15,13 @@
|
||||
#include "libbpf_internal.h"
|
||||
#include "nlattr.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
#ifndef SOL_NETLINK
|
||||
#define SOL_NETLINK 270
|
||||
#endif
|
||||
|
||||
typedef int (*libbpf_dump_nlmsg_t)(void *cookie, void *msg, struct nlattr **tb);
|
||||
|
||||
typedef int (*__dump_nlmsg_t)(struct nlmsghdr *nlmsg, libbpf_dump_nlmsg_t,
|
||||
void *cookie);
|
||||
|
||||
@@ -33,7 +31,7 @@ struct xdp_id_md {
|
||||
struct xdp_link_info info;
|
||||
};
|
||||
|
||||
static int libbpf_netlink_open(__u32 *nl_pid)
|
||||
int libbpf_netlink_open(__u32 *nl_pid)
|
||||
{
|
||||
struct sockaddr_nl sa;
|
||||
socklen_t addrlen;
|
||||
@@ -43,7 +41,7 @@ static int libbpf_netlink_open(__u32 *nl_pid)
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.nl_family = AF_NETLINK;
|
||||
|
||||
sock = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
|
||||
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (sock < 0)
|
||||
return -errno;
|
||||
|
||||
@@ -76,20 +74,9 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void libbpf_netlink_close(int sock)
|
||||
{
|
||||
close(sock);
|
||||
}
|
||||
|
||||
enum {
|
||||
NL_CONT,
|
||||
NL_NEXT,
|
||||
NL_DONE,
|
||||
};
|
||||
|
||||
static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
|
||||
__dump_nlmsg_t _fn, libbpf_dump_nlmsg_t fn,
|
||||
void *cookie)
|
||||
static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq,
|
||||
__dump_nlmsg_t _fn, libbpf_dump_nlmsg_t fn,
|
||||
void *cookie)
|
||||
{
|
||||
bool multipart = true;
|
||||
struct nlmsgerr *err;
|
||||
@@ -98,7 +85,6 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq,
|
||||
int len, ret;
|
||||
|
||||
while (multipart) {
|
||||
start:
|
||||
multipart = false;
|
||||
len = recv(sock, buf, sizeof(buf), 0);
|
||||
if (len < 0) {
|
||||
@@ -136,16 +122,8 @@ start:
|
||||
}
|
||||
if (_fn) {
|
||||
ret = _fn(nh, fn, cookie);
|
||||
switch (ret) {
|
||||
case NL_CONT:
|
||||
break;
|
||||
case NL_NEXT:
|
||||
goto start;
|
||||
case NL_DONE:
|
||||
return 0;
|
||||
default:
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,72 +132,72 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int libbpf_netlink_send_recv(struct nlmsghdr *nh,
|
||||
__dump_nlmsg_t parse_msg,
|
||||
libbpf_dump_nlmsg_t parse_attr,
|
||||
void *cookie)
|
||||
{
|
||||
__u32 nl_pid = 0;
|
||||
int sock, ret;
|
||||
|
||||
sock = libbpf_netlink_open(&nl_pid);
|
||||
if (sock < 0)
|
||||
return sock;
|
||||
|
||||
nh->nlmsg_pid = 0;
|
||||
nh->nlmsg_seq = time(NULL);
|
||||
|
||||
if (send(sock, nh, nh->nlmsg_len, 0) < 0) {
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = libbpf_netlink_recv(sock, nl_pid, nh->nlmsg_seq,
|
||||
parse_msg, parse_attr, cookie);
|
||||
out:
|
||||
libbpf_netlink_close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
|
||||
__u32 flags)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
int ret;
|
||||
int sock, seq = 0, ret;
|
||||
struct nlattr *nla, *nla_xdp;
|
||||
struct {
|
||||
struct nlmsghdr nh;
|
||||
struct ifinfomsg ifinfo;
|
||||
char attrbuf[64];
|
||||
} req;
|
||||
__u32 nl_pid = 0;
|
||||
|
||||
sock = libbpf_netlink_open(&nl_pid);
|
||||
if (sock < 0)
|
||||
return sock;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
req.nh.nlmsg_type = RTM_SETLINK;
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
req.nh.nlmsg_type = RTM_SETLINK;
|
||||
req.nh.nlmsg_pid = 0;
|
||||
req.nh.nlmsg_seq = ++seq;
|
||||
req.ifinfo.ifi_family = AF_UNSPEC;
|
||||
req.ifinfo.ifi_index = ifindex;
|
||||
req.ifinfo.ifi_index = ifindex;
|
||||
|
||||
nla = nlattr_begin_nested(&req.nh, sizeof(req), IFLA_XDP);
|
||||
if (!nla)
|
||||
return -EMSGSIZE;
|
||||
ret = nlattr_add(&req.nh, sizeof(req), IFLA_XDP_FD, &fd, sizeof(fd));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* started nested attribute for XDP */
|
||||
nla = (struct nlattr *)(((char *)&req)
|
||||
+ NLMSG_ALIGN(req.nh.nlmsg_len));
|
||||
nla->nla_type = NLA_F_NESTED | IFLA_XDP;
|
||||
nla->nla_len = NLA_HDRLEN;
|
||||
|
||||
/* add XDP fd */
|
||||
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
|
||||
nla_xdp->nla_type = IFLA_XDP_FD;
|
||||
nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
|
||||
memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
|
||||
nla->nla_len += nla_xdp->nla_len;
|
||||
|
||||
/* if user passed in any flags, add those too */
|
||||
if (flags) {
|
||||
ret = nlattr_add(&req.nh, sizeof(req), IFLA_XDP_FLAGS, &flags,
|
||||
sizeof(flags));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
|
||||
nla_xdp->nla_type = IFLA_XDP_FLAGS;
|
||||
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
|
||||
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
|
||||
nla->nla_len += nla_xdp->nla_len;
|
||||
}
|
||||
if (flags & XDP_FLAGS_REPLACE) {
|
||||
ret = nlattr_add(&req.nh, sizeof(req), IFLA_XDP_EXPECTED_FD,
|
||||
&old_fd, sizeof(old_fd));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
nlattr_end_nested(&req.nh, nla);
|
||||
|
||||
return libbpf_netlink_send_recv(&req.nh, NULL, NULL, NULL);
|
||||
if (flags & XDP_FLAGS_REPLACE) {
|
||||
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
|
||||
nla_xdp->nla_type = IFLA_XDP_EXPECTED_FD;
|
||||
nla_xdp->nla_len = NLA_HDRLEN + sizeof(old_fd);
|
||||
memcpy((char *)nla_xdp + NLA_HDRLEN, &old_fd, sizeof(old_fd));
|
||||
nla->nla_len += nla_xdp->nla_len;
|
||||
}
|
||||
|
||||
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
|
||||
|
||||
if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
|
||||
ret = -errno;
|
||||
goto cleanup;
|
||||
}
|
||||
ret = bpf_netlink_recv(sock, nl_pid, seq, NULL, NULL, NULL);
|
||||
|
||||
cleanup:
|
||||
close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bpf_set_link_xdp_fd_opts(int ifindex, int fd, __u32 flags,
|
||||
@@ -235,7 +213,9 @@ int bpf_set_link_xdp_fd_opts(int ifindex, int fd, __u32 flags,
|
||||
flags |= XDP_FLAGS_REPLACE;
|
||||
}
|
||||
|
||||
return __bpf_set_link_xdp_fd_replace(ifindex, fd, old_fd, flags);
|
||||
return __bpf_set_link_xdp_fd_replace(ifindex, fd,
|
||||
old_fd,
|
||||
flags);
|
||||
}
|
||||
|
||||
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
|
||||
@@ -252,7 +232,6 @@ static int __dump_link_nlmsg(struct nlmsghdr *nlh,
|
||||
|
||||
len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
|
||||
attr = (struct nlattr *) ((void *) ifi + NLMSG_ALIGN(sizeof(*ifi)));
|
||||
|
||||
if (libbpf_nla_parse(tb, IFLA_MAX, attr, len, NULL) != 0)
|
||||
return -LIBBPF_ERRNO__NLPARSE;
|
||||
|
||||
@@ -308,17 +287,9 @@ int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
|
||||
size_t info_size, __u32 flags)
|
||||
{
|
||||
struct xdp_id_md xdp_id = {};
|
||||
int sock, ret;
|
||||
__u32 nl_pid = 0;
|
||||
__u32 mask;
|
||||
int ret;
|
||||
struct {
|
||||
struct nlmsghdr nh;
|
||||
struct ifinfomsg ifm;
|
||||
} req = {
|
||||
.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
||||
.nh.nlmsg_type = RTM_GETLINK,
|
||||
.nh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
|
||||
.ifm.ifi_family = AF_PACKET,
|
||||
};
|
||||
|
||||
if (flags & ~XDP_FLAGS_MASK || !info_size)
|
||||
return -EINVAL;
|
||||
@@ -329,11 +300,14 @@ int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
|
||||
if (flags && flags & mask)
|
||||
return -EINVAL;
|
||||
|
||||
sock = libbpf_netlink_open(&nl_pid);
|
||||
if (sock < 0)
|
||||
return sock;
|
||||
|
||||
xdp_id.ifindex = ifindex;
|
||||
xdp_id.flags = flags;
|
||||
|
||||
ret = libbpf_netlink_send_recv(&req.nh, __dump_link_nlmsg,
|
||||
get_xdp_info, &xdp_id);
|
||||
ret = libbpf_nl_get_link(sock, nl_pid, get_xdp_info, &xdp_id);
|
||||
if (!ret) {
|
||||
size_t sz = min(info_size, sizeof(xdp_id.info));
|
||||
|
||||
@@ -341,6 +315,7 @@ int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
|
||||
memset((void *) info + sz, 0, info_size - sz);
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -372,403 +347,142 @@ int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef int (*qdisc_config_t)(struct nlmsghdr *nh, struct tcmsg *t,
|
||||
size_t maxsz);
|
||||
|
||||
static int clsact_config(struct nlmsghdr *nh, struct tcmsg *t, size_t maxsz)
|
||||
int libbpf_nl_get_link(int sock, unsigned int nl_pid,
|
||||
libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie)
|
||||
{
|
||||
t->tcm_parent = TC_H_CLSACT;
|
||||
t->tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0);
|
||||
|
||||
return nlattr_add(nh, maxsz, TCA_KIND, "clsact", sizeof("clsact"));
|
||||
}
|
||||
|
||||
static int attach_point_to_config(struct bpf_tc_hook *hook,
|
||||
qdisc_config_t *config)
|
||||
{
|
||||
switch (OPTS_GET(hook, attach_point, 0)) {
|
||||
case BPF_TC_INGRESS:
|
||||
case BPF_TC_EGRESS:
|
||||
case BPF_TC_INGRESS | BPF_TC_EGRESS:
|
||||
if (OPTS_GET(hook, parent, 0))
|
||||
return -EINVAL;
|
||||
*config = &clsact_config;
|
||||
return 0;
|
||||
case BPF_TC_CUSTOM:
|
||||
return -EOPNOTSUPP;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int tc_get_tcm_parent(enum bpf_tc_attach_point attach_point,
|
||||
__u32 *parent)
|
||||
{
|
||||
switch (attach_point) {
|
||||
case BPF_TC_INGRESS:
|
||||
case BPF_TC_EGRESS:
|
||||
if (*parent)
|
||||
return -EINVAL;
|
||||
*parent = TC_H_MAKE(TC_H_CLSACT,
|
||||
attach_point == BPF_TC_INGRESS ?
|
||||
TC_H_MIN_INGRESS : TC_H_MIN_EGRESS);
|
||||
break;
|
||||
case BPF_TC_CUSTOM:
|
||||
if (!*parent)
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tc_qdisc_modify(struct bpf_tc_hook *hook, int cmd, int flags)
|
||||
{
|
||||
qdisc_config_t config;
|
||||
int ret;
|
||||
struct {
|
||||
struct nlmsghdr nh;
|
||||
struct tcmsg tc;
|
||||
char buf[256];
|
||||
} req;
|
||||
struct nlmsghdr nlh;
|
||||
struct ifinfomsg ifm;
|
||||
} req = {
|
||||
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
|
||||
.nlh.nlmsg_type = RTM_GETLINK,
|
||||
.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
|
||||
.ifm.ifi_family = AF_PACKET,
|
||||
};
|
||||
int seq = time(NULL);
|
||||
|
||||
ret = attach_point_to_config(hook, &config);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
|
||||
req.nh.nlmsg_type = cmd;
|
||||
req.tc.tcm_family = AF_UNSPEC;
|
||||
req.tc.tcm_ifindex = OPTS_GET(hook, ifindex, 0);
|
||||
|
||||
ret = config(&req.nh, &req.tc, sizeof(req));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return libbpf_netlink_send_recv(&req.nh, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static int tc_qdisc_create_excl(struct bpf_tc_hook *hook)
|
||||
{
|
||||
return tc_qdisc_modify(hook, RTM_NEWQDISC, NLM_F_CREATE);
|
||||
}
|
||||
|
||||
static int tc_qdisc_delete(struct bpf_tc_hook *hook)
|
||||
{
|
||||
return tc_qdisc_modify(hook, RTM_DELQDISC, 0);
|
||||
}
|
||||
|
||||
int bpf_tc_hook_create(struct bpf_tc_hook *hook)
|
||||
{
|
||||
if (!hook || !OPTS_VALID(hook, bpf_tc_hook) ||
|
||||
OPTS_GET(hook, ifindex, 0) <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return tc_qdisc_create_excl(hook);
|
||||
}
|
||||
|
||||
static int __bpf_tc_detach(const struct bpf_tc_hook *hook,
|
||||
const struct bpf_tc_opts *opts,
|
||||
const bool flush);
|
||||
|
||||
int bpf_tc_hook_destroy(struct bpf_tc_hook *hook)
|
||||
{
|
||||
if (!hook || !OPTS_VALID(hook, bpf_tc_hook) ||
|
||||
OPTS_GET(hook, ifindex, 0) <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (OPTS_GET(hook, attach_point, 0)) {
|
||||
case BPF_TC_INGRESS:
|
||||
case BPF_TC_EGRESS:
|
||||
return __bpf_tc_detach(hook, NULL, true);
|
||||
case BPF_TC_INGRESS | BPF_TC_EGRESS:
|
||||
return tc_qdisc_delete(hook);
|
||||
case BPF_TC_CUSTOM:
|
||||
return -EOPNOTSUPP;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
struct bpf_cb_ctx {
|
||||
struct bpf_tc_opts *opts;
|
||||
bool processed;
|
||||
};
|
||||
|
||||
static int __get_tc_info(void *cookie, struct tcmsg *tc, struct nlattr **tb,
|
||||
bool unicast)
|
||||
{
|
||||
struct nlattr *tbb[TCA_BPF_MAX + 1];
|
||||
struct bpf_cb_ctx *info = cookie;
|
||||
|
||||
if (!info || !info->opts)
|
||||
return -EINVAL;
|
||||
if (unicast && info->processed)
|
||||
return -EINVAL;
|
||||
if (!tb[TCA_OPTIONS])
|
||||
return NL_CONT;
|
||||
|
||||
libbpf_nla_parse_nested(tbb, TCA_BPF_MAX, tb[TCA_OPTIONS], NULL);
|
||||
if (!tbb[TCA_BPF_ID])
|
||||
return -EINVAL;
|
||||
|
||||
OPTS_SET(info->opts, prog_id, libbpf_nla_getattr_u32(tbb[TCA_BPF_ID]));
|
||||
OPTS_SET(info->opts, handle, tc->tcm_handle);
|
||||
OPTS_SET(info->opts, priority, TC_H_MAJ(tc->tcm_info) >> 16);
|
||||
|
||||
info->processed = true;
|
||||
return unicast ? NL_NEXT : NL_DONE;
|
||||
}
|
||||
|
||||
static int get_tc_info(struct nlmsghdr *nh, libbpf_dump_nlmsg_t fn,
|
||||
void *cookie)
|
||||
{
|
||||
struct tcmsg *tc = NLMSG_DATA(nh);
|
||||
struct nlattr *tb[TCA_MAX + 1];
|
||||
|
||||
libbpf_nla_parse(tb, TCA_MAX,
|
||||
(struct nlattr *)((char *)tc + NLMSG_ALIGN(sizeof(*tc))),
|
||||
NLMSG_PAYLOAD(nh, sizeof(*tc)), NULL);
|
||||
if (!tb[TCA_KIND])
|
||||
return NL_CONT;
|
||||
return __get_tc_info(cookie, tc, tb, nh->nlmsg_flags & NLM_F_ECHO);
|
||||
}
|
||||
|
||||
static int tc_add_fd_and_name(struct nlmsghdr *nh, size_t maxsz, int fd)
|
||||
{
|
||||
struct bpf_prog_info info = {};
|
||||
__u32 info_len = sizeof(info);
|
||||
char name[256];
|
||||
int len, ret;
|
||||
|
||||
ret = bpf_obj_get_info_by_fd(fd, &info, &info_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = nlattr_add(nh, maxsz, TCA_BPF_FD, &fd, sizeof(fd));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
len = snprintf(name, sizeof(name), "%s:[%u]", info.name, info.id);
|
||||
if (len < 0)
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
if (len >= sizeof(name))
|
||||
return -ENAMETOOLONG;
|
||||
return nlattr_add(nh, maxsz, TCA_BPF_NAME, name, len + 1);
|
||||
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_link_nlmsg,
|
||||
dump_link_nlmsg, cookie);
|
||||
}
|
||||
|
||||
int bpf_tc_attach(const struct bpf_tc_hook *hook, struct bpf_tc_opts *opts)
|
||||
static int __dump_class_nlmsg(struct nlmsghdr *nlh,
|
||||
libbpf_dump_nlmsg_t dump_class_nlmsg,
|
||||
void *cookie)
|
||||
{
|
||||
struct nlattr *tb[TCA_MAX + 1], *attr;
|
||||
struct tcmsg *t = NLMSG_DATA(nlh);
|
||||
int len;
|
||||
|
||||
len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*t));
|
||||
attr = (struct nlattr *) ((void *) t + NLMSG_ALIGN(sizeof(*t)));
|
||||
if (libbpf_nla_parse(tb, TCA_MAX, attr, len, NULL) != 0)
|
||||
return -LIBBPF_ERRNO__NLPARSE;
|
||||
|
||||
return dump_class_nlmsg(cookie, t, tb);
|
||||
}
|
||||
|
||||
int libbpf_nl_get_class(int sock, unsigned int nl_pid, int ifindex,
|
||||
libbpf_dump_nlmsg_t dump_class_nlmsg, void *cookie)
|
||||
{
|
||||
__u32 protocol, bpf_flags, handle, priority, parent, prog_id, flags;
|
||||
int ret, ifindex, attach_point, prog_fd;
|
||||
struct bpf_cb_ctx info = {};
|
||||
struct nlattr *nla;
|
||||
struct {
|
||||
struct nlmsghdr nh;
|
||||
struct tcmsg tc;
|
||||
char buf[256];
|
||||
} req;
|
||||
struct nlmsghdr nlh;
|
||||
struct tcmsg t;
|
||||
} req = {
|
||||
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
|
||||
.nlh.nlmsg_type = RTM_GETTCLASS,
|
||||
.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
|
||||
.t.tcm_family = AF_UNSPEC,
|
||||
.t.tcm_ifindex = ifindex,
|
||||
};
|
||||
int seq = time(NULL);
|
||||
|
||||
if (!hook || !opts ||
|
||||
!OPTS_VALID(hook, bpf_tc_hook) ||
|
||||
!OPTS_VALID(opts, bpf_tc_opts))
|
||||
return -EINVAL;
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
ifindex = OPTS_GET(hook, ifindex, 0);
|
||||
parent = OPTS_GET(hook, parent, 0);
|
||||
attach_point = OPTS_GET(hook, attach_point, 0);
|
||||
|
||||
handle = OPTS_GET(opts, handle, 0);
|
||||
priority = OPTS_GET(opts, priority, 0);
|
||||
prog_fd = OPTS_GET(opts, prog_fd, 0);
|
||||
prog_id = OPTS_GET(opts, prog_id, 0);
|
||||
flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
if (ifindex <= 0 || !prog_fd || prog_id)
|
||||
return -EINVAL;
|
||||
if (priority > UINT16_MAX)
|
||||
return -EINVAL;
|
||||
if (flags & ~BPF_TC_F_REPLACE)
|
||||
return -EINVAL;
|
||||
|
||||
flags = (flags & BPF_TC_F_REPLACE) ? NLM_F_REPLACE : NLM_F_EXCL;
|
||||
protocol = ETH_P_ALL;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE |
|
||||
NLM_F_ECHO | flags;
|
||||
req.nh.nlmsg_type = RTM_NEWTFILTER;
|
||||
req.tc.tcm_family = AF_UNSPEC;
|
||||
req.tc.tcm_ifindex = ifindex;
|
||||
req.tc.tcm_handle = handle;
|
||||
req.tc.tcm_info = TC_H_MAKE(priority << 16, htons(protocol));
|
||||
|
||||
ret = tc_get_tcm_parent(attach_point, &parent);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
req.tc.tcm_parent = parent;
|
||||
|
||||
ret = nlattr_add(&req.nh, sizeof(req), TCA_KIND, "bpf", sizeof("bpf"));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
nla = nlattr_begin_nested(&req.nh, sizeof(req), TCA_OPTIONS);
|
||||
if (!nla)
|
||||
return -EMSGSIZE;
|
||||
ret = tc_add_fd_and_name(&req.nh, sizeof(req), prog_fd);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
bpf_flags = TCA_BPF_FLAG_ACT_DIRECT;
|
||||
ret = nlattr_add(&req.nh, sizeof(req), TCA_BPF_FLAGS, &bpf_flags,
|
||||
sizeof(bpf_flags));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
nlattr_end_nested(&req.nh, nla);
|
||||
|
||||
info.opts = opts;
|
||||
|
||||
ret = libbpf_netlink_send_recv(&req.nh, get_tc_info, NULL, &info);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!info.processed)
|
||||
return -ENOENT;
|
||||
return ret;
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_class_nlmsg,
|
||||
dump_class_nlmsg, cookie);
|
||||
}
|
||||
|
||||
static int __bpf_tc_detach(const struct bpf_tc_hook *hook,
|
||||
const struct bpf_tc_opts *opts,
|
||||
const bool flush)
|
||||
static int __dump_qdisc_nlmsg(struct nlmsghdr *nlh,
|
||||
libbpf_dump_nlmsg_t dump_qdisc_nlmsg,
|
||||
void *cookie)
|
||||
{
|
||||
struct nlattr *tb[TCA_MAX + 1], *attr;
|
||||
struct tcmsg *t = NLMSG_DATA(nlh);
|
||||
int len;
|
||||
|
||||
len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*t));
|
||||
attr = (struct nlattr *) ((void *) t + NLMSG_ALIGN(sizeof(*t)));
|
||||
if (libbpf_nla_parse(tb, TCA_MAX, attr, len, NULL) != 0)
|
||||
return -LIBBPF_ERRNO__NLPARSE;
|
||||
|
||||
return dump_qdisc_nlmsg(cookie, t, tb);
|
||||
}
|
||||
|
||||
int libbpf_nl_get_qdisc(int sock, unsigned int nl_pid, int ifindex,
|
||||
libbpf_dump_nlmsg_t dump_qdisc_nlmsg, void *cookie)
|
||||
{
|
||||
__u32 protocol = 0, handle, priority, parent, prog_id, flags;
|
||||
int ret, ifindex, attach_point, prog_fd;
|
||||
struct {
|
||||
struct nlmsghdr nh;
|
||||
struct tcmsg tc;
|
||||
char buf[256];
|
||||
} req;
|
||||
struct nlmsghdr nlh;
|
||||
struct tcmsg t;
|
||||
} req = {
|
||||
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
|
||||
.nlh.nlmsg_type = RTM_GETQDISC,
|
||||
.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
|
||||
.t.tcm_family = AF_UNSPEC,
|
||||
.t.tcm_ifindex = ifindex,
|
||||
};
|
||||
int seq = time(NULL);
|
||||
|
||||
if (!hook ||
|
||||
!OPTS_VALID(hook, bpf_tc_hook) ||
|
||||
!OPTS_VALID(opts, bpf_tc_opts))
|
||||
return -EINVAL;
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
ifindex = OPTS_GET(hook, ifindex, 0);
|
||||
parent = OPTS_GET(hook, parent, 0);
|
||||
attach_point = OPTS_GET(hook, attach_point, 0);
|
||||
|
||||
handle = OPTS_GET(opts, handle, 0);
|
||||
priority = OPTS_GET(opts, priority, 0);
|
||||
prog_fd = OPTS_GET(opts, prog_fd, 0);
|
||||
prog_id = OPTS_GET(opts, prog_id, 0);
|
||||
flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
if (ifindex <= 0 || flags || prog_fd || prog_id)
|
||||
return -EINVAL;
|
||||
if (priority > UINT16_MAX)
|
||||
return -EINVAL;
|
||||
if (flags & ~BPF_TC_F_REPLACE)
|
||||
return -EINVAL;
|
||||
if (!flush) {
|
||||
if (!handle || !priority)
|
||||
return -EINVAL;
|
||||
protocol = ETH_P_ALL;
|
||||
} else {
|
||||
if (handle || priority)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
req.nh.nlmsg_type = RTM_DELTFILTER;
|
||||
req.tc.tcm_family = AF_UNSPEC;
|
||||
req.tc.tcm_ifindex = ifindex;
|
||||
if (!flush) {
|
||||
req.tc.tcm_handle = handle;
|
||||
req.tc.tcm_info = TC_H_MAKE(priority << 16, htons(protocol));
|
||||
}
|
||||
|
||||
ret = tc_get_tcm_parent(attach_point, &parent);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
req.tc.tcm_parent = parent;
|
||||
|
||||
if (!flush) {
|
||||
ret = nlattr_add(&req.nh, sizeof(req), TCA_KIND,
|
||||
"bpf", sizeof("bpf"));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return libbpf_netlink_send_recv(&req.nh, NULL, NULL, NULL);
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_qdisc_nlmsg,
|
||||
dump_qdisc_nlmsg, cookie);
|
||||
}
|
||||
|
||||
int bpf_tc_detach(const struct bpf_tc_hook *hook,
|
||||
const struct bpf_tc_opts *opts)
|
||||
static int __dump_filter_nlmsg(struct nlmsghdr *nlh,
|
||||
libbpf_dump_nlmsg_t dump_filter_nlmsg,
|
||||
void *cookie)
|
||||
{
|
||||
return !opts ? -EINVAL : __bpf_tc_detach(hook, opts, false);
|
||||
struct nlattr *tb[TCA_MAX + 1], *attr;
|
||||
struct tcmsg *t = NLMSG_DATA(nlh);
|
||||
int len;
|
||||
|
||||
len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*t));
|
||||
attr = (struct nlattr *) ((void *) t + NLMSG_ALIGN(sizeof(*t)));
|
||||
if (libbpf_nla_parse(tb, TCA_MAX, attr, len, NULL) != 0)
|
||||
return -LIBBPF_ERRNO__NLPARSE;
|
||||
|
||||
return dump_filter_nlmsg(cookie, t, tb);
|
||||
}
|
||||
|
||||
int bpf_tc_query(const struct bpf_tc_hook *hook, struct bpf_tc_opts *opts)
|
||||
int libbpf_nl_get_filter(int sock, unsigned int nl_pid, int ifindex, int handle,
|
||||
libbpf_dump_nlmsg_t dump_filter_nlmsg, void *cookie)
|
||||
{
|
||||
__u32 protocol, handle, priority, parent, prog_id, flags;
|
||||
int ret, ifindex, attach_point, prog_fd;
|
||||
struct bpf_cb_ctx info = {};
|
||||
struct {
|
||||
struct nlmsghdr nh;
|
||||
struct tcmsg tc;
|
||||
char buf[256];
|
||||
} req;
|
||||
struct nlmsghdr nlh;
|
||||
struct tcmsg t;
|
||||
} req = {
|
||||
.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)),
|
||||
.nlh.nlmsg_type = RTM_GETTFILTER,
|
||||
.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST,
|
||||
.t.tcm_family = AF_UNSPEC,
|
||||
.t.tcm_ifindex = ifindex,
|
||||
.t.tcm_parent = handle,
|
||||
};
|
||||
int seq = time(NULL);
|
||||
|
||||
if (!hook || !opts ||
|
||||
!OPTS_VALID(hook, bpf_tc_hook) ||
|
||||
!OPTS_VALID(opts, bpf_tc_opts))
|
||||
return -EINVAL;
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
ifindex = OPTS_GET(hook, ifindex, 0);
|
||||
parent = OPTS_GET(hook, parent, 0);
|
||||
attach_point = OPTS_GET(hook, attach_point, 0);
|
||||
|
||||
handle = OPTS_GET(opts, handle, 0);
|
||||
priority = OPTS_GET(opts, priority, 0);
|
||||
prog_fd = OPTS_GET(opts, prog_fd, 0);
|
||||
prog_id = OPTS_GET(opts, prog_id, 0);
|
||||
flags = OPTS_GET(opts, flags, 0);
|
||||
|
||||
if (ifindex <= 0 || flags || prog_fd || prog_id ||
|
||||
!handle || !priority)
|
||||
return -EINVAL;
|
||||
if (priority > UINT16_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
protocol = ETH_P_ALL;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
|
||||
req.nh.nlmsg_flags = NLM_F_REQUEST;
|
||||
req.nh.nlmsg_type = RTM_GETTFILTER;
|
||||
req.tc.tcm_family = AF_UNSPEC;
|
||||
req.tc.tcm_ifindex = ifindex;
|
||||
req.tc.tcm_handle = handle;
|
||||
req.tc.tcm_info = TC_H_MAKE(priority << 16, htons(protocol));
|
||||
|
||||
ret = tc_get_tcm_parent(attach_point, &parent);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
req.tc.tcm_parent = parent;
|
||||
|
||||
ret = nlattr_add(&req.nh, sizeof(req), TCA_KIND, "bpf", sizeof("bpf"));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
info.opts = opts;
|
||||
|
||||
ret = libbpf_netlink_send_recv(&req.nh, get_tc_info, NULL, &info);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!info.processed)
|
||||
return -ENOENT;
|
||||
return ret;
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_filter_nlmsg,
|
||||
dump_filter_nlmsg, cookie);
|
||||
}
|
||||
|
||||
@@ -7,11 +7,14 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include "nlattr.h"
|
||||
#include "libbpf_internal.h"
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
static uint16_t nla_attr_minlen[LIBBPF_NLA_TYPE_MAX+1] = {
|
||||
[LIBBPF_NLA_U8] = sizeof(uint8_t),
|
||||
|
||||
48
src/nlattr.h
48
src/nlattr.h
@@ -10,10 +10,7 @@
|
||||
#define __LIBBPF_NLATTR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <linux/netlink.h>
|
||||
|
||||
/* avoid multiple definition of netlink features */
|
||||
#define __LINUX_NETLINK_H
|
||||
|
||||
@@ -106,49 +103,4 @@ int libbpf_nla_parse_nested(struct nlattr *tb[], int maxtype,
|
||||
|
||||
int libbpf_nla_dump_errormsg(struct nlmsghdr *nlh);
|
||||
|
||||
static inline struct nlattr *nla_data(struct nlattr *nla)
|
||||
{
|
||||
return (struct nlattr *)((char *)nla + NLA_HDRLEN);
|
||||
}
|
||||
|
||||
static inline struct nlattr *nh_tail(struct nlmsghdr *nh)
|
||||
{
|
||||
return (struct nlattr *)((char *)nh + NLMSG_ALIGN(nh->nlmsg_len));
|
||||
}
|
||||
|
||||
static inline int nlattr_add(struct nlmsghdr *nh, size_t maxsz, int type,
|
||||
const void *data, int len)
|
||||
{
|
||||
struct nlattr *nla;
|
||||
|
||||
if (NLMSG_ALIGN(nh->nlmsg_len) + NLA_ALIGN(NLA_HDRLEN + len) > maxsz)
|
||||
return -EMSGSIZE;
|
||||
if (!!data != !!len)
|
||||
return -EINVAL;
|
||||
|
||||
nla = nh_tail(nh);
|
||||
nla->nla_type = type;
|
||||
nla->nla_len = NLA_HDRLEN + len;
|
||||
if (data)
|
||||
memcpy(nla_data(nla), data, len);
|
||||
nh->nlmsg_len = NLMSG_ALIGN(nh->nlmsg_len) + NLA_ALIGN(nla->nla_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct nlattr *nlattr_begin_nested(struct nlmsghdr *nh,
|
||||
size_t maxsz, int type)
|
||||
{
|
||||
struct nlattr *tail;
|
||||
|
||||
tail = nh_tail(nh);
|
||||
if (nlattr_add(nh, maxsz, type | NLA_F_NESTED, NULL, 0))
|
||||
return NULL;
|
||||
return tail;
|
||||
}
|
||||
|
||||
static inline void nlattr_end_nested(struct nlmsghdr *nh, struct nlattr *tail)
|
||||
{
|
||||
tail->nla_len = (char *)nh_tail(nh) - (char *)tail;
|
||||
}
|
||||
|
||||
#endif /* __LIBBPF_NLATTR_H */
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
#include <asm/barrier.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <tools/libc_compat.h>
|
||||
|
||||
#include "libbpf.h"
|
||||
#include "libbpf_internal.h"
|
||||
#include "bpf.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
struct ring {
|
||||
ring_buffer_sample_fn sample_cb;
|
||||
void *ctx;
|
||||
@@ -78,12 +82,12 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tmp = libbpf_reallocarray(rb->rings, rb->ring_cnt + 1, sizeof(*rb->rings));
|
||||
tmp = reallocarray(rb->rings, rb->ring_cnt + 1, sizeof(*rb->rings));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
rb->rings = tmp;
|
||||
|
||||
tmp = libbpf_reallocarray(rb->events, rb->ring_cnt + 1, sizeof(*rb->events));
|
||||
tmp = reallocarray(rb->events, rb->ring_cnt + 1, sizeof(*rb->events));
|
||||
if (!tmp)
|
||||
return -ENOMEM;
|
||||
rb->events = tmp;
|
||||
@@ -202,11 +206,9 @@ static inline int roundup_len(__u32 len)
|
||||
return (len + 7) / 8 * 8;
|
||||
}
|
||||
|
||||
static int64_t ringbuf_process_ring(struct ring* r)
|
||||
static int ringbuf_process_ring(struct ring* r)
|
||||
{
|
||||
int *len_ptr, len, err;
|
||||
/* 64-bit to avoid overflow in case of extreme application behavior */
|
||||
int64_t cnt = 0;
|
||||
int *len_ptr, len, err, cnt = 0;
|
||||
unsigned long cons_pos, prod_pos;
|
||||
bool got_new_data;
|
||||
void *sample;
|
||||
@@ -229,7 +231,7 @@ static int64_t ringbuf_process_ring(struct ring* r)
|
||||
if ((len & BPF_RINGBUF_DISCARD_BIT) == 0) {
|
||||
sample = (void *)len_ptr + BPF_RINGBUF_HDR_SZ;
|
||||
err = r->sample_cb(r->ctx, sample, len);
|
||||
if (err < 0) {
|
||||
if (err) {
|
||||
/* update consumer pos and bail out */
|
||||
smp_store_release(r->consumer_pos,
|
||||
cons_pos);
|
||||
@@ -246,14 +248,12 @@ done:
|
||||
}
|
||||
|
||||
/* Consume available ring buffer(s) data without event polling.
|
||||
* Returns number of records consumed across all registered ring buffers (or
|
||||
* INT_MAX, whichever is less), or negative number if any of the callbacks
|
||||
* return error.
|
||||
* Returns number of records consumed across all registered ring buffers, or
|
||||
* negative number if any of the callbacks return error.
|
||||
*/
|
||||
int ring_buffer__consume(struct ring_buffer *rb)
|
||||
{
|
||||
int64_t err, res = 0;
|
||||
int i;
|
||||
int i, err, res = 0;
|
||||
|
||||
for (i = 0; i < rb->ring_cnt; i++) {
|
||||
struct ring *ring = &rb->rings[i];
|
||||
@@ -263,24 +263,18 @@ int ring_buffer__consume(struct ring_buffer *rb)
|
||||
return err;
|
||||
res += err;
|
||||
}
|
||||
if (res > INT_MAX)
|
||||
return INT_MAX;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Poll for available data and consume records, if any are available.
|
||||
* Returns number of records consumed (or INT_MAX, whichever is less), or
|
||||
* negative number, if any of the registered callbacks returned error.
|
||||
* Returns number of records consumed, or negative number, if any of the
|
||||
* registered callbacks returned error.
|
||||
*/
|
||||
int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
|
||||
{
|
||||
int i, cnt;
|
||||
int64_t err, res = 0;
|
||||
int i, cnt, err, res = 0;
|
||||
|
||||
cnt = epoll_wait(rb->epoll_fd, rb->events, rb->ring_cnt, timeout_ms);
|
||||
if (cnt < 0)
|
||||
return -errno;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
__u32 ring_id = rb->events[i].data.fd;
|
||||
struct ring *ring = &rb->rings[ring_id];
|
||||
@@ -288,15 +282,7 @@ int ring_buffer__poll(struct ring_buffer *rb, int timeout_ms)
|
||||
err = ringbuf_process_ring(ring);
|
||||
if (err < 0)
|
||||
return err;
|
||||
res += err;
|
||||
res += cnt;
|
||||
}
|
||||
if (res > INT_MAX)
|
||||
return INT_MAX;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Get an fd that can be used to sleep until data is available in the ring(s) */
|
||||
int ring_buffer__epoll_fd(const struct ring_buffer *rb)
|
||||
{
|
||||
return rb->epoll_fd;
|
||||
return cnt < 0 ? -errno : res;
|
||||
}
|
||||
|
||||
176
src/strset.c
176
src/strset.c
@@ -1,176 +0,0 @@
|
||||
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
/* Copyright (c) 2021 Facebook */
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <linux/err.h>
|
||||
#include "hashmap.h"
|
||||
#include "libbpf_internal.h"
|
||||
#include "strset.h"
|
||||
|
||||
struct strset {
|
||||
void *strs_data;
|
||||
size_t strs_data_len;
|
||||
size_t strs_data_cap;
|
||||
size_t strs_data_max_len;
|
||||
|
||||
/* lookup index for each unique string in strings set */
|
||||
struct hashmap *strs_hash;
|
||||
};
|
||||
|
||||
static size_t strset_hash_fn(const void *key, void *ctx)
|
||||
{
|
||||
const struct strset *s = ctx;
|
||||
const char *str = s->strs_data + (long)key;
|
||||
|
||||
return str_hash(str);
|
||||
}
|
||||
|
||||
static bool strset_equal_fn(const void *key1, const void *key2, void *ctx)
|
||||
{
|
||||
const struct strset *s = ctx;
|
||||
const char *str1 = s->strs_data + (long)key1;
|
||||
const char *str2 = s->strs_data + (long)key2;
|
||||
|
||||
return strcmp(str1, str2) == 0;
|
||||
}
|
||||
|
||||
struct strset *strset__new(size_t max_data_sz, const char *init_data, size_t init_data_sz)
|
||||
{
|
||||
struct strset *set = calloc(1, sizeof(*set));
|
||||
struct hashmap *hash;
|
||||
int err = -ENOMEM;
|
||||
|
||||
if (!set)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
hash = hashmap__new(strset_hash_fn, strset_equal_fn, set);
|
||||
if (IS_ERR(hash))
|
||||
goto err_out;
|
||||
|
||||
set->strs_data_max_len = max_data_sz;
|
||||
set->strs_hash = hash;
|
||||
|
||||
if (init_data) {
|
||||
long off;
|
||||
|
||||
set->strs_data = malloc(init_data_sz);
|
||||
if (!set->strs_data)
|
||||
goto err_out;
|
||||
|
||||
memcpy(set->strs_data, init_data, init_data_sz);
|
||||
set->strs_data_len = init_data_sz;
|
||||
set->strs_data_cap = init_data_sz;
|
||||
|
||||
for (off = 0; off < set->strs_data_len; off += strlen(set->strs_data + off) + 1) {
|
||||
/* hashmap__add() returns EEXIST if string with the same
|
||||
* content already is in the hash map
|
||||
*/
|
||||
err = hashmap__add(hash, (void *)off, (void *)off);
|
||||
if (err == -EEXIST)
|
||||
continue; /* duplicate */
|
||||
if (err)
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
|
||||
return set;
|
||||
err_out:
|
||||
strset__free(set);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
void strset__free(struct strset *set)
|
||||
{
|
||||
if (IS_ERR_OR_NULL(set))
|
||||
return;
|
||||
|
||||
hashmap__free(set->strs_hash);
|
||||
free(set->strs_data);
|
||||
}
|
||||
|
||||
size_t strset__data_size(const struct strset *set)
|
||||
{
|
||||
return set->strs_data_len;
|
||||
}
|
||||
|
||||
const char *strset__data(const struct strset *set)
|
||||
{
|
||||
return set->strs_data;
|
||||
}
|
||||
|
||||
static void *strset_add_str_mem(struct strset *set, size_t add_sz)
|
||||
{
|
||||
return libbpf_add_mem(&set->strs_data, &set->strs_data_cap, 1,
|
||||
set->strs_data_len, set->strs_data_max_len, add_sz);
|
||||
}
|
||||
|
||||
/* Find string offset that corresponds to a given string *s*.
|
||||
* Returns:
|
||||
* - >0 offset into string data, if string is found;
|
||||
* - -ENOENT, if string is not in the string data;
|
||||
* - <0, on any other error.
|
||||
*/
|
||||
int strset__find_str(struct strset *set, const char *s)
|
||||
{
|
||||
long old_off, new_off, len;
|
||||
void *p;
|
||||
|
||||
/* see strset__add_str() for why we do this */
|
||||
len = strlen(s) + 1;
|
||||
p = strset_add_str_mem(set, len);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
new_off = set->strs_data_len;
|
||||
memcpy(p, s, len);
|
||||
|
||||
if (hashmap__find(set->strs_hash, (void *)new_off, (void **)&old_off))
|
||||
return old_off;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Add a string s to the string data. If the string already exists, return its
|
||||
* offset within string data.
|
||||
* Returns:
|
||||
* - > 0 offset into string data, on success;
|
||||
* - < 0, on error.
|
||||
*/
|
||||
int strset__add_str(struct strset *set, const char *s)
|
||||
{
|
||||
long old_off, new_off, len;
|
||||
void *p;
|
||||
int err;
|
||||
|
||||
/* Hashmap keys are always offsets within set->strs_data, so to even
|
||||
* look up some string from the "outside", we need to first append it
|
||||
* at the end, so that it can be addressed with an offset. Luckily,
|
||||
* until set->strs_data_len is incremented, that string is just a piece
|
||||
* of garbage for the rest of the code, so no harm, no foul. On the
|
||||
* other hand, if the string is unique, it's already appended and
|
||||
* ready to be used, only a simple set->strs_data_len increment away.
|
||||
*/
|
||||
len = strlen(s) + 1;
|
||||
p = strset_add_str_mem(set, len);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
new_off = set->strs_data_len;
|
||||
memcpy(p, s, len);
|
||||
|
||||
/* Now attempt to add the string, but only if the string with the same
|
||||
* contents doesn't exist already (HASHMAP_ADD strategy). If such
|
||||
* string exists, we'll get its offset in old_off (that's old_key).
|
||||
*/
|
||||
err = hashmap__insert(set->strs_hash, (void *)new_off, (void *)new_off,
|
||||
HASHMAP_ADD, (const void **)&old_off, NULL);
|
||||
if (err == -EEXIST)
|
||||
return old_off; /* duplicated string, return existing offset */
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
set->strs_data_len += len; /* new unique string, adjust data length */
|
||||
return new_off;
|
||||
}
|
||||
21
src/strset.h
21
src/strset.h
@@ -1,21 +0,0 @@
|
||||
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
||||
|
||||
/* Copyright (c) 2021 Facebook */
|
||||
#ifndef __LIBBPF_STRSET_H
|
||||
#define __LIBBPF_STRSET_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct strset;
|
||||
|
||||
struct strset *strset__new(size_t max_data_sz, const char *init_data, size_t init_data_sz);
|
||||
void strset__free(struct strset *set);
|
||||
|
||||
const char *strset__data(const struct strset *set);
|
||||
size_t strset__data_size(const struct strset *set);
|
||||
|
||||
int strset__find_str(struct strset *set, const char *s);
|
||||
int strset__add_str(struct strset *set, const char *s);
|
||||
|
||||
#endif /* __LIBBPF_STRSET_H */
|
||||
118
src/xsk.h
118
src/xsk.h
@@ -3,8 +3,7 @@
|
||||
/*
|
||||
* AF_XDP user-space access library.
|
||||
*
|
||||
* Copyright (c) 2018 - 2019 Intel Corporation.
|
||||
* Copyright (c) 2019 Facebook
|
||||
* Copyright(c) 2018 - 2019 Intel Corporation.
|
||||
*
|
||||
* Author(s): Magnus Karlsson <magnus.karlsson@intel.com>
|
||||
*/
|
||||
@@ -14,80 +13,15 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <linux/if_xdp.h>
|
||||
|
||||
#include "libbpf.h"
|
||||
#include "libbpf_util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Load-Acquire Store-Release barriers used by the XDP socket
|
||||
* library. The following macros should *NOT* be considered part of
|
||||
* the xsk.h API, and is subject to change anytime.
|
||||
*
|
||||
* LIBRARY INTERNAL
|
||||
*/
|
||||
|
||||
#define __XSK_READ_ONCE(x) (*(volatile typeof(x) *)&x)
|
||||
#define __XSK_WRITE_ONCE(x, v) (*(volatile typeof(x) *)&x) = (v)
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define libbpf_smp_store_release(p, v) \
|
||||
do { \
|
||||
asm volatile("" : : : "memory"); \
|
||||
__XSK_WRITE_ONCE(*p, v); \
|
||||
} while (0)
|
||||
# define libbpf_smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1 = __XSK_READ_ONCE(*p); \
|
||||
asm volatile("" : : : "memory"); \
|
||||
___p1; \
|
||||
})
|
||||
#elif defined(__aarch64__)
|
||||
# define libbpf_smp_store_release(p, v) \
|
||||
asm volatile ("stlr %w1, %0" : "=Q" (*p) : "r" (v) : "memory")
|
||||
# define libbpf_smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1; \
|
||||
asm volatile ("ldar %w0, %1" \
|
||||
: "=r" (___p1) : "Q" (*p) : "memory"); \
|
||||
___p1; \
|
||||
})
|
||||
#elif defined(__riscv)
|
||||
# define libbpf_smp_store_release(p, v) \
|
||||
do { \
|
||||
asm volatile ("fence rw,w" : : : "memory"); \
|
||||
__XSK_WRITE_ONCE(*p, v); \
|
||||
} while (0)
|
||||
# define libbpf_smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1 = __XSK_READ_ONCE(*p); \
|
||||
asm volatile ("fence r,rw" : : : "memory"); \
|
||||
___p1; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifndef libbpf_smp_store_release
|
||||
#define libbpf_smp_store_release(p, v) \
|
||||
do { \
|
||||
__sync_synchronize(); \
|
||||
__XSK_WRITE_ONCE(*p, v); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef libbpf_smp_load_acquire
|
||||
#define libbpf_smp_load_acquire(p) \
|
||||
({ \
|
||||
typeof(*p) ___p1 = __XSK_READ_ONCE(*p); \
|
||||
__sync_synchronize(); \
|
||||
___p1; \
|
||||
})
|
||||
#endif
|
||||
|
||||
/* LIBRARY INTERNAL -- END */
|
||||
|
||||
/* Do not access these members directly. Use the functions below. */
|
||||
#define DEFINE_XSK_RING(name) \
|
||||
struct name { \
|
||||
@@ -162,8 +96,7 @@ static inline __u32 xsk_prod_nb_free(struct xsk_ring_prod *r, __u32 nb)
|
||||
* this function. Without this optimization it whould have been
|
||||
* free_entries = r->cached_prod - r->cached_cons + r->size.
|
||||
*/
|
||||
r->cached_cons = libbpf_smp_load_acquire(r->consumer);
|
||||
r->cached_cons += r->size;
|
||||
r->cached_cons = *r->consumer + r->size;
|
||||
|
||||
return r->cached_cons - r->cached_prod;
|
||||
}
|
||||
@@ -173,14 +106,15 @@ static inline __u32 xsk_cons_nb_avail(struct xsk_ring_cons *r, __u32 nb)
|
||||
__u32 entries = r->cached_prod - r->cached_cons;
|
||||
|
||||
if (entries == 0) {
|
||||
r->cached_prod = libbpf_smp_load_acquire(r->producer);
|
||||
r->cached_prod = *r->producer;
|
||||
entries = r->cached_prod - r->cached_cons;
|
||||
}
|
||||
|
||||
return (entries > nb) ? nb : entries;
|
||||
}
|
||||
|
||||
static inline __u32 xsk_ring_prod__reserve(struct xsk_ring_prod *prod, __u32 nb, __u32 *idx)
|
||||
static inline size_t xsk_ring_prod__reserve(struct xsk_ring_prod *prod,
|
||||
size_t nb, __u32 *idx)
|
||||
{
|
||||
if (xsk_prod_nb_free(prod, nb) < nb)
|
||||
return 0;
|
||||
@@ -191,19 +125,27 @@ static inline __u32 xsk_ring_prod__reserve(struct xsk_ring_prod *prod, __u32 nb,
|
||||
return nb;
|
||||
}
|
||||
|
||||
static inline void xsk_ring_prod__submit(struct xsk_ring_prod *prod, __u32 nb)
|
||||
static inline void xsk_ring_prod__submit(struct xsk_ring_prod *prod, size_t nb)
|
||||
{
|
||||
/* Make sure everything has been written to the ring before indicating
|
||||
* this to the kernel by writing the producer pointer.
|
||||
*/
|
||||
libbpf_smp_store_release(prod->producer, *prod->producer + nb);
|
||||
libbpf_smp_wmb();
|
||||
|
||||
*prod->producer += nb;
|
||||
}
|
||||
|
||||
static inline __u32 xsk_ring_cons__peek(struct xsk_ring_cons *cons, __u32 nb, __u32 *idx)
|
||||
static inline size_t xsk_ring_cons__peek(struct xsk_ring_cons *cons,
|
||||
size_t nb, __u32 *idx)
|
||||
{
|
||||
__u32 entries = xsk_cons_nb_avail(cons, nb);
|
||||
size_t entries = xsk_cons_nb_avail(cons, nb);
|
||||
|
||||
if (entries > 0) {
|
||||
/* Make sure we do not speculatively read the data before
|
||||
* we have received the packet buffers from the ring.
|
||||
*/
|
||||
libbpf_smp_rmb();
|
||||
|
||||
*idx = cons->cached_cons;
|
||||
cons->cached_cons += entries;
|
||||
}
|
||||
@@ -211,18 +153,14 @@ static inline __u32 xsk_ring_cons__peek(struct xsk_ring_cons *cons, __u32 nb, __
|
||||
return entries;
|
||||
}
|
||||
|
||||
static inline void xsk_ring_cons__cancel(struct xsk_ring_cons *cons, __u32 nb)
|
||||
{
|
||||
cons->cached_cons -= nb;
|
||||
}
|
||||
|
||||
static inline void xsk_ring_cons__release(struct xsk_ring_cons *cons, __u32 nb)
|
||||
static inline void xsk_ring_cons__release(struct xsk_ring_cons *cons, size_t nb)
|
||||
{
|
||||
/* Make sure data has been read before indicating we are done
|
||||
* with the entries by updating the consumer pointer.
|
||||
*/
|
||||
libbpf_smp_store_release(cons->consumer, *cons->consumer + nb);
|
||||
libbpf_smp_rwmb();
|
||||
|
||||
*cons->consumer += nb;
|
||||
}
|
||||
|
||||
static inline void *xsk_umem__get_data(void *umem_area, __u64 addr)
|
||||
@@ -263,11 +201,6 @@ struct xsk_umem_config {
|
||||
__u32 flags;
|
||||
};
|
||||
|
||||
LIBBPF_API int xsk_setup_xdp_prog(int ifindex,
|
||||
int *xsks_map_fd);
|
||||
LIBBPF_API int xsk_socket__update_xskmap(struct xsk_socket *xsk,
|
||||
int xsks_map_fd);
|
||||
|
||||
/* Flags for the libbpf_flags field. */
|
||||
#define XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD (1 << 0)
|
||||
|
||||
@@ -301,15 +234,6 @@ LIBBPF_API int xsk_socket__create(struct xsk_socket **xsk,
|
||||
struct xsk_ring_cons *rx,
|
||||
struct xsk_ring_prod *tx,
|
||||
const struct xsk_socket_config *config);
|
||||
LIBBPF_API int
|
||||
xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
const char *ifname,
|
||||
__u32 queue_id, struct xsk_umem *umem,
|
||||
struct xsk_ring_cons *rx,
|
||||
struct xsk_ring_prod *tx,
|
||||
struct xsk_ring_prod *fill,
|
||||
struct xsk_ring_cons *comp,
|
||||
const struct xsk_socket_config *config);
|
||||
|
||||
/* Returns 0 for success and -EBUSY if the umem is still in use. */
|
||||
LIBBPF_API int xsk_umem__delete(struct xsk_umem *umem);
|
||||
|
||||
@@ -6,7 +6,7 @@ CONT_NAME="${CONT_NAME:-libbpf-debian-$DEBIAN_RELEASE}"
|
||||
ENV_VARS="${ENV_VARS:-}"
|
||||
DOCKER_RUN="${DOCKER_RUN:-docker run}"
|
||||
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
||||
ADDITIONAL_DEPS=(clang pkg-config gcc-10)
|
||||
ADDITIONAL_DEPS=(clang pkg-config gcc-8)
|
||||
CFLAGS="-g -O2 -Werror -Wall"
|
||||
|
||||
function info() {
|
||||
@@ -21,7 +21,7 @@ function docker_exec() {
|
||||
docker exec $ENV_VARS -it $CONT_NAME "$@"
|
||||
}
|
||||
|
||||
set -eu
|
||||
set -e
|
||||
|
||||
source "$(dirname $0)/travis_wait.bash"
|
||||
|
||||
@@ -31,6 +31,7 @@ for phase in "${PHASES[@]}"; do
|
||||
info "Setup phase"
|
||||
info "Using Debian $DEBIAN_RELEASE"
|
||||
|
||||
sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||
docker --version
|
||||
|
||||
docker pull debian:$DEBIAN_RELEASE
|
||||
@@ -40,18 +41,17 @@ for phase in "${PHASES[@]}"; do
|
||||
-dit --net=host debian:$DEBIAN_RELEASE /bin/bash
|
||||
docker_exec bash -c "echo deb-src http://deb.debian.org/debian $DEBIAN_RELEASE main >>/etc/apt/sources.list"
|
||||
docker_exec apt-get -y update
|
||||
docker_exec apt-get -y install aptitude
|
||||
docker_exec aptitude -y build-dep libelf-dev
|
||||
docker_exec aptitude -y install libelf-dev
|
||||
docker_exec aptitude -y install "${ADDITIONAL_DEPS[@]}"
|
||||
docker_exec apt-get -y build-dep libelf-dev
|
||||
docker_exec apt-get -y install libelf-dev
|
||||
docker_exec apt-get -y install "${ADDITIONAL_DEPS[@]}"
|
||||
;;
|
||||
RUN|RUN_CLANG|RUN_GCC10|RUN_ASAN|RUN_CLANG_ASAN|RUN_GCC10_ASAN)
|
||||
RUN|RUN_CLANG|RUN_GCC8|RUN_ASAN|RUN_CLANG_ASAN|RUN_GCC8_ASAN)
|
||||
if [[ "$phase" = *"CLANG"* ]]; then
|
||||
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||
CC="clang"
|
||||
elif [[ "$phase" = *"GCC10"* ]]; then
|
||||
ENV_VARS="-e CC=gcc-10 -e CXX=g++-10"
|
||||
CC="gcc-10"
|
||||
elif [[ "$phase" = *"GCC8"* ]]; then
|
||||
ENV_VARS="-e CC=gcc-8 -e CXX=g++-8"
|
||||
CC="gcc-8"
|
||||
else
|
||||
CFLAGS="${CFLAGS} -Wno-stringop-truncation"
|
||||
fi
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -eux
|
||||
set -e
|
||||
set -x
|
||||
|
||||
RELEASE="focal"
|
||||
RELEASE="bionic"
|
||||
|
||||
echo "deb-src http://archive.ubuntu.com/ubuntu/ $RELEASE main restricted universe multiverse" >>/etc/apt/sources.list
|
||||
|
||||
apt-get update
|
||||
apt-get install -y pkg-config
|
||||
apt-get -y build-dep libelf-dev
|
||||
apt-get install -y libelf-dev pkg-config
|
||||
|
||||
source "$(dirname $0)/travis_wait.bash"
|
||||
|
||||
cd $REPO_ROOT
|
||||
|
||||
CFLAGS="-g -O2 -Werror -Wall -fsanitize=address,undefined -Wno-stringop-truncation"
|
||||
CFLAGS="-g -O2 -Werror -Wall -fsanitize=address,undefined"
|
||||
mkdir build install
|
||||
cc --version
|
||||
make -j$((4*$(nproc))) CFLAGS="${CFLAGS}" -C ./src -B OBJDIR=../build
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
|
||||
travis_fold start build_pahole "Building pahole"
|
||||
set -eux
|
||||
|
||||
CWD=$(pwd)
|
||||
REPO_PATH=$1
|
||||
@@ -27,4 +23,3 @@ export LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-}:/usr/local/lib
|
||||
ldd $(which pahole)
|
||||
pahole --version
|
||||
|
||||
travis_fold end build_pahole
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
set -euxo pipefail
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
|
||||
travis_fold start prepare_selftests "Building selftests"
|
||||
|
||||
sudo apt-get -y install python-docutils # for rst2man
|
||||
|
||||
LLVM_VER=13
|
||||
LLVM_VER=11
|
||||
LIBBPF_PATH="${REPO_ROOT}"
|
||||
REPO_PATH="travis-ci/vmtest/bpf-next"
|
||||
|
||||
@@ -17,18 +11,11 @@ if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then
|
||||
(cd "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT})
|
||||
fi
|
||||
|
||||
if [[ "${KERNEL}" = 'LATEST' ]]; then
|
||||
VMLINUX_H=
|
||||
else
|
||||
VMLINUX_H=${VMTEST_ROOT}/vmlinux.h
|
||||
fi
|
||||
|
||||
make \
|
||||
CLANG=clang-${LLVM_VER} \
|
||||
LLC=llc-${LLVM_VER} \
|
||||
LLVM_STRIP=llvm-strip-${LLVM_VER} \
|
||||
VMLINUX_BTF="${VMLINUX_BTF}" \
|
||||
VMLINUX_H=${VMLINUX_H} \
|
||||
-C "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
|
||||
-j $((4*$(nproc)))
|
||||
mkdir ${LIBBPF_PATH}/selftests
|
||||
@@ -39,5 +26,3 @@ rm selftests/bpf/.gitignore
|
||||
git add selftests
|
||||
|
||||
git add "${VMTEST_ROOT}/configs/blacklist"
|
||||
|
||||
travis_fold end prepare_selftests
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
set -eux
|
||||
|
||||
CWD=$(pwd)
|
||||
LIBBPF_PATH=$(pwd)
|
||||
@@ -10,35 +8,17 @@ REPO_PATH=$1
|
||||
|
||||
BPF_NEXT_ORIGIN=https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
|
||||
LINUX_SHA=$(cat ${LIBBPF_PATH}/CHECKPOINT-COMMIT)
|
||||
SNAPSHOT_URL=https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/snapshot/bpf-next-${LINUX_SHA}.tar.gz
|
||||
|
||||
echo REPO_PATH = ${REPO_PATH}
|
||||
echo LINUX_SHA = ${LINUX_SHA}
|
||||
|
||||
if [ ! -d "${REPO_PATH}" ]; then
|
||||
echo
|
||||
travis_fold start pull_kernel_srcs "Fetching kernel sources"
|
||||
|
||||
mkdir -p $(dirname "${REPO_PATH}")
|
||||
cd $(dirname "${REPO_PATH}")
|
||||
# attempt to fetch desired bpf-next repo snapshot
|
||||
if wget ${SNAPSHOT_URL} && tar xf bpf-next-${LINUX_SHA}.tar.gz ; then
|
||||
mv bpf-next-${LINUX_SHA} $(basename ${REPO_PATH})
|
||||
else
|
||||
# but fallback to git fetch approach if that fails
|
||||
mkdir -p $(basename ${REPO_PATH})
|
||||
cd $(basename ${REPO_PATH})
|
||||
git init
|
||||
git remote add bpf-next ${BPF_NEXT_ORIGIN}
|
||||
# try shallow clone first
|
||||
git fetch --depth 32 bpf-next
|
||||
# check if desired SHA exists
|
||||
if ! git cat-file -e ${LINUX_SHA}^{commit} ; then
|
||||
# if not, fetch all of bpf-next; slow and painful
|
||||
git fetch bpf-next
|
||||
fi
|
||||
git reset --hard ${LINUX_SHA}
|
||||
fi
|
||||
|
||||
travis_fold end pull_kernel_srcs
|
||||
mkdir -p ${REPO_PATH}
|
||||
cd ${REPO_PATH}
|
||||
git init
|
||||
git remote add bpf-next ${BPF_NEXT_ORIGIN}
|
||||
for depth in 32 64 128; do
|
||||
git fetch --depth ${depth} bpf-next
|
||||
git reset --hard ${LINUX_SHA} && break
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
INDEX https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/INDEX
|
||||
libbpf-vmtest-rootfs-2020.09.27.tar.zst https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/libbpf-vmtest-rootfs-2020.09.27.tar.zst
|
||||
vmlinux-4.9.0.zst https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinux-4.9.0.zst
|
||||
libbpf-vmtest-rootfs-2020.03.11.tar.zst https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/libbpf-vmtest-rootfs-2020.03.11.tar.zst
|
||||
vmlinux-5.5.0-rc6.zst https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinux-5.5.0-rc6.zst
|
||||
vmlinux-5.5.0.zst https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinux-5.5.0.zst
|
||||
vmlinuz-5.5.0-rc6 https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinuz-5.5.0-rc6
|
||||
vmlinuz-5.5.0 https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinuz-5.5.0
|
||||
vmlinuz-4.9.0 https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinuz-4.9.0
|
||||
|
||||
@@ -1,53 +1,33 @@
|
||||
# PERMANENTLY DISABLED
|
||||
align # verifier output format changed
|
||||
atomics # new atomic operations (v5.12+)
|
||||
atomic_bounds # new atomic operations (v5.12+)
|
||||
bind_perm # changed semantics of return values (v5.12+)
|
||||
bpf_iter # bpf_iter support is missing
|
||||
bpf_obj_id # bpf_link support missing for GET_OBJ_INFO, GET_FD_BY_ID, etc
|
||||
bpf_tcp_ca # STRUCT_OPS is missing
|
||||
btf_map_in_map # inner map leak fixed in 5.8
|
||||
btf_skc_cls_ingress # v5.10+ functionality
|
||||
cg_storage_multi # v5.9+ functionality
|
||||
|
||||
# latest Clang generates code that fails to verify
|
||||
bpf_verif_scale
|
||||
#bpf_verif_scale/strobemeta.o
|
||||
#bpf_verif_scale/strobemeta_nounroll1.o
|
||||
#bpf_verif_scale/strobemeta_nounroll2.o
|
||||
|
||||
cgroup_attach_multi # BPF_F_REPLACE_PROG missing
|
||||
cgroup_link # LINK_CREATE is missing
|
||||
cgroup_skb_sk_lookup # bpf_sk_lookup_tcp() helper is missing
|
||||
check_mtu # missing BPF helper (v5.12+)
|
||||
cls_redirect # bpf_csum_level() helper is missing
|
||||
connect_force_port # cgroup/get{peer,sock}name{4,6} support is missing
|
||||
d_path # v5.10+ feature
|
||||
enable_stats # BPF_ENABLE_STATS support is missing
|
||||
fentry_fexit # bpf_prog_test_tracing missing
|
||||
fentry_test # bpf_prog_test_tracing missing
|
||||
fexit_bpf2bpf # freplace is missing
|
||||
fexit_sleep # relies on bpf_trampoline fix in 5.12+
|
||||
fexit_test # bpf_prog_test_tracing missing
|
||||
flow_dissector # bpf_link-based flow dissector is in 5.8+
|
||||
flow_dissector_reattach
|
||||
for_each # v5.12+
|
||||
get_stack_raw_tp # exercising BPF verifier bug causing infinite loop
|
||||
hash_large_key # v5.11+
|
||||
ima # v5.11+
|
||||
kfree_skb # 32-bit pointer arith in test_pkt_access
|
||||
ksyms # __start_BTF has different name
|
||||
kfunc_call # v5.13+
|
||||
link_pinning # bpf_link is missing
|
||||
linked_vars # v5.13+
|
||||
load_bytes_relative # new functionality in 5.8
|
||||
map_init # per-CPU LRU missing
|
||||
map_ptr # test uses BPF_MAP_TYPE_RINGBUF, added in 5.8
|
||||
metadata # v5.10+
|
||||
mmap # 5.5 kernel is too permissive with re-mmaping
|
||||
modify_return # fmod_ret support is missing
|
||||
module_attach # module BTF support missing (v5.11+)
|
||||
ns_current_pid_tgid # bpf_get_ns_current_pid_tgid() helper is missing
|
||||
pe_preserve_elems # v5.10+
|
||||
perf_branches # bpf_read_branch_records() helper is missing
|
||||
pkt_access # 32-bit pointer arith in test_pkt_access
|
||||
probe_read_user_str # kernel bug with garbage bytes at the end
|
||||
prog_run_xattr # 32-bit pointer arith in test_pkt_access
|
||||
raw_tp_test_run # v5.10+
|
||||
recursion # v5.12+
|
||||
ringbuf # BPF_MAP_TYPE_RINGBUF is supported in 5.8+
|
||||
|
||||
# bug in verifier w/ tracking references
|
||||
@@ -55,44 +35,19 @@ ringbuf # BPF_MAP_TYPE_RINGBUF is supported in 5.8+
|
||||
reference_tracking
|
||||
|
||||
select_reuseport # UDP support is missing
|
||||
send_signal # bpf_send_signal_thread() helper is missing
|
||||
sk_assign # bpf_sk_assign helper missing
|
||||
sk_lookup # v5.9+
|
||||
sk_storage_tracing # missing bpf_sk_storage_get() helper
|
||||
skb_ctx # ctx_{size, }_{in, out} in BPF_PROG_TEST_RUN is missing
|
||||
skb_helpers # helpers added in 5.8+
|
||||
snprintf # v5.13+
|
||||
snprintf_btf # v5.10+
|
||||
sock_fields # v5.10+
|
||||
socket_cookie # v5.12+
|
||||
sockmap_basic # uses new socket fields, 5.8+
|
||||
sockmap_listen # no listen socket supportin SOCKMAP
|
||||
sockopt_sk
|
||||
stacktrace_build_id # v5.9+
|
||||
stack_var_off # v5.12+
|
||||
task_local_storage # v5.12+
|
||||
tcp_hdr_options # v5.10+, new TCP header options feature in BPF
|
||||
tcpbpf_user # LINK_CREATE is missing
|
||||
test_bpffs # v5.10+, new CONFIG_BPF_PRELOAD=y and CONFIG_BPF_PRELOAD_UMG=y|m
|
||||
test_bprm_opts # v5.11+
|
||||
skb_ctx # ctx_{size, }_{in, out} in BPF_PROG_TEST_RUN is missing
|
||||
test_global_funcs # kernel doesn't support BTF linkage=global on FUNCs
|
||||
test_local_storage # v5.10+ feature
|
||||
test_lsm # no BPF_LSM support
|
||||
test_overhead # no fmod_ret support
|
||||
test_profiler # needs verifier logic improvements from v5.10+
|
||||
test_skb_pkt_end # v5.11+
|
||||
trace_ext # v5.10+
|
||||
trampoline_count # v5.12+ have lower allowed limits
|
||||
udp_limit # no cgroup/sock_release BPF program type (5.9+)
|
||||
varlen # verifier bug fixed in later kernels
|
||||
vmlinux # hrtimer_nanosleep() signature changed incompatibly
|
||||
xdp_adjust_tail # new XDP functionality added in 5.8
|
||||
xdp_attach # IFLA_XDP_EXPECTED_FD support is missing
|
||||
xdp_bpf2bpf # freplace is missing
|
||||
xdp_cpumap_attach # v5.9+
|
||||
xdp_devmap_attach # new feature in 5.8
|
||||
xdp_link # v5.9+
|
||||
|
||||
# SUBTESTS FAILING (block entire test until blocking subtests works properly)
|
||||
btf # "size check test", "func (Non zero vlen)"
|
||||
tailcalls # tailcall_bpf2bpf_1, tailcall_bpf2bpf_2, tailcall_bpf2bpf_3
|
||||
|
||||
# TEMPORARILY DISABLED
|
||||
send_signal # flaky
|
||||
cls_redirect # latest Clang breaks BPF verification
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
# TEMPORARY
|
||||
# TEMPORARILY DISABLED
|
||||
send_signal # flaky
|
||||
test_lsm # semi-working
|
||||
sk_assign # needs better setup in Travis CI
|
||||
core_reloc # temporary test breakage
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86 5.9.0-rc1 Kernel Configuration
|
||||
# Linux/x86 5.6.0-rc3 Kernel Configuration
|
||||
#
|
||||
|
||||
#
|
||||
# Compiler: gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36)
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="gcc (GCC) 8.2.1 20180801 (Red Hat 8.2.1-2)"
|
||||
CONFIG_CC_IS_GCC=y
|
||||
CONFIG_GCC_VERSION=80201
|
||||
CONFIG_LD_VERSION=230000000
|
||||
CONFIG_GCC_VERSION=40805
|
||||
CONFIG_CLANG_VERSION=0
|
||||
CONFIG_CC_CAN_LINK=y
|
||||
CONFIG_CC_CAN_LINK_STATIC=y
|
||||
CONFIG_CC_HAS_ASM_GOTO=y
|
||||
CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y
|
||||
CONFIG_CC_DISABLE_WARN_MAYBE_UNINITIALIZED=y
|
||||
CONFIG_IRQ_WORK=y
|
||||
CONFIG_BUILDTIME_TABLE_SORT=y
|
||||
CONFIG_THREAD_INFO_IN_TASK=y
|
||||
@@ -28,27 +31,22 @@ CONFIG_HAVE_KERNEL_LZMA=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_LZ4=y
|
||||
CONFIG_HAVE_KERNEL_ZSTD=y
|
||||
CONFIG_KERNEL_GZIP=y
|
||||
# CONFIG_KERNEL_BZIP2 is not set
|
||||
# CONFIG_KERNEL_LZMA is not set
|
||||
# CONFIG_KERNEL_XZ is not set
|
||||
# CONFIG_KERNEL_LZO is not set
|
||||
# CONFIG_KERNEL_LZ4 is not set
|
||||
# CONFIG_KERNEL_ZSTD is not set
|
||||
CONFIG_DEFAULT_INIT=""
|
||||
CONFIG_DEFAULT_HOSTNAME="(none)"
|
||||
CONFIG_SWAP=y
|
||||
CONFIG_SYSVIPC=y
|
||||
CONFIG_SYSVIPC_SYSCTL=y
|
||||
CONFIG_POSIX_MQUEUE=y
|
||||
CONFIG_POSIX_MQUEUE_SYSCTL=y
|
||||
# CONFIG_WATCH_QUEUE is not set
|
||||
CONFIG_CROSS_MEMORY_ATTACH=y
|
||||
# CONFIG_USELIB is not set
|
||||
CONFIG_AUDIT=y
|
||||
# CONFIG_AUDIT is not set
|
||||
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
|
||||
CONFIG_AUDITSYSCALL=y
|
||||
|
||||
#
|
||||
# IRQ subsystem
|
||||
@@ -58,7 +56,6 @@ CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
|
||||
CONFIG_GENERIC_PENDING_IRQ=y
|
||||
CONFIG_GENERIC_IRQ_MIGRATION=y
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
|
||||
CONFIG_GENERIC_MSI_IRQ=y
|
||||
@@ -71,6 +68,7 @@ CONFIG_SPARSE_IRQ=y
|
||||
# end of IRQ subsystem
|
||||
|
||||
CONFIG_CLOCKSOURCE_WATCHDOG=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_DATA=y
|
||||
CONFIG_ARCH_CLOCKSOURCE_INIT=y
|
||||
CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y
|
||||
CONFIG_GENERIC_TIME_VSYSCALL=y
|
||||
@@ -78,8 +76,6 @@ CONFIG_GENERIC_CLOCKEVENTS=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
|
||||
CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y
|
||||
CONFIG_GENERIC_CMOS_UPDATE=y
|
||||
CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
|
||||
|
||||
#
|
||||
# Timers subsystem
|
||||
@@ -124,9 +120,7 @@ CONFIG_PREEMPT_RCU=y
|
||||
# CONFIG_RCU_EXPERT is not set
|
||||
CONFIG_SRCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_TASKS_RCU_GENERIC=y
|
||||
CONFIG_TASKS_RCU=y
|
||||
CONFIG_TASKS_RUDE_RCU=y
|
||||
CONFIG_RCU_STALL_COMMON=y
|
||||
CONFIG_RCU_NEED_SEGCBLIST=y
|
||||
# end of RCU Subsystem
|
||||
@@ -142,7 +136,6 @@ CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
|
||||
#
|
||||
# Scheduler features
|
||||
#
|
||||
# CONFIG_UCLAMP_TASK is not set
|
||||
# end of Scheduler features
|
||||
|
||||
CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y
|
||||
@@ -155,6 +148,7 @@ CONFIG_CGROUPS=y
|
||||
CONFIG_PAGE_COUNTER=y
|
||||
CONFIG_MEMCG=y
|
||||
CONFIG_MEMCG_SWAP=y
|
||||
CONFIG_MEMCG_SWAP_ENABLED=y
|
||||
CONFIG_MEMCG_KMEM=y
|
||||
CONFIG_BLK_CGROUP=y
|
||||
CONFIG_CGROUP_WRITEBACK=y
|
||||
@@ -193,7 +187,6 @@ CONFIG_RD_LZMA=y
|
||||
CONFIG_RD_XZ=y
|
||||
CONFIG_RD_LZO=y
|
||||
CONFIG_RD_LZ4=y
|
||||
CONFIG_RD_ZSTD=y
|
||||
CONFIG_BOOT_CONFIG=y
|
||||
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
|
||||
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
|
||||
@@ -228,14 +221,10 @@ CONFIG_KALLSYMS=y
|
||||
CONFIG_KALLSYMS_ALL=y
|
||||
CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y
|
||||
CONFIG_KALLSYMS_BASE_RELATIVE=y
|
||||
CONFIG_BPF_LSM=y
|
||||
CONFIG_BPF_SYSCALL=y
|
||||
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
|
||||
CONFIG_BPF_JIT_ALWAYS_ON=y
|
||||
CONFIG_BPF_JIT_DEFAULT_ON=y
|
||||
CONFIG_USERMODE_DRIVER=y
|
||||
CONFIG_BPF_PRELOAD=y
|
||||
CONFIG_BPF_PRELOAD_UMD=y
|
||||
# CONFIG_USERFAULTFD is not set
|
||||
CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
|
||||
CONFIG_RSEQ=y
|
||||
@@ -272,6 +261,7 @@ CONFIG_X86_64=y
|
||||
CONFIG_X86=y
|
||||
CONFIG_INSTRUCTION_DECODER=y
|
||||
CONFIG_OUTPUT_FORMAT="elf64-x86-64"
|
||||
CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig"
|
||||
CONFIG_LOCKDEP_SUPPORT=y
|
||||
CONFIG_STACKTRACE_SUPPORT=y
|
||||
CONFIG_MMU=y
|
||||
@@ -389,6 +379,7 @@ CONFIG_X86_DIRECT_GBPAGES=y
|
||||
CONFIG_NUMA=y
|
||||
CONFIG_AMD_NUMA=y
|
||||
CONFIG_X86_64_ACPI_NUMA=y
|
||||
CONFIG_NODES_SPAN_OTHER_NODES=y
|
||||
# CONFIG_NUMA_EMU is not set
|
||||
CONFIG_NODES_SHIFT=6
|
||||
CONFIG_ARCH_SPARSEMEM_ENABLE=y
|
||||
@@ -461,12 +452,12 @@ CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y
|
||||
# CONFIG_ACPI_DEBUGGER is not set
|
||||
# CONFIG_ACPI_SPCR_TABLE is not set
|
||||
CONFIG_ACPI_LPIT=y
|
||||
# CONFIG_ACPI_PROCFS_POWER is not set
|
||||
# CONFIG_ACPI_REV_OVERRIDE_POSSIBLE is not set
|
||||
# CONFIG_ACPI_EC_DEBUGFS is not set
|
||||
# CONFIG_ACPI_AC is not set
|
||||
# CONFIG_ACPI_BATTERY is not set
|
||||
# CONFIG_ACPI_BUTTON is not set
|
||||
# CONFIG_ACPI_TINY_POWER_BUTTON is not set
|
||||
# CONFIG_ACPI_VIDEO is not set
|
||||
# CONFIG_ACPI_FAN is not set
|
||||
# CONFIG_ACPI_DOCK is not set
|
||||
@@ -519,7 +510,7 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
|
||||
CONFIG_CPU_FREQ_GOV_USERSPACE=y
|
||||
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
|
||||
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
|
||||
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
|
||||
# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
|
||||
|
||||
#
|
||||
# CPU frequency scaling drivers
|
||||
@@ -589,7 +580,6 @@ CONFIG_EFI_ESRT=y
|
||||
CONFIG_EFI_RUNTIME_MAP=y
|
||||
# CONFIG_EFI_FAKE_MEMMAP is not set
|
||||
CONFIG_EFI_RUNTIME_WRAPPERS=y
|
||||
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
|
||||
# CONFIG_EFI_CAPSULE_LOADER is not set
|
||||
# CONFIG_EFI_TEST is not set
|
||||
# CONFIG_APPLE_PROPERTIES is not set
|
||||
@@ -609,10 +599,8 @@ CONFIG_EFI_EARLYCON=y
|
||||
CONFIG_HAVE_KVM=y
|
||||
CONFIG_VIRTUALIZATION=y
|
||||
# CONFIG_KVM is not set
|
||||
CONFIG_KVM_WERROR=y
|
||||
CONFIG_AS_AVX512=y
|
||||
CONFIG_AS_SHA1_NI=y
|
||||
CONFIG_AS_SHA256_NI=y
|
||||
# CONFIG_VHOST_NET is not set
|
||||
# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
|
||||
|
||||
#
|
||||
# General architecture-dependent options
|
||||
@@ -620,7 +608,6 @@ CONFIG_AS_SHA256_NI=y
|
||||
CONFIG_CRASH_CORE=y
|
||||
CONFIG_KEXEC_CORE=y
|
||||
CONFIG_HOTPLUG_SMT=y
|
||||
CONFIG_GENERIC_ENTRY=y
|
||||
# CONFIG_OPROFILE is not set
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_OPROFILE_NMI_TIMER=y
|
||||
@@ -652,6 +639,7 @@ CONFIG_HAVE_ASM_MODVERSIONS=y
|
||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||
CONFIG_HAVE_RSEQ=y
|
||||
CONFIG_HAVE_FUNCTION_ARG_ACCESS_API=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_HW_BREAKPOINT=y
|
||||
CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
|
||||
CONFIG_HAVE_USER_RETURN_NOTIFIER=y
|
||||
@@ -669,6 +657,7 @@ CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
|
||||
CONFIG_SECCOMP_FILTER=y
|
||||
CONFIG_HAVE_ARCH_STACKLEAK=y
|
||||
CONFIG_HAVE_STACKPROTECTOR=y
|
||||
CONFIG_CC_HAS_STACKPROTECTOR_NONE=y
|
||||
# CONFIG_STACKPROTECTOR is not set
|
||||
CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES=y
|
||||
CONFIG_HAVE_CONTEXT_TRACKING=y
|
||||
@@ -682,10 +671,12 @@ CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
|
||||
CONFIG_HAVE_ARCH_SOFT_DIRTY=y
|
||||
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
|
||||
CONFIG_MODULES_USE_ELF_RELA=y
|
||||
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
|
||||
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
|
||||
CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
|
||||
CONFIG_HAVE_EXIT_THREAD=y
|
||||
CONFIG_ARCH_MMAP_RND_BITS=28
|
||||
CONFIG_HAVE_COPY_THREAD_TLS=y
|
||||
CONFIG_HAVE_STACK_VALIDATION=y
|
||||
CONFIG_HAVE_RELIABLE_STACKTRACE=y
|
||||
CONFIG_COMPAT_32BIT_TIME=y
|
||||
@@ -707,6 +698,7 @@ CONFIG_ARCH_HAS_MEM_ENCRYPT=y
|
||||
CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
|
||||
# end of GCOV-based kernel profiling
|
||||
|
||||
CONFIG_PLUGIN_HOSTCC=""
|
||||
CONFIG_HAVE_GCC_PLUGINS=y
|
||||
# end of General architecture-dependent options
|
||||
|
||||
@@ -740,7 +732,6 @@ CONFIG_BLK_CGROUP_IOLATENCY=y
|
||||
# CONFIG_BLK_CGROUP_IOCOST is not set
|
||||
CONFIG_BLK_DEBUG_FS=y
|
||||
# CONFIG_BLK_SED_OPAL is not set
|
||||
# CONFIG_BLK_INLINE_ENCRYPTION is not set
|
||||
|
||||
#
|
||||
# Partition Types
|
||||
@@ -788,7 +779,6 @@ CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
|
||||
CONFIG_QUEUED_SPINLOCKS=y
|
||||
CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
|
||||
CONFIG_QUEUED_RWLOCKS=y
|
||||
CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE=y
|
||||
CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE=y
|
||||
CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y
|
||||
CONFIG_FREEZER=y
|
||||
@@ -811,9 +801,11 @@ CONFIG_SELECT_MEMORY_MODEL=y
|
||||
CONFIG_SPARSEMEM_MANUAL=y
|
||||
CONFIG_SPARSEMEM=y
|
||||
CONFIG_NEED_MULTIPLE_NODES=y
|
||||
CONFIG_HAVE_MEMORY_PRESENT=y
|
||||
CONFIG_SPARSEMEM_EXTREME=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
|
||||
CONFIG_SPARSEMEM_VMEMMAP=y
|
||||
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
|
||||
CONFIG_HAVE_FAST_GUP=y
|
||||
CONFIG_MEMORY_ISOLATION=y
|
||||
# CONFIG_MEMORY_HOTPLUG is not set
|
||||
@@ -821,7 +813,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
|
||||
CONFIG_MEMORY_BALLOON=y
|
||||
CONFIG_BALLOON_COMPACTION=y
|
||||
CONFIG_COMPACTION=y
|
||||
CONFIG_PAGE_REPORTING=y
|
||||
CONFIG_MIGRATION=y
|
||||
CONFIG_CONTIG_ALLOC=y
|
||||
CONFIG_PHYS_ADDR_T_64BIT=y
|
||||
@@ -837,6 +828,7 @@ CONFIG_TRANSPARENT_HUGEPAGE=y
|
||||
CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y
|
||||
CONFIG_ARCH_WANTS_THP_SWAP=y
|
||||
CONFIG_THP_SWAP=y
|
||||
CONFIG_TRANSPARENT_HUGE_PAGECACHE=y
|
||||
# CONFIG_CLEANCACHE is not set
|
||||
# CONFIG_FRONTSWAP is not set
|
||||
CONFIG_CMA=y
|
||||
@@ -957,7 +949,6 @@ CONFIG_IPV6_SUBTREES=y
|
||||
CONFIG_IPV6_SEG6_LWTUNNEL=y
|
||||
# CONFIG_IPV6_SEG6_HMAC is not set
|
||||
CONFIG_IPV6_SEG6_BPF=y
|
||||
# CONFIG_IPV6_RPL_LWTUNNEL is not set
|
||||
CONFIG_NETLABEL=y
|
||||
# CONFIG_MPTCP is not set
|
||||
CONFIG_NETWORK_SECMARK=y
|
||||
@@ -988,7 +979,6 @@ CONFIG_NETFILTER_XTABLES=y
|
||||
#
|
||||
# Xtables targets
|
||||
#
|
||||
# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
|
||||
# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
|
||||
# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
|
||||
# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
|
||||
@@ -1192,7 +1182,6 @@ CONFIG_NET_ACT_BPF=y
|
||||
# CONFIG_NET_ACT_SKBMOD is not set
|
||||
# CONFIG_NET_ACT_IFE is not set
|
||||
# CONFIG_NET_ACT_TUNNEL_KEY is not set
|
||||
# CONFIG_NET_ACT_GATE is not set
|
||||
CONFIG_NET_TC_SKB_EXT=y
|
||||
CONFIG_NET_SCH_FIFO=y
|
||||
CONFIG_DCB=y
|
||||
@@ -1208,7 +1197,6 @@ CONFIG_MPLS=y
|
||||
# CONFIG_HSR is not set
|
||||
# CONFIG_NET_SWITCHDEV is not set
|
||||
# CONFIG_NET_L3_MASTER_DEV is not set
|
||||
# CONFIG_QRTR is not set
|
||||
# CONFIG_NET_NCSI is not set
|
||||
CONFIG_RPS=y
|
||||
CONFIG_RFS_ACCEL=y
|
||||
@@ -1307,11 +1295,6 @@ CONFIG_PCI_LABEL=y
|
||||
# CONFIG_PCI_MESON is not set
|
||||
# end of DesignWare PCI Core Support
|
||||
|
||||
#
|
||||
# Mobiveil PCIe Core Support
|
||||
#
|
||||
# end of Mobiveil PCIe Core Support
|
||||
|
||||
#
|
||||
# Cadence PCIe controllers support
|
||||
#
|
||||
@@ -1367,7 +1350,6 @@ CONFIG_DMA_SHARED_BUFFER=y
|
||||
#
|
||||
# Bus devices
|
||||
#
|
||||
# CONFIG_MHI_BUS is not set
|
||||
# end of Bus devices
|
||||
|
||||
# CONFIG_CONNECTOR is not set
|
||||
@@ -1388,7 +1370,7 @@ CONFIG_BLK_DEV=y
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
|
||||
# CONFIG_BLK_DEV_UMEM is not set
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
# CONFIG_BLK_DEV_LOOP is not set
|
||||
# CONFIG_BLK_DEV_DRBD is not set
|
||||
# CONFIG_BLK_DEV_NBD is not set
|
||||
# CONFIG_BLK_DEV_SKD is not set
|
||||
@@ -1595,7 +1577,23 @@ CONFIG_HW_CONSOLE=y
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
# CONFIG_ROCKETPORT is not set
|
||||
# CONFIG_CYCLADES is not set
|
||||
# CONFIG_MOXA_INTELLIO is not set
|
||||
# CONFIG_MOXA_SMARTIO is not set
|
||||
# CONFIG_SYNCLINK is not set
|
||||
# CONFIG_SYNCLINKMP is not set
|
||||
# CONFIG_SYNCLINK_GT is not set
|
||||
# CONFIG_NOZOMI is not set
|
||||
# CONFIG_ISI is not set
|
||||
# CONFIG_N_HDLC is not set
|
||||
# CONFIG_N_GSM is not set
|
||||
# CONFIG_TRACE_SINK is not set
|
||||
# CONFIG_NULL_TTY is not set
|
||||
CONFIG_LDISC_AUTOLOAD=y
|
||||
CONFIG_DEVMEM=y
|
||||
CONFIG_DEVKMEM=y
|
||||
|
||||
#
|
||||
# Serial drivers
|
||||
@@ -1628,7 +1626,6 @@ CONFIG_SERIAL_8250_RSA=y
|
||||
CONFIG_SERIAL_CORE=y
|
||||
CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
# CONFIG_SERIAL_JSM is not set
|
||||
# CONFIG_SERIAL_LANTIQ is not set
|
||||
# CONFIG_SERIAL_SCCNXP is not set
|
||||
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
|
||||
# CONFIG_SERIAL_ALTERA_UART is not set
|
||||
@@ -1636,36 +1633,18 @@ CONFIG_SERIAL_CORE_CONSOLE=y
|
||||
# CONFIG_SERIAL_RP2 is not set
|
||||
# CONFIG_SERIAL_FSL_LPUART is not set
|
||||
# CONFIG_SERIAL_FSL_LINFLEXUART is not set
|
||||
# CONFIG_SERIAL_SPRD is not set
|
||||
# end of Serial drivers
|
||||
|
||||
CONFIG_SERIAL_NONSTANDARD=y
|
||||
# CONFIG_ROCKETPORT is not set
|
||||
# CONFIG_CYCLADES is not set
|
||||
# CONFIG_MOXA_INTELLIO is not set
|
||||
# CONFIG_MOXA_SMARTIO is not set
|
||||
# CONFIG_SYNCLINK is not set
|
||||
# CONFIG_SYNCLINKMP is not set
|
||||
# CONFIG_SYNCLINK_GT is not set
|
||||
# CONFIG_ISI is not set
|
||||
# CONFIG_N_HDLC is not set
|
||||
# CONFIG_N_GSM is not set
|
||||
# CONFIG_NOZOMI is not set
|
||||
# CONFIG_NULL_TTY is not set
|
||||
# CONFIG_TRACE_SINK is not set
|
||||
CONFIG_HVC_DRIVER=y
|
||||
# CONFIG_SERIAL_DEV_BUS is not set
|
||||
# CONFIG_TTY_PRINTK is not set
|
||||
CONFIG_HVC_DRIVER=y
|
||||
CONFIG_VIRTIO_CONSOLE=y
|
||||
# CONFIG_IPMI_HANDLER is not set
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
# CONFIG_NVRAM is not set
|
||||
# CONFIG_APPLICOM is not set
|
||||
# CONFIG_MWAVE is not set
|
||||
CONFIG_DEVMEM=y
|
||||
CONFIG_DEVKMEM=y
|
||||
# CONFIG_NVRAM is not set
|
||||
# CONFIG_RAW_DRIVER is not set
|
||||
CONFIG_DEVPORT=y
|
||||
CONFIG_HPET=y
|
||||
# CONFIG_HPET_MMAP is not set
|
||||
# CONFIG_HANGCHECK_TIMER is not set
|
||||
@@ -1678,6 +1657,7 @@ CONFIG_TCG_TIS=y
|
||||
CONFIG_TCG_CRB=y
|
||||
# CONFIG_TCG_VTPM_PROXY is not set
|
||||
# CONFIG_TELCLOCK is not set
|
||||
CONFIG_DEVPORT=y
|
||||
# CONFIG_XILLYBUS is not set
|
||||
# end of Character devices
|
||||
|
||||
@@ -1733,7 +1713,6 @@ CONFIG_POWER_SUPPLY=y
|
||||
# CONFIG_CHARGER_MAX8903 is not set
|
||||
# CONFIG_HWMON is not set
|
||||
CONFIG_THERMAL=y
|
||||
# CONFIG_THERMAL_NETLINK is not set
|
||||
# CONFIG_THERMAL_STATISTICS is not set
|
||||
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
|
||||
CONFIG_THERMAL_WRITABLE_TRIPS=y
|
||||
@@ -1792,7 +1771,6 @@ CONFIG_BCMA_POSSIBLE=y
|
||||
|
||||
# CONFIG_REGULATOR is not set
|
||||
# CONFIG_RC_CORE is not set
|
||||
# CONFIG_MEDIA_CEC_SUPPORT is not set
|
||||
# CONFIG_MEDIA_SUPPORT is not set
|
||||
|
||||
#
|
||||
@@ -1814,6 +1792,11 @@ CONFIG_VGA_ARB_MAX_GPUS=16
|
||||
#
|
||||
# end of ARM devices
|
||||
|
||||
#
|
||||
# ACP (Audio CoProcessor) Configuration
|
||||
#
|
||||
# end of ACP (Audio CoProcessor) Configuration
|
||||
|
||||
#
|
||||
# Frame buffer Devices
|
||||
#
|
||||
@@ -1879,6 +1862,7 @@ CONFIG_FB_VESA=y
|
||||
#
|
||||
# CONFIG_LCD_CLASS_DEVICE is not set
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_BACKLIGHT_GENERIC=y
|
||||
# CONFIG_BACKLIGHT_APPLE is not set
|
||||
# CONFIG_BACKLIGHT_QCOM_WLED is not set
|
||||
# CONFIG_BACKLIGHT_SAHARA is not set
|
||||
@@ -1938,7 +1922,6 @@ CONFIG_HID_DRAGONRISE=y
|
||||
CONFIG_HID_EZKEY=y
|
||||
# CONFIG_HID_GEMBIRD is not set
|
||||
# CONFIG_HID_GFRM is not set
|
||||
# CONFIG_HID_GLORIOUS is not set
|
||||
# CONFIG_HID_KEYTOUCH is not set
|
||||
CONFIG_HID_KYE=y
|
||||
# CONFIG_HID_WALTOP is not set
|
||||
@@ -2018,7 +2001,6 @@ CONFIG_RTC_MC146818_LIB=y
|
||||
CONFIG_SYNC_FILE=y
|
||||
# CONFIG_SW_SYNC is not set
|
||||
# CONFIG_UDMABUF is not set
|
||||
# CONFIG_DMABUF_MOVE_NOTIFY is not set
|
||||
# CONFIG_DMABUF_SELFTESTS is not set
|
||||
# CONFIG_DMABUF_HEAPS is not set
|
||||
# end of DMABUF options
|
||||
@@ -2034,10 +2016,6 @@ CONFIG_VIRTIO_PCI_LEGACY=y
|
||||
CONFIG_VIRTIO_BALLOON=y
|
||||
# CONFIG_VIRTIO_INPUT is not set
|
||||
# CONFIG_VIRTIO_MMIO is not set
|
||||
# CONFIG_VDPA is not set
|
||||
CONFIG_VHOST_MENU=y
|
||||
# CONFIG_VHOST_NET is not set
|
||||
# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
|
||||
|
||||
#
|
||||
# Microsoft Hyper-V guest support
|
||||
@@ -2051,10 +2029,15 @@ CONFIG_PMC_ATOM=y
|
||||
# CONFIG_MFD_CROS_EC is not set
|
||||
# CONFIG_CHROME_PLATFORMS is not set
|
||||
# CONFIG_MELLANOX_PLATFORM is not set
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_HAVE_CLK_PREPARE=y
|
||||
CONFIG_COMMON_CLK=y
|
||||
|
||||
#
|
||||
# Common Clock Framework
|
||||
#
|
||||
# end of Common Clock Framework
|
||||
|
||||
# CONFIG_HWSPINLOCK is not set
|
||||
|
||||
#
|
||||
@@ -2248,13 +2231,12 @@ CONFIG_INOTIFY_USER=y
|
||||
# end of CD-ROM/DVD Filesystems
|
||||
|
||||
#
|
||||
# DOS/FAT/EXFAT/NT Filesystems
|
||||
# DOS/FAT/NT Filesystems
|
||||
#
|
||||
# CONFIG_MSDOS_FS is not set
|
||||
# CONFIG_VFAT_FS is not set
|
||||
# CONFIG_EXFAT_FS is not set
|
||||
# CONFIG_NTFS_FS is not set
|
||||
# end of DOS/FAT/EXFAT/NT Filesystems
|
||||
# end of DOS/FAT/NT Filesystems
|
||||
|
||||
#
|
||||
# Pseudo filesystems
|
||||
@@ -2270,7 +2252,6 @@ CONFIG_SYSFS=y
|
||||
CONFIG_TMPFS=y
|
||||
CONFIG_TMPFS_POSIX_ACL=y
|
||||
CONFIG_TMPFS_XATTR=y
|
||||
# CONFIG_TMPFS_INODE64 is not set
|
||||
CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE=y
|
||||
CONFIG_MEMFD_CREATE=y
|
||||
@@ -2351,6 +2332,7 @@ CONFIG_IO_WQ=y
|
||||
CONFIG_KEYS=y
|
||||
# CONFIG_KEYS_REQUEST_CACHE is not set
|
||||
# CONFIG_PERSISTENT_KEYRINGS is not set
|
||||
# CONFIG_BIG_KEYS is not set
|
||||
# CONFIG_TRUSTED_KEYS is not set
|
||||
# CONFIG_ENCRYPTED_KEYS is not set
|
||||
# CONFIG_KEY_DH_OPERATIONS is not set
|
||||
@@ -2361,19 +2343,10 @@ CONFIG_SECURITY_NETWORK=y
|
||||
CONFIG_PAGE_TABLE_ISOLATION=y
|
||||
# CONFIG_SECURITY_NETWORK_XFRM is not set
|
||||
# CONFIG_SECURITY_PATH is not set
|
||||
CONFIG_LSM_MMAP_MIN_ADDR=65536
|
||||
CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
|
||||
# CONFIG_HARDENED_USERCOPY is not set
|
||||
# CONFIG_FORTIFY_SOURCE is not set
|
||||
# CONFIG_STATIC_USERMODEHELPER is not set
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set
|
||||
# CONFIG_SECURITY_SELINUX_DISABLE is not set
|
||||
CONFIG_SECURITY_SELINUX_DEVELOP=y
|
||||
CONFIG_SECURITY_SELINUX_AVC_STATS=y
|
||||
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
|
||||
CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS=9
|
||||
CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
|
||||
# CONFIG_SECURITY_SMACK is not set
|
||||
# CONFIG_SECURITY_TOMOYO is not set
|
||||
# CONFIG_SECURITY_APPARMOR is not set
|
||||
@@ -2383,10 +2356,8 @@ CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE=256
|
||||
# CONFIG_SECURITY_LOCKDOWN_LSM is not set
|
||||
CONFIG_INTEGRITY=y
|
||||
# CONFIG_INTEGRITY_SIGNATURE is not set
|
||||
CONFIG_INTEGRITY_AUDIT=y
|
||||
CONFIG_IMA=y
|
||||
CONFIG_IMA_MEASURE_PCR_IDX=10
|
||||
CONFIG_IMA_LSM_RULES=y
|
||||
# CONFIG_IMA_TEMPLATE is not set
|
||||
CONFIG_IMA_NG_TEMPLATE=y
|
||||
# CONFIG_IMA_SIG_TEMPLATE is not set
|
||||
@@ -2394,16 +2365,17 @@ CONFIG_IMA_DEFAULT_TEMPLATE="ima-ng"
|
||||
CONFIG_IMA_DEFAULT_HASH_SHA1=y
|
||||
# CONFIG_IMA_DEFAULT_HASH_SHA256 is not set
|
||||
CONFIG_IMA_DEFAULT_HASH="sha1"
|
||||
CONFIG_IMA_WRITE_POLICY=y
|
||||
CONFIG_IMA_READ_POLICY=y
|
||||
# CONFIG_IMA_WRITE_POLICY is not set
|
||||
# CONFIG_IMA_READ_POLICY is not set
|
||||
# CONFIG_IMA_APPRAISE is not set
|
||||
CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS=y
|
||||
CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS=y
|
||||
# CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set
|
||||
# CONFIG_EVM is not set
|
||||
# CONFIG_DEFAULT_SECURITY_SELINUX is not set
|
||||
CONFIG_DEFAULT_SECURITY_DAC=y
|
||||
CONFIG_LSM="selinux,bpf,integrity"
|
||||
CONFIG_LSM="selinux,bpf"
|
||||
CONFIG_BPF_LSM=y
|
||||
CONFIG_AUDIT=y
|
||||
CONFIG_SECURITY_SELINUX=y
|
||||
|
||||
#
|
||||
# Kernel hardening options
|
||||
@@ -2651,13 +2623,11 @@ CONFIG_GENERIC_STRNLEN_USER=y
|
||||
CONFIG_GENERIC_NET_UTILS=y
|
||||
CONFIG_GENERIC_FIND_FIRST_BIT=y
|
||||
# CONFIG_CORDIC is not set
|
||||
# CONFIG_PRIME_NUMBERS is not set
|
||||
CONFIG_RATIONAL=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GENERIC_IOMAP=y
|
||||
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
|
||||
CONFIG_ARCH_HAS_FAST_MULTIPLIER=y
|
||||
CONFIG_ARCH_USE_SYM_ANNOTATIONS=y
|
||||
CONFIG_CRC_CCITT=y
|
||||
CONFIG_CRC16=y
|
||||
CONFIG_CRC_T10DIF=y
|
||||
@@ -2678,7 +2648,6 @@ CONFIG_XXHASH=y
|
||||
CONFIG_ZLIB_INFLATE=y
|
||||
CONFIG_LZO_DECOMPRESS=y
|
||||
CONFIG_LZ4_DECOMPRESS=y
|
||||
CONFIG_ZSTD_DECOMPRESS=y
|
||||
CONFIG_XZ_DEC=y
|
||||
CONFIG_XZ_DEC_X86=y
|
||||
# CONFIG_XZ_DEC_POWERPC is not set
|
||||
@@ -2694,14 +2663,12 @@ CONFIG_DECOMPRESS_LZMA=y
|
||||
CONFIG_DECOMPRESS_XZ=y
|
||||
CONFIG_DECOMPRESS_LZO=y
|
||||
CONFIG_DECOMPRESS_LZ4=y
|
||||
CONFIG_DECOMPRESS_ZSTD=y
|
||||
CONFIG_GENERIC_ALLOCATOR=y
|
||||
CONFIG_XARRAY_MULTI=y
|
||||
CONFIG_ASSOCIATIVE_ARRAY=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT_MAP=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_DMA_OPS=y
|
||||
CONFIG_NEED_SG_DMA_LENGTH=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
|
||||
@@ -2769,7 +2736,6 @@ CONFIG_CONSOLE_LOGLEVEL_QUIET=4
|
||||
CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
|
||||
# CONFIG_BOOT_PRINTK_DELAY is not set
|
||||
# CONFIG_DYNAMIC_DEBUG is not set
|
||||
# CONFIG_DYNAMIC_DEBUG_CORE is not set
|
||||
CONFIG_SYMBOLIC_ERRNAME=y
|
||||
CONFIG_DEBUG_BUGVERBOSE=y
|
||||
# end of printk and dmesg options
|
||||
@@ -2779,7 +2745,6 @@ CONFIG_DEBUG_BUGVERBOSE=y
|
||||
#
|
||||
CONFIG_DEBUG_INFO=y
|
||||
# CONFIG_DEBUG_INFO_REDUCED is not set
|
||||
# CONFIG_DEBUG_INFO_COMPRESSED is not set
|
||||
# CONFIG_DEBUG_INFO_SPLIT is not set
|
||||
# CONFIG_DEBUG_INFO_DWARF4 is not set
|
||||
CONFIG_DEBUG_INFO_BTF=y
|
||||
@@ -2789,9 +2754,9 @@ CONFIG_FRAME_WARN=2048
|
||||
# CONFIG_STRIP_ASM_SYMS is not set
|
||||
# CONFIG_READABLE_ASM is not set
|
||||
# CONFIG_HEADERS_INSTALL is not set
|
||||
CONFIG_OPTIMIZE_INLINING=y
|
||||
# CONFIG_DEBUG_SECTION_MISMATCH is not set
|
||||
CONFIG_SECTION_MISMATCH_WARN_ONLY=y
|
||||
# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set
|
||||
CONFIG_STACK_VALIDATION=y
|
||||
# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
|
||||
# end of Compile-time checks and compiler options
|
||||
@@ -2802,15 +2767,12 @@ CONFIG_STACK_VALIDATION=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
|
||||
CONFIG_MAGIC_SYSRQ_SERIAL=y
|
||||
CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_FS_ALLOW_ALL=y
|
||||
# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
|
||||
# CONFIG_DEBUG_FS_ALLOW_NONE is not set
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
# CONFIG_KGDB is not set
|
||||
CONFIG_ARCH_HAS_UBSAN_SANITIZE_ALL=y
|
||||
# CONFIG_UBSAN is not set
|
||||
CONFIG_UBSAN_ALIGNMENT=y
|
||||
# end of Generic Kernel Debugging Instruments
|
||||
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
@@ -2825,8 +2787,6 @@ CONFIG_DEBUG_MISC=y
|
||||
# CONFIG_PAGE_POISONING is not set
|
||||
# CONFIG_DEBUG_PAGE_REF is not set
|
||||
# CONFIG_DEBUG_RODATA_TEST is not set
|
||||
CONFIG_ARCH_HAS_DEBUG_WX=y
|
||||
# CONFIG_DEBUG_WX is not set
|
||||
CONFIG_GENERIC_PTDUMP=y
|
||||
# CONFIG_PTDUMP_DEBUGFS is not set
|
||||
# CONFIG_DEBUG_OBJECTS is not set
|
||||
@@ -2836,16 +2796,14 @@ CONFIG_HAVE_DEBUG_KMEMLEAK=y
|
||||
# CONFIG_DEBUG_KMEMLEAK is not set
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
CONFIG_SCHED_STACK_END_CHECK=y
|
||||
CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE=y
|
||||
# CONFIG_DEBUG_VM is not set
|
||||
# CONFIG_DEBUG_VM_PGTABLE is not set
|
||||
CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
|
||||
# CONFIG_DEBUG_VIRTUAL is not set
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
# CONFIG_DEBUG_PER_CPU_MAPS is not set
|
||||
CONFIG_HAVE_ARCH_KASAN=y
|
||||
CONFIG_HAVE_ARCH_KASAN_VMALLOC=y
|
||||
CONFIG_CC_HAS_KASAN_GENERIC=y
|
||||
CONFIG_KASAN_STACK=1
|
||||
# end of Memory Debugging
|
||||
|
||||
# CONFIG_DEBUG_SHIRQ is not set
|
||||
@@ -2870,7 +2828,6 @@ CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
|
||||
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
|
||||
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
|
||||
# CONFIG_WQ_WATCHDOG is not set
|
||||
# CONFIG_TEST_LOCKUP is not set
|
||||
# end of Debug Oops, Lockups and Hangs
|
||||
|
||||
#
|
||||
@@ -2889,7 +2846,6 @@ CONFIG_DEBUG_PREEMPT=y
|
||||
#
|
||||
CONFIG_LOCK_DEBUGGING_SUPPORT=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
# CONFIG_PROVE_RAW_LOCK_NESTING is not set
|
||||
# CONFIG_LOCK_STAT is not set
|
||||
CONFIG_DEBUG_RT_MUTEXES=y
|
||||
CONFIG_DEBUG_SPINLOCK=y
|
||||
@@ -2906,7 +2862,6 @@ CONFIG_DEBUG_ATOMIC_SLEEP=y
|
||||
# end of Lock Debugging (spinlocks, mutexes, etc...)
|
||||
|
||||
CONFIG_TRACE_IRQFLAGS=y
|
||||
CONFIG_TRACE_IRQFLAGS_NMI=y
|
||||
CONFIG_STACKTRACE=y
|
||||
# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
|
||||
# CONFIG_DEBUG_KOBJECT is not set
|
||||
@@ -2929,7 +2884,6 @@ CONFIG_DEBUG_CREDENTIALS=y
|
||||
CONFIG_PROVE_RCU=y
|
||||
# CONFIG_RCU_PERF_TEST is not set
|
||||
# CONFIG_RCU_TORTURE_TEST is not set
|
||||
# CONFIG_RCU_REF_SCALE_TEST is not set
|
||||
CONFIG_RCU_CPU_STALL_TIMEOUT=60
|
||||
# CONFIG_RCU_TRACE is not set
|
||||
# CONFIG_RCU_EQS_DEBUG is not set
|
||||
@@ -2967,6 +2921,7 @@ CONFIG_DYNAMIC_FTRACE_WITH_REGS=y
|
||||
CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
|
||||
# CONFIG_FUNCTION_PROFILER is not set
|
||||
# CONFIG_STACK_TRACER is not set
|
||||
# CONFIG_PREEMPTIRQ_EVENTS is not set
|
||||
# CONFIG_IRQSOFF_TRACER is not set
|
||||
# CONFIG_PREEMPT_TRACER is not set
|
||||
# CONFIG_SCHED_TRACER is not set
|
||||
@@ -2986,7 +2941,6 @@ CONFIG_DYNAMIC_EVENTS=y
|
||||
CONFIG_PROBE_EVENTS=y
|
||||
CONFIG_BPF_KPROBE_OVERRIDE=y
|
||||
CONFIG_FTRACE_MCOUNT_RECORD=y
|
||||
# CONFIG_SYNTH_EVENTS is not set
|
||||
# CONFIG_HIST_TRIGGERS is not set
|
||||
# CONFIG_TRACE_EVENT_INJECT is not set
|
||||
# CONFIG_TRACEPOINT_BENCHMARK is not set
|
||||
@@ -2998,7 +2952,6 @@ CONFIG_FTRACE_MCOUNT_RECORD=y
|
||||
# CONFIG_KPROBE_EVENT_GEN_TEST is not set
|
||||
# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
|
||||
# CONFIG_SAMPLES is not set
|
||||
CONFIG_HAVE_ARCH_KCSAN=y
|
||||
CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
|
||||
# CONFIG_STRICT_DEVMEM is not set
|
||||
|
||||
@@ -3006,12 +2959,13 @@ CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
|
||||
# x86 Debugging
|
||||
#
|
||||
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
|
||||
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
|
||||
CONFIG_X86_VERBOSE_BOOTUP=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
# CONFIG_EARLY_PRINTK_DBGP is not set
|
||||
# CONFIG_EARLY_PRINTK_USB_XDBC is not set
|
||||
# CONFIG_EFI_PGT_DUMP is not set
|
||||
# CONFIG_DEBUG_WX is not set
|
||||
CONFIG_DOUBLEFAULT=y
|
||||
# CONFIG_DEBUG_TLBFLUSH is not set
|
||||
# CONFIG_IOMMU_DEBUG is not set
|
||||
CONFIG_HAVE_MMIOTRACE_SUPPORT=y
|
||||
@@ -3038,16 +2992,9 @@ CONFIG_UNWINDER_ORC=y
|
||||
# CONFIG_NOTIFIER_ERROR_INJECTION is not set
|
||||
CONFIG_FUNCTION_ERROR_INJECTION=y
|
||||
CONFIG_FAULT_INJECTION=y
|
||||
# CONFIG_FAILSLAB is not set
|
||||
# CONFIG_FAIL_PAGE_ALLOC is not set
|
||||
# CONFIG_FAIL_MAKE_REQUEST is not set
|
||||
# CONFIG_FAIL_IO_TIMEOUT is not set
|
||||
# CONFIG_FAIL_FUTEX is not set
|
||||
CONFIG_FAULT_INJECTION_DEBUG_FS=y
|
||||
CONFIG_FAIL_FUNCTION=y
|
||||
CONFIG_ARCH_HAS_KCOV=y
|
||||
CONFIG_CC_HAS_SANCOV_TRACE_PC=y
|
||||
# CONFIG_KCOV is not set
|
||||
# CONFIG_RUNTIME_TESTING_MENU is not set
|
||||
# CONFIG_MEMTEST is not set
|
||||
# end of Kernel Testing and Coverage
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
btf_dump
|
||||
core_retro
|
||||
cpu_mask
|
||||
hashmap
|
||||
perf_buffer
|
||||
section_names
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
# $1 - start or end
|
||||
# $2 - fold identifier, no spaces
|
||||
# $3 - fold section description
|
||||
travis_fold() {
|
||||
local YELLOW='\033[1;33m'
|
||||
local NOCOLOR='\033[0m'
|
||||
echo travis_fold:$1:$2
|
||||
if [ ! -z "${3:-}" ]; then
|
||||
echo -e "${YELLOW}$3${NOCOLOR}"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
@@ -81,7 +81,6 @@ packages=(
|
||||
binutils
|
||||
elfutils
|
||||
glibc
|
||||
iproute2
|
||||
# selftests test_verifier dependencies.
|
||||
libcap
|
||||
)
|
||||
@@ -102,6 +101,15 @@ rm -rf "$root/usr/share/{doc,help,man,texinfo}"
|
||||
|
||||
chroot "${root}" /bin/busybox --install
|
||||
|
||||
cat > "$root/etc/fstab" << "EOF"
|
||||
dev /dev devtmpfs rw,nosuid 0 0
|
||||
proc /proc proc rw,nosuid,nodev,noexec 0 0
|
||||
sys /sys sysfs rw,nosuid,nodev,noexec 0 0
|
||||
debugfs /sys/kernel/debug debugfs mode=755,realtime 0 0
|
||||
bpffs /sys/fs/bpf bpf realtime 0 0
|
||||
EOF
|
||||
chmod 644 "$root/etc/fstab"
|
||||
|
||||
cat > "$root/etc/inittab" << "EOF"
|
||||
::sysinit:/etc/init.d/rcS
|
||||
::ctrlaltdel:/sbin/reboot
|
||||
@@ -115,29 +123,13 @@ mkdir -m 755 "$root/etc/init.d" "$root/etc/rcS.d"
|
||||
cat > "$root/etc/rcS.d/S10-mount" << "EOF"
|
||||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
/bin/mount proc /proc -t proc
|
||||
|
||||
# Mount devtmpfs if not mounted
|
||||
if [[ -z $(/bin/mount -l -t devtmpfs) ]]; then
|
||||
/bin/mount devtmpfs /dev -t devtmpfs
|
||||
fi
|
||||
|
||||
/bin/mount sysfs /sys -t sysfs
|
||||
/bin/mount bpffs /sys/fs/bpf -t bpf
|
||||
/bin/mount debugfs /sys/kernel/debug -t debugfs
|
||||
|
||||
echo 'Listing currently mounted file systems'
|
||||
/bin/mount
|
||||
/bin/mount -a
|
||||
EOF
|
||||
chmod 755 "$root/etc/rcS.d/S10-mount"
|
||||
|
||||
cat > "$root/etc/rcS.d/S40-network" << "EOF"
|
||||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
ip link set lo up
|
||||
EOF
|
||||
chmod 755 "$root/etc/rcS.d/S40-network"
|
||||
@@ -145,8 +137,6 @@ chmod 755 "$root/etc/rcS.d/S40-network"
|
||||
cat > "$root/etc/init.d/rcS" << "EOF"
|
||||
#!/bin/sh
|
||||
|
||||
set -eux
|
||||
|
||||
for path in /etc/rcS.d/S*; do
|
||||
[ -x "$path" ] && "$path"
|
||||
done
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||
@@ -1,3 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||
set -euxo pipefail
|
||||
|
||||
# these tests expect vmlinux.h to have latest defiition of bpf_devmap_val xdp_md->egress_ifindex
|
||||
rm progs/test_xdp_with_devmap_helpers.c
|
||||
rm progs/test_xdp_devmap_helpers.c
|
||||
rm prog_tests/xdp_devmap_attach.c
|
||||
|
||||
# no BPF_F_NO_PREALLOC in BTF and no sk_msg_md->sk field
|
||||
rm progs/test_skmsg_load_helpers.c
|
||||
rm prog_tests/sockmap_basic.c
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
set -eux
|
||||
|
||||
REPO_PATH=$1
|
||||
|
||||
@@ -10,11 +8,7 @@ ${VMTEST_ROOT}/checkout_latest_kernel.sh ${REPO_PATH}
|
||||
cd ${REPO_PATH}
|
||||
|
||||
if [[ "${KERNEL}" = 'LATEST' ]]; then
|
||||
travis_fold start build_kernel "Kernel build"
|
||||
|
||||
cp ${VMTEST_ROOT}/configs/latest.config .config
|
||||
make -j $((4*$(nproc))) olddefconfig all
|
||||
|
||||
travis_fold end build_kernel
|
||||
fi
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
set -uo pipefail
|
||||
trap 'exit 2' ERR
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
|
||||
usage () {
|
||||
USAGE_STRING="usage: $0 [-k KERNELRELEASE|-b DIR] [[-r ROOTFSVERSION] [-fo]|-I] [-Si] [-d DIR] IMG
|
||||
$0 [-k KERNELRELEASE] -l
|
||||
@@ -277,10 +275,6 @@ if [[ $SKIPIMG -eq 0 && ! -v ROOTFSVERSION ]]; then
|
||||
fi
|
||||
|
||||
echo "Kernel release: $KERNELRELEASE" >&2
|
||||
echo
|
||||
|
||||
travis_fold start vmlinux_setup "Preparing Linux image"
|
||||
|
||||
if (( SKIPIMG )); then
|
||||
echo "Not extracting root filesystem" >&2
|
||||
else
|
||||
@@ -372,15 +366,11 @@ else
|
||||
sudo chmod 644 "$vmlinux"
|
||||
fi
|
||||
|
||||
travis_fold end vmlinux_setup
|
||||
|
||||
LIBBPF_PATH="${REPO_ROOT}" \
|
||||
REPO_PATH="travis-ci/vmtest/bpf-next" \
|
||||
VMTEST_ROOT="${VMTEST_ROOT}" \
|
||||
VMLINUX_BTF=${vmlinux} ${VMTEST_ROOT}/build_selftests.sh
|
||||
|
||||
travis_fold start vm_init "Starting virtual machine..."
|
||||
|
||||
if (( SKIPSOURCE )); then
|
||||
echo "Not copying source files..." >&2
|
||||
else
|
||||
@@ -411,12 +401,12 @@ if [[ ! -z SETUPCMD ]]; then
|
||||
if [[ -v BUILDDIR ]]; then kernel='latest'; fi
|
||||
setup_envvars="export KERNEL=${kernel}"
|
||||
setup_script=$(printf "#!/bin/sh
|
||||
set -eux
|
||||
set -e
|
||||
|
||||
echo 'Running setup commands'
|
||||
%s
|
||||
set +e; %s; exitstatus=\$?; set -e
|
||||
echo \$exitstatus > /exitstatus
|
||||
%s
|
||||
echo $? > /exitstatus
|
||||
chmod 644 /exitstatus" "${setup_envvars}" "${setup_cmd}")
|
||||
fi
|
||||
|
||||
@@ -425,19 +415,15 @@ sudo chmod 755 "$mnt/etc/rcS.d/S50-run-tests"
|
||||
|
||||
poweroff_script="#!/bin/sh
|
||||
|
||||
echo travis_fold:start:shutdown
|
||||
echo -e '\033[1;33mShutdown\033[0m\n'
|
||||
|
||||
poweroff"
|
||||
echo "${poweroff_script}" | sudo tee "$mnt/etc/rcS.d/S99-poweroff" > /dev/null
|
||||
sudo chmod 755 "$mnt/etc/rcS.d/S99-poweroff"
|
||||
|
||||
sudo umount "$mnt"
|
||||
|
||||
echo "Starting VM with $(nproc) CPUs..."
|
||||
|
||||
echo "Starting virtual machine..." >&2
|
||||
qemu-system-x86_64 -nodefaults -display none -serial mon:stdio \
|
||||
-cpu kvm64 -enable-kvm -smp "$(nproc)" -m 4G \
|
||||
-cpu kvm64 -enable-kvm -smp "$(nproc)" -m 2G \
|
||||
-drive file="$IMG",format=raw,index=1,media=disk,if=virtio,cache=none \
|
||||
-kernel "$vmlinuz" -append "root=/dev/vda rw console=ttyS0,115200$APPEND"
|
||||
|
||||
@@ -449,7 +435,4 @@ else
|
||||
exitstatus=1
|
||||
fi
|
||||
sudo umount "$mnt"
|
||||
|
||||
travis_fold end shutdown
|
||||
|
||||
exit "$exitstatus"
|
||||
|
||||
@@ -1,35 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
set -euxo pipefail
|
||||
|
||||
test_progs() {
|
||||
if [[ "${KERNEL}" != '4.9.0' ]]; then
|
||||
travis_fold start test_progs "Testing test_progs"
|
||||
./test_progs ${BLACKLIST:+-b$BLACKLIST} ${WHITELIST:+-t$WHITELIST}
|
||||
travis_fold end test_progs
|
||||
fi
|
||||
|
||||
travis_fold start test_progs-no_alu32 "Testing test_progs-no_alu32"
|
||||
./test_progs-no_alu32 ${BLACKLIST:+-b$BLACKLIST} ${WHITELIST:+-t$WHITELIST}
|
||||
travis_fold end test_progs-no_alu32
|
||||
echo TEST_PROGS
|
||||
./test_progs ${BLACKLIST:+-b$BLACKLIST} ${WHITELIST:+-t$WHITELIST}
|
||||
}
|
||||
|
||||
test_maps() {
|
||||
travis_fold start test_maps "Testing test_maps"
|
||||
echo TEST_MAPS
|
||||
# Allow failing on older kernels.
|
||||
./test_maps
|
||||
travis_fold end test_maps
|
||||
}
|
||||
|
||||
test_verifier() {
|
||||
travis_fold start test_verifier "Testing test_verifier"
|
||||
echo TEST_VERIFIER
|
||||
./test_verifier
|
||||
travis_fold end test_verifier
|
||||
}
|
||||
|
||||
travis_fold end vm_init
|
||||
|
||||
configs_path='libbpf/travis-ci/vmtest/configs'
|
||||
blacklist_path="$configs_path/blacklist/BLACKLIST-${KERNEL}"
|
||||
if [[ -s "${blacklist_path}" ]]; then
|
||||
@@ -46,6 +34,6 @@ cd libbpf/selftests/bpf
|
||||
test_progs
|
||||
|
||||
if [[ "${KERNEL}" == 'latest' ]]; then
|
||||
#test_maps
|
||||
test_maps
|
||||
test_verifier
|
||||
fi
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
set -eux
|
||||
|
||||
VMTEST_SETUPCMD="PROJECT_NAME=${PROJECT_NAME} ./${PROJECT_NAME}/travis-ci/vmtest/run_selftests.sh"
|
||||
|
||||
echo "KERNEL: $KERNEL"
|
||||
echo
|
||||
|
||||
# Build latest pahole
|
||||
${VMTEST_ROOT}/build_pahole.sh travis-ci/vmtest/pahole
|
||||
|
||||
travis_fold start install_clang "Installing Clang/LLVM"
|
||||
|
||||
# Install required packages
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main"
|
||||
sudo apt-get update
|
||||
sudo apt-get install --allow-downgrades -y libc6=2.31-0ubuntu9.2
|
||||
sudo aptitude install -y g++ libelf-dev
|
||||
sudo aptitude install -y clang-13 lld-13 llvm-13
|
||||
|
||||
travis_fold end install_clang
|
||||
echo "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main" | sudo tee -a /etc/apt/sources.list
|
||||
sudo apt-get -qq update
|
||||
sudo apt-get -qq -y install clang lld llvm
|
||||
|
||||
# Build selftests (and latest kernel, if necessary)
|
||||
KERNEL="${KERNEL}" ${VMTEST_ROOT}/prepare_selftests.sh travis-ci/vmtest/bpf-next
|
||||
|
||||
138018
travis-ci/vmtest/vmlinux.h
138018
travis-ci/vmtest/vmlinux.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user