mirror of
https://github.com/netdata/libbpf.git
synced 2026-03-15 13:59:06 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1107a4d0d4 |
@@ -1 +1 @@
|
||||
1a3449c19407a28f7019a887cdf0d6ba2444751a
|
||||
3fb1a96a91120877488071a167d26d76be4be977
|
||||
|
||||
@@ -1 +1 @@
|
||||
3db1a3fa98808aa90f95ec3e0fa2fc7abf28f5c9
|
||||
06a4ec1d9dc652e17ee3ac2ceb6c7cf6c2b75cdd
|
||||
|
||||
42
README.md
42
README.md
@@ -1,11 +1,17 @@
|
||||
BPF/libbpf usage and questions
|
||||
==============================
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
BPF questions
|
||||
=============
|
||||
|
||||
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||
their application, should be sent to bpf@vger.kernel.org mailing list. You can
|
||||
@@ -20,7 +26,7 @@ should be opened only for dealing with issues pertaining to specific way this
|
||||
libbpf mirror repo is set up and organized.
|
||||
|
||||
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)
|
||||
=====
|
||||
@@ -61,9 +67,8 @@ 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)
|
||||
- [Debian](https://packages.debian.org/sid/libbpf-dev)
|
||||
- [Arch](https://www.archlinux.org/packages/extra/x86_64/libbpf/)
|
||||
- [Ubuntu](https://packages.ubuntu.com/source/groovy/libbpf)
|
||||
|
||||
Benefits of packaging from the mirror over packaging from kernel sources:
|
||||
- Consistent versioning across distributions.
|
||||
@@ -97,7 +102,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
|
||||
|
||||
If your kernel doesn't come with BTF built-in, you'll need to build custom
|
||||
kernel. You'll need:
|
||||
@@ -117,8 +121,6 @@ distributions have Clang/LLVM 10+ packaged by default:
|
||||
- Fedora 32+
|
||||
- Ubuntu 20.04+
|
||||
- Arch Linux
|
||||
- Ubuntu 20.10 (LLVM 11)
|
||||
- Debian 11 (LLVM 11)
|
||||
|
||||
Otherwise, please make sure to update it on your system.
|
||||
|
||||
@@ -130,20 +132,6 @@ use it:
|
||||
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
@@ -409,8 +409,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,
|
||||
};
|
||||
|
||||
|
||||
19
scripts/check-reallocarray.sh
Executable file
19
scripts/check-reallocarray.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
# Usage: check-reallocarray.sh cc_path [cc_args...]
|
||||
|
||||
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
|
||||
|
||||
"$@" $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,7 +237,7 @@ 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
|
||||
@@ -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."
|
||||
|
||||
|
||||
83
src/Makefile
83
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 $(CC))
|
||||
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 ?= .
|
||||
@@ -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) $1 $(if $3,-m $3,) '$(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 -fpR $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
|
||||
|
||||
174
src/bpf.c
174
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,31 +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;
|
||||
}
|
||||
attr.link_create.iter_info =
|
||||
ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0));
|
||||
attr.link_create.iter_info_len = OPTS_GET(opts, iter_info_len, 0);
|
||||
|
||||
return sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr));
|
||||
}
|
||||
@@ -764,37 +715,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 +818,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 +875,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));
|
||||
}
|
||||
|
||||
39
src/bpf.h
39
src/bpf.h
@@ -174,9 +174,8 @@ struct bpf_link_create_opts {
|
||||
__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 iter_info_len
|
||||
|
||||
LIBBPF_API int bpf_link_create(int prog_fd, int target_fd,
|
||||
enum bpf_attach_type attach_type,
|
||||
@@ -235,7 +234,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 +243,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; \
|
||||
@@ -112,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
|
||||
@@ -195,8 +115,8 @@ 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))
|
||||
|
||||
/*
|
||||
* bpf_core_read_str() is a thin wrapper around bpf_probe_read_str()
|
||||
@@ -204,8 +124,8 @@ enum bpf_enum_value_kind {
|
||||
* argument.
|
||||
*/
|
||||
#define bpf_core_read_str(dst, sz, src) \
|
||||
bpf_probe_read_kernel_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)
|
||||
@@ -319,17 +239,15 @@ 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.
|
||||
|
||||
@@ -6,7 +6,6 @@ struct bpf_sk_lookup;
|
||||
struct bpf_perf_event_data;
|
||||
struct bpf_perf_event_value;
|
||||
struct bpf_pidns_info;
|
||||
struct bpf_redir_neigh;
|
||||
struct bpf_sock;
|
||||
struct bpf_sock_addr;
|
||||
struct bpf_sock_ops;
|
||||
@@ -16,7 +15,6 @@ struct bpf_sysctl;
|
||||
struct bpf_tcp_sock;
|
||||
struct bpf_tunnel_key;
|
||||
struct bpf_xfrm_state;
|
||||
struct linux_binprm;
|
||||
struct pt_regs;
|
||||
struct sk_reuseport_md;
|
||||
struct sockaddr;
|
||||
@@ -31,11 +29,6 @@ struct task_struct;
|
||||
struct __sk_buff;
|
||||
struct sk_msg_md;
|
||||
struct xdp_md;
|
||||
struct path;
|
||||
struct btf_ptr;
|
||||
struct inode;
|
||||
struct socket;
|
||||
struct file;
|
||||
|
||||
/*
|
||||
* bpf_map_lookup_elem
|
||||
@@ -157,7 +150,7 @@ static __u64 (*bpf_ktime_get_ns)(void) = (void *) 5;
|
||||
*
|
||||
* Also, note that **bpf_trace_printk**\ () is slow, and should
|
||||
* only be used for debugging purposes. For this reason, a notice
|
||||
* block (spanning several lines) is printed to kernel logs and
|
||||
* bloc (spanning several lines) is printed to kernel logs and
|
||||
* states that the helper should not be used "for production use"
|
||||
* the first time this helper is used (or more precisely, when
|
||||
* **trace_printk**\ () buffers are allocated). For passing values
|
||||
@@ -481,14 +474,14 @@ static long (*bpf_skb_vlan_pop)(struct __sk_buff *skb) = (void *) 19;
|
||||
*
|
||||
* int ret;
|
||||
* struct bpf_tunnel_key key = {};
|
||||
*
|
||||
*
|
||||
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||
* if (ret < 0)
|
||||
* return TC_ACT_SHOT; // drop packet
|
||||
*
|
||||
*
|
||||
* if (key.remote_ipv4 != 0x0a000001)
|
||||
* return TC_ACT_SHOT; // drop packet
|
||||
*
|
||||
*
|
||||
* return TC_ACT_OK; // accept packet
|
||||
*
|
||||
* This interface can also be used with all encapsulation devices
|
||||
@@ -611,7 +604,7 @@ static long (*bpf_redirect)(__u32 ifindex, __u64 flags) = (void *) 23;
|
||||
*
|
||||
* Retrieve the realm or the route, that is to say the
|
||||
* **tclassid** field of the destination for the *skb*. The
|
||||
* identifier retrieved is a user-provided tag, similar to the
|
||||
* indentifier retrieved is a user-provided tag, similar to the
|
||||
* one used with the net_cls cgroup (see description for
|
||||
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
|
||||
* held by a route (a destination entry), not by a task.
|
||||
@@ -956,8 +949,8 @@ static long (*bpf_probe_write_user)(void *dst, const void *src, __u32 len) = (vo
|
||||
* Returns
|
||||
* The return value depends on the result of the test, and can be:
|
||||
*
|
||||
* * 0, if current task belongs to the cgroup2.
|
||||
* * 1, if current task does not belong to the cgroup2.
|
||||
* * 0, if the *skb* task belongs to the cgroup2.
|
||||
* * 1, if the *skb* task does not belong to the cgroup2.
|
||||
* * A negative error code, if an error occurred.
|
||||
*/
|
||||
static long (*bpf_current_task_under_cgroup)(void *map, __u32 index) = (void *) 37;
|
||||
@@ -1201,7 +1194,7 @@ static long (*bpf_set_hash)(struct __sk_buff *skb, __u32 hash) = (void *) 48;
|
||||
* **TCP_CONGESTION**, **TCP_BPF_IW**,
|
||||
* **TCP_BPF_SNDCWND_CLAMP**, **TCP_SAVE_SYN**,
|
||||
* **TCP_KEEPIDLE**, **TCP_KEEPINTVL**, **TCP_KEEPCNT**,
|
||||
* **TCP_SYNCNT**, **TCP_USER_TIMEOUT**, **TCP_NOTSENT_LOWAT**.
|
||||
* **TCP_SYNCNT**, **TCP_USER_TIMEOUT**.
|
||||
* * **IPPROTO_IP**, which supports *optname* **IP_TOS**.
|
||||
* * **IPPROTO_IPV6**, which supports *optname* **IPV6_TCLASS**.
|
||||
*
|
||||
@@ -1848,7 +1841,7 @@ static long (*bpf_msg_redirect_hash)(struct sk_msg_md *msg, void *map, void *key
|
||||
*
|
||||
* This helper is used in programs implementing policies at the
|
||||
* skb socket level. If the sk_buff *skb* is allowed to pass (i.e.
|
||||
* if the verdict eBPF program returns **SK_PASS**), redirect it
|
||||
* if the verdeict eBPF program returns **SK_PASS**), redirect it
|
||||
* to the socket referenced by *map* (of type
|
||||
* **BPF_MAP_TYPE_SOCKHASH**) using hash *key*. Both ingress and
|
||||
* egress interfaces can be used for redirection. The
|
||||
@@ -2206,7 +2199,7 @@ static struct bpf_sock *(*bpf_sk_lookup_udp)(void *ctx, struct bpf_sock_tuple *t
|
||||
* Returns
|
||||
* 0 on success, or a negative error in case of failure.
|
||||
*/
|
||||
static long (*bpf_sk_release)(void *sock) = (void *) 86;
|
||||
static long (*bpf_sk_release)(struct bpf_sock *sock) = (void *) 86;
|
||||
|
||||
/*
|
||||
* bpf_map_push_elem
|
||||
@@ -2449,7 +2442,7 @@ static struct bpf_sock *(*bpf_skc_lookup_tcp)(void *ctx, struct bpf_sock_tuple *
|
||||
* 0 if *iph* and *th* are a valid SYN cookie ACK, or a negative
|
||||
* error otherwise.
|
||||
*/
|
||||
static long (*bpf_tcp_check_syncookie)(void *sk, void *iph, __u32 iph_len, struct tcphdr *th, __u32 th_len) = (void *) 100;
|
||||
static long (*bpf_tcp_check_syncookie)(struct bpf_sock *sk, void *iph, __u32 iph_len, struct tcphdr *th, __u32 th_len) = (void *) 100;
|
||||
|
||||
/*
|
||||
* bpf_sysctl_get_name
|
||||
@@ -2608,9 +2601,6 @@ static long (*bpf_strtoul)(const char *buf, unsigned long buf_len, __u64 flags,
|
||||
* "type". The bpf-local-storage "type" (i.e. the *map*) is
|
||||
* searched against all bpf-local-storages residing at *sk*.
|
||||
*
|
||||
* *sk* is a kernel **struct sock** pointer for LSM program.
|
||||
* *sk* is a **struct bpf_sock** pointer for other program types.
|
||||
*
|
||||
* An optional *flags* (**BPF_SK_STORAGE_GET_F_CREATE**) can be
|
||||
* used such that a new bpf-local-storage will be
|
||||
* created if one does not exist. *value* can be used
|
||||
@@ -2624,7 +2614,7 @@ static long (*bpf_strtoul)(const char *buf, unsigned long buf_len, __u64 flags,
|
||||
* **NULL** if not found or there was an error in adding
|
||||
* a new bpf-local-storage.
|
||||
*/
|
||||
static void *(*bpf_sk_storage_get)(void *map, void *sk, void *value, __u64 flags) = (void *) 107;
|
||||
static void *(*bpf_sk_storage_get)(void *map, struct bpf_sock *sk, void *value, __u64 flags) = (void *) 107;
|
||||
|
||||
/*
|
||||
* bpf_sk_storage_delete
|
||||
@@ -2635,9 +2625,8 @@ static void *(*bpf_sk_storage_get)(void *map, void *sk, void *value, __u64 flags
|
||||
* 0 on success.
|
||||
*
|
||||
* **-ENOENT** if the bpf-local-storage cannot be found.
|
||||
* **-EINVAL** if sk is not a fullsock (e.g. a request_sock).
|
||||
*/
|
||||
static long (*bpf_sk_storage_delete)(void *map, void *sk) = (void *) 108;
|
||||
static long (*bpf_sk_storage_delete)(void *map, struct bpf_sock *sk) = (void *) 108;
|
||||
|
||||
/*
|
||||
* bpf_send_signal
|
||||
@@ -2686,7 +2675,7 @@ static long (*bpf_send_signal)(__u32 sig) = (void *) 109;
|
||||
*
|
||||
* **-EPROTONOSUPPORT** IP packet version is not 4 or 6
|
||||
*/
|
||||
static __s64 (*bpf_tcp_gen_syncookie)(void *sk, void *iph, __u32 iph_len, struct tcphdr *th, __u32 th_len) = (void *) 110;
|
||||
static __s64 (*bpf_tcp_gen_syncookie)(struct bpf_sock *sk, void *iph, __u32 iph_len, struct tcphdr *th, __u32 th_len) = (void *) 110;
|
||||
|
||||
/*
|
||||
* bpf_skb_output
|
||||
@@ -2976,7 +2965,7 @@ static __u64 (*bpf_get_current_ancestor_cgroup_id)(int ancestor_level) = (void *
|
||||
* **-ESOCKTNOSUPPORT** if the socket type is not supported
|
||||
* (reuseport).
|
||||
*/
|
||||
static long (*bpf_sk_assign)(void *ctx, void *sk, __u64 flags) = (void *) 124;
|
||||
static long (*bpf_sk_assign)(void *ctx, struct bpf_sock *sk, __u64 flags) = (void *) 124;
|
||||
|
||||
/*
|
||||
* bpf_ktime_get_boot_ns
|
||||
@@ -3042,7 +3031,7 @@ static long (*bpf_seq_write)(struct seq_file *m, const void *data, __u32 len) =
|
||||
*
|
||||
* Return the cgroup v2 id of the socket *sk*.
|
||||
*
|
||||
* *sk* must be a non-**NULL** pointer to a socket, e.g. one
|
||||
* *sk* must be a non-**NULL** pointer to a full socket, e.g. one
|
||||
* returned from **bpf_sk_lookup_xxx**\ (),
|
||||
* **bpf_sk_fullsock**\ (), etc. The format of returned id is
|
||||
* same as in **bpf_skb_cgroup_id**\ ().
|
||||
@@ -3053,7 +3042,7 @@ static long (*bpf_seq_write)(struct seq_file *m, const void *data, __u32 len) =
|
||||
* Returns
|
||||
* The id is returned or 0 in case the id could not be retrieved.
|
||||
*/
|
||||
static __u64 (*bpf_sk_cgroup_id)(void *sk) = (void *) 128;
|
||||
static __u64 (*bpf_sk_cgroup_id)(struct bpf_sock *sk) = (void *) 128;
|
||||
|
||||
/*
|
||||
* bpf_sk_ancestor_cgroup_id
|
||||
@@ -3075,7 +3064,7 @@ static __u64 (*bpf_sk_cgroup_id)(void *sk) = (void *) 128;
|
||||
* Returns
|
||||
* The id is returned or 0 in case the id could not be retrieved.
|
||||
*/
|
||||
static __u64 (*bpf_sk_ancestor_cgroup_id)(void *sk, int ancestor_level) = (void *) 129;
|
||||
static __u64 (*bpf_sk_ancestor_cgroup_id)(struct bpf_sock *sk, int ancestor_level) = (void *) 129;
|
||||
|
||||
/*
|
||||
* bpf_ringbuf_output
|
||||
@@ -3193,7 +3182,7 @@ static long (*bpf_csum_level)(struct __sk_buff *skb, __u64 level) = (void *) 135
|
||||
* Dynamically cast a *sk* pointer to a *tcp6_sock* pointer.
|
||||
*
|
||||
* Returns
|
||||
* *sk* if casting is valid, or **NULL** otherwise.
|
||||
* *sk* if casting is valid, or NULL otherwise.
|
||||
*/
|
||||
static struct tcp6_sock *(*bpf_skc_to_tcp6_sock)(void *sk) = (void *) 136;
|
||||
|
||||
@@ -3203,7 +3192,7 @@ static struct tcp6_sock *(*bpf_skc_to_tcp6_sock)(void *sk) = (void *) 136;
|
||||
* Dynamically cast a *sk* pointer to a *tcp_sock* pointer.
|
||||
*
|
||||
* Returns
|
||||
* *sk* if casting is valid, or **NULL** otherwise.
|
||||
* *sk* if casting is valid, or NULL otherwise.
|
||||
*/
|
||||
static struct tcp_sock *(*bpf_skc_to_tcp_sock)(void *sk) = (void *) 137;
|
||||
|
||||
@@ -3213,7 +3202,7 @@ static struct tcp_sock *(*bpf_skc_to_tcp_sock)(void *sk) = (void *) 137;
|
||||
* Dynamically cast a *sk* pointer to a *tcp_timewait_sock* pointer.
|
||||
*
|
||||
* Returns
|
||||
* *sk* if casting is valid, or **NULL** otherwise.
|
||||
* *sk* if casting is valid, or NULL otherwise.
|
||||
*/
|
||||
static struct tcp_timewait_sock *(*bpf_skc_to_tcp_timewait_sock)(void *sk) = (void *) 138;
|
||||
|
||||
@@ -3223,7 +3212,7 @@ static struct tcp_timewait_sock *(*bpf_skc_to_tcp_timewait_sock)(void *sk) = (vo
|
||||
* Dynamically cast a *sk* pointer to a *tcp_request_sock* pointer.
|
||||
*
|
||||
* Returns
|
||||
* *sk* if casting is valid, or **NULL** otherwise.
|
||||
* *sk* if casting is valid, or NULL otherwise.
|
||||
*/
|
||||
static struct tcp_request_sock *(*bpf_skc_to_tcp_request_sock)(void *sk) = (void *) 139;
|
||||
|
||||
@@ -3233,7 +3222,7 @@ static struct tcp_request_sock *(*bpf_skc_to_tcp_request_sock)(void *sk) = (void
|
||||
* Dynamically cast a *sk* pointer to a *udp6_sock* pointer.
|
||||
*
|
||||
* Returns
|
||||
* *sk* if casting is valid, or **NULL** otherwise.
|
||||
* *sk* if casting is valid, or NULL otherwise.
|
||||
*/
|
||||
static struct udp6_sock *(*bpf_skc_to_udp6_sock)(void *sk) = (void *) 140;
|
||||
|
||||
@@ -3242,8 +3231,8 @@ static struct udp6_sock *(*bpf_skc_to_udp6_sock)(void *sk) = (void *) 140;
|
||||
*
|
||||
* Return a user or a kernel stack in bpf program provided buffer.
|
||||
* To achieve this, the helper needs *task*, which is a valid
|
||||
* pointer to **struct task_struct**. To store the stacktrace, the
|
||||
* bpf program provides *buf* with a nonnegative *size*.
|
||||
* pointer to struct task_struct. To store the stacktrace, the
|
||||
* bpf program provides *buf* with a nonnegative *size*.
|
||||
*
|
||||
* The last argument, *flags*, holds the number of stack frames to
|
||||
* skip (from 0 to 255), masked with
|
||||
@@ -3273,462 +3262,4 @@ static struct udp6_sock *(*bpf_skc_to_udp6_sock)(void *sk) = (void *) 140;
|
||||
*/
|
||||
static long (*bpf_get_task_stack)(struct task_struct *task, void *buf, __u32 size, __u64 flags) = (void *) 141;
|
||||
|
||||
/*
|
||||
* bpf_load_hdr_opt
|
||||
*
|
||||
* Load header option. Support reading a particular TCP header
|
||||
* option for bpf program (**BPF_PROG_TYPE_SOCK_OPS**).
|
||||
*
|
||||
* If *flags* is 0, it will search the option from the
|
||||
* *skops*\ **->skb_data**. The comment in **struct bpf_sock_ops**
|
||||
* has details on what skb_data contains under different
|
||||
* *skops*\ **->op**.
|
||||
*
|
||||
* The first byte of the *searchby_res* specifies the
|
||||
* kind that it wants to search.
|
||||
*
|
||||
* If the searching kind is an experimental kind
|
||||
* (i.e. 253 or 254 according to RFC6994). It also
|
||||
* needs to specify the "magic" which is either
|
||||
* 2 bytes or 4 bytes. It then also needs to
|
||||
* specify the size of the magic by using
|
||||
* the 2nd byte which is "kind-length" of a TCP
|
||||
* header option and the "kind-length" also
|
||||
* includes the first 2 bytes "kind" and "kind-length"
|
||||
* itself as a normal TCP header option also does.
|
||||
*
|
||||
* For example, to search experimental kind 254 with
|
||||
* 2 byte magic 0xeB9F, the searchby_res should be
|
||||
* [ 254, 4, 0xeB, 0x9F, 0, 0, .... 0 ].
|
||||
*
|
||||
* To search for the standard window scale option (3),
|
||||
* the *searchby_res* should be [ 3, 0, 0, .... 0 ].
|
||||
* Note, kind-length must be 0 for regular option.
|
||||
*
|
||||
* Searching for No-Op (0) and End-of-Option-List (1) are
|
||||
* not supported.
|
||||
*
|
||||
* *len* must be at least 2 bytes which is the minimal size
|
||||
* of a header option.
|
||||
*
|
||||
* Supported flags:
|
||||
*
|
||||
* * **BPF_LOAD_HDR_OPT_TCP_SYN** to search from the
|
||||
* saved_syn packet or the just-received syn packet.
|
||||
*
|
||||
*
|
||||
* Returns
|
||||
* > 0 when found, the header option is copied to *searchby_res*.
|
||||
* The return value is the total length copied. On failure, a
|
||||
* negative error code is returned:
|
||||
*
|
||||
* **-EINVAL** if a parameter is invalid.
|
||||
*
|
||||
* **-ENOMSG** if the option is not found.
|
||||
*
|
||||
* **-ENOENT** if no syn packet is available when
|
||||
* **BPF_LOAD_HDR_OPT_TCP_SYN** is used.
|
||||
*
|
||||
* **-ENOSPC** if there is not enough space. Only *len* number of
|
||||
* bytes are copied.
|
||||
*
|
||||
* **-EFAULT** on failure to parse the header options in the
|
||||
* packet.
|
||||
*
|
||||
* **-EPERM** if the helper cannot be used under the current
|
||||
* *skops*\ **->op**.
|
||||
*/
|
||||
static long (*bpf_load_hdr_opt)(struct bpf_sock_ops *skops, void *searchby_res, __u32 len, __u64 flags) = (void *) 142;
|
||||
|
||||
/*
|
||||
* bpf_store_hdr_opt
|
||||
*
|
||||
* Store header option. The data will be copied
|
||||
* from buffer *from* with length *len* to the TCP header.
|
||||
*
|
||||
* The buffer *from* should have the whole option that
|
||||
* includes the kind, kind-length, and the actual
|
||||
* option data. The *len* must be at least kind-length
|
||||
* long. The kind-length does not have to be 4 byte
|
||||
* aligned. The kernel will take care of the padding
|
||||
* and setting the 4 bytes aligned value to th->doff.
|
||||
*
|
||||
* This helper will check for duplicated option
|
||||
* by searching the same option in the outgoing skb.
|
||||
*
|
||||
* This helper can only be called during
|
||||
* **BPF_SOCK_OPS_WRITE_HDR_OPT_CB**.
|
||||
*
|
||||
*
|
||||
* Returns
|
||||
* 0 on success, or negative error in case of failure:
|
||||
*
|
||||
* **-EINVAL** If param is invalid.
|
||||
*
|
||||
* **-ENOSPC** if there is not enough space in the header.
|
||||
* Nothing has been written
|
||||
*
|
||||
* **-EEXIST** if the option already exists.
|
||||
*
|
||||
* **-EFAULT** on failrue to parse the existing header options.
|
||||
*
|
||||
* **-EPERM** if the helper cannot be used under the current
|
||||
* *skops*\ **->op**.
|
||||
*/
|
||||
static long (*bpf_store_hdr_opt)(struct bpf_sock_ops *skops, const void *from, __u32 len, __u64 flags) = (void *) 143;
|
||||
|
||||
/*
|
||||
* bpf_reserve_hdr_opt
|
||||
*
|
||||
* Reserve *len* bytes for the bpf header option. The
|
||||
* space will be used by **bpf_store_hdr_opt**\ () later in
|
||||
* **BPF_SOCK_OPS_WRITE_HDR_OPT_CB**.
|
||||
*
|
||||
* If **bpf_reserve_hdr_opt**\ () is called multiple times,
|
||||
* the total number of bytes will be reserved.
|
||||
*
|
||||
* This helper can only be called during
|
||||
* **BPF_SOCK_OPS_HDR_OPT_LEN_CB**.
|
||||
*
|
||||
*
|
||||
* Returns
|
||||
* 0 on success, or negative error in case of failure:
|
||||
*
|
||||
* **-EINVAL** if a parameter is invalid.
|
||||
*
|
||||
* **-ENOSPC** if there is not enough space in the header.
|
||||
*
|
||||
* **-EPERM** if the helper cannot be used under the current
|
||||
* *skops*\ **->op**.
|
||||
*/
|
||||
static long (*bpf_reserve_hdr_opt)(struct bpf_sock_ops *skops, __u32 len, __u64 flags) = (void *) 144;
|
||||
|
||||
/*
|
||||
* bpf_inode_storage_get
|
||||
*
|
||||
* Get a bpf_local_storage from an *inode*.
|
||||
*
|
||||
* Logically, it could be thought of as getting the value from
|
||||
* a *map* with *inode* as the **key**. From this
|
||||
* perspective, the usage is not much different from
|
||||
* **bpf_map_lookup_elem**\ (*map*, **&**\ *inode*) except this
|
||||
* helper enforces the key must be an inode and the map must also
|
||||
* be a **BPF_MAP_TYPE_INODE_STORAGE**.
|
||||
*
|
||||
* Underneath, the value is stored locally at *inode* instead of
|
||||
* the *map*. The *map* is used as the bpf-local-storage
|
||||
* "type". The bpf-local-storage "type" (i.e. the *map*) is
|
||||
* searched against all bpf_local_storage residing at *inode*.
|
||||
*
|
||||
* An optional *flags* (**BPF_LOCAL_STORAGE_GET_F_CREATE**) can be
|
||||
* used such that a new bpf_local_storage will be
|
||||
* created if one does not exist. *value* can be used
|
||||
* together with **BPF_LOCAL_STORAGE_GET_F_CREATE** to specify
|
||||
* the initial value of a bpf_local_storage. If *value* is
|
||||
* **NULL**, the new bpf_local_storage will be zero initialized.
|
||||
*
|
||||
* Returns
|
||||
* A bpf_local_storage pointer is returned on success.
|
||||
*
|
||||
* **NULL** if not found or there was an error in adding
|
||||
* a new bpf_local_storage.
|
||||
*/
|
||||
static void *(*bpf_inode_storage_get)(void *map, void *inode, void *value, __u64 flags) = (void *) 145;
|
||||
|
||||
/*
|
||||
* bpf_inode_storage_delete
|
||||
*
|
||||
* Delete a bpf_local_storage from an *inode*.
|
||||
*
|
||||
* Returns
|
||||
* 0 on success.
|
||||
*
|
||||
* **-ENOENT** if the bpf_local_storage cannot be found.
|
||||
*/
|
||||
static int (*bpf_inode_storage_delete)(void *map, void *inode) = (void *) 146;
|
||||
|
||||
/*
|
||||
* bpf_d_path
|
||||
*
|
||||
* Return full path for given **struct path** object, which
|
||||
* needs to be the kernel BTF *path* object. The path is
|
||||
* returned in the provided buffer *buf* of size *sz* and
|
||||
* is zero terminated.
|
||||
*
|
||||
*
|
||||
* Returns
|
||||
* On success, the strictly positive length of the string,
|
||||
* including the trailing NUL character. On error, a negative
|
||||
* value.
|
||||
*/
|
||||
static long (*bpf_d_path)(struct path *path, char *buf, __u32 sz) = (void *) 147;
|
||||
|
||||
/*
|
||||
* bpf_copy_from_user
|
||||
*
|
||||
* Read *size* bytes from user space address *user_ptr* and store
|
||||
* the data in *dst*. This is a wrapper of **copy_from_user**\ ().
|
||||
*
|
||||
* Returns
|
||||
* 0 on success, or a negative error in case of failure.
|
||||
*/
|
||||
static long (*bpf_copy_from_user)(void *dst, __u32 size, const void *user_ptr) = (void *) 148;
|
||||
|
||||
/*
|
||||
* bpf_snprintf_btf
|
||||
*
|
||||
* Use BTF to store a string representation of *ptr*->ptr in *str*,
|
||||
* using *ptr*->type_id. This value should specify the type
|
||||
* that *ptr*->ptr points to. LLVM __builtin_btf_type_id(type, 1)
|
||||
* can be used to look up vmlinux BTF type ids. Traversing the
|
||||
* data structure using BTF, the type information and values are
|
||||
* stored in the first *str_size* - 1 bytes of *str*. Safe copy of
|
||||
* the pointer data is carried out to avoid kernel crashes during
|
||||
* operation. Smaller types can use string space on the stack;
|
||||
* larger programs can use map data to store the string
|
||||
* representation.
|
||||
*
|
||||
* The string can be subsequently shared with userspace via
|
||||
* bpf_perf_event_output() or ring buffer interfaces.
|
||||
* bpf_trace_printk() is to be avoided as it places too small
|
||||
* a limit on string size to be useful.
|
||||
*
|
||||
* *flags* is a combination of
|
||||
*
|
||||
* **BTF_F_COMPACT**
|
||||
* no formatting around type information
|
||||
* **BTF_F_NONAME**
|
||||
* no struct/union member names/types
|
||||
* **BTF_F_PTR_RAW**
|
||||
* show raw (unobfuscated) pointer values;
|
||||
* equivalent to printk specifier %px.
|
||||
* **BTF_F_ZERO**
|
||||
* show zero-valued struct/union members; they
|
||||
* are not displayed by default
|
||||
*
|
||||
*
|
||||
* Returns
|
||||
* The number of bytes that were written (or would have been
|
||||
* written if output had to be truncated due to string size),
|
||||
* or a negative error in cases of failure.
|
||||
*/
|
||||
static long (*bpf_snprintf_btf)(char *str, __u32 str_size, struct btf_ptr *ptr, __u32 btf_ptr_size, __u64 flags) = (void *) 149;
|
||||
|
||||
/*
|
||||
* bpf_seq_printf_btf
|
||||
*
|
||||
* Use BTF to write to seq_write a string representation of
|
||||
* *ptr*->ptr, using *ptr*->type_id as per bpf_snprintf_btf().
|
||||
* *flags* are identical to those used for bpf_snprintf_btf.
|
||||
*
|
||||
* Returns
|
||||
* 0 on success or a negative error in case of failure.
|
||||
*/
|
||||
static long (*bpf_seq_printf_btf)(struct seq_file *m, struct btf_ptr *ptr, __u32 ptr_size, __u64 flags) = (void *) 150;
|
||||
|
||||
/*
|
||||
* bpf_skb_cgroup_classid
|
||||
*
|
||||
* See **bpf_get_cgroup_classid**\ () for the main description.
|
||||
* This helper differs from **bpf_get_cgroup_classid**\ () in that
|
||||
* the cgroup v1 net_cls class is retrieved only from the *skb*'s
|
||||
* associated socket instead of the current process.
|
||||
*
|
||||
* Returns
|
||||
* The id is returned or 0 in case the id could not be retrieved.
|
||||
*/
|
||||
static __u64 (*bpf_skb_cgroup_classid)(struct __sk_buff *skb) = (void *) 151;
|
||||
|
||||
/*
|
||||
* bpf_redirect_neigh
|
||||
*
|
||||
* Redirect the packet to another net device of index *ifindex*
|
||||
* and fill in L2 addresses from neighboring subsystem. This helper
|
||||
* is somewhat similar to **bpf_redirect**\ (), except that it
|
||||
* populates L2 addresses as well, meaning, internally, the helper
|
||||
* relies on the neighbor lookup for the L2 address of the nexthop.
|
||||
*
|
||||
* The helper will perform a FIB lookup based on the skb's
|
||||
* networking header to get the address of the next hop, unless
|
||||
* this is supplied by the caller in the *params* argument. The
|
||||
* *plen* argument indicates the len of *params* and should be set
|
||||
* to 0 if *params* is NULL.
|
||||
*
|
||||
* The *flags* argument is reserved and must be 0. The helper is
|
||||
* currently only supported for tc BPF program types, and enabled
|
||||
* for IPv4 and IPv6 protocols.
|
||||
*
|
||||
* Returns
|
||||
* The helper returns **TC_ACT_REDIRECT** on success or
|
||||
* **TC_ACT_SHOT** on error.
|
||||
*/
|
||||
static long (*bpf_redirect_neigh)(__u32 ifindex, struct bpf_redir_neigh *params, int plen, __u64 flags) = (void *) 152;
|
||||
|
||||
/*
|
||||
* bpf_per_cpu_ptr
|
||||
*
|
||||
* Take a pointer to a percpu ksym, *percpu_ptr*, and return a
|
||||
* pointer to the percpu kernel variable on *cpu*. A ksym is an
|
||||
* extern variable decorated with '__ksym'. For ksym, there is a
|
||||
* global var (either static or global) defined of the same name
|
||||
* in the kernel. The ksym is percpu if the global var is percpu.
|
||||
* The returned pointer points to the global percpu var on *cpu*.
|
||||
*
|
||||
* bpf_per_cpu_ptr() has the same semantic as per_cpu_ptr() in the
|
||||
* kernel, except that bpf_per_cpu_ptr() may return NULL. This
|
||||
* happens if *cpu* is larger than nr_cpu_ids. The caller of
|
||||
* bpf_per_cpu_ptr() must check the returned value.
|
||||
*
|
||||
* Returns
|
||||
* A pointer pointing to the kernel percpu variable on *cpu*, or
|
||||
* NULL, if *cpu* is invalid.
|
||||
*/
|
||||
static void *(*bpf_per_cpu_ptr)(const void *percpu_ptr, __u32 cpu) = (void *) 153;
|
||||
|
||||
/*
|
||||
* bpf_this_cpu_ptr
|
||||
*
|
||||
* Take a pointer to a percpu ksym, *percpu_ptr*, and return a
|
||||
* pointer to the percpu kernel variable on this cpu. See the
|
||||
* description of 'ksym' in **bpf_per_cpu_ptr**\ ().
|
||||
*
|
||||
* bpf_this_cpu_ptr() has the same semantic as this_cpu_ptr() in
|
||||
* the kernel. Different from **bpf_per_cpu_ptr**\ (), it would
|
||||
* never return NULL.
|
||||
*
|
||||
* Returns
|
||||
* A pointer pointing to the kernel percpu variable on this cpu.
|
||||
*/
|
||||
static void *(*bpf_this_cpu_ptr)(const void *percpu_ptr) = (void *) 154;
|
||||
|
||||
/*
|
||||
* bpf_redirect_peer
|
||||
*
|
||||
* Redirect the packet to another net device of index *ifindex*.
|
||||
* This helper is somewhat similar to **bpf_redirect**\ (), except
|
||||
* that the redirection happens to the *ifindex*' peer device and
|
||||
* the netns switch takes place from ingress to ingress without
|
||||
* going through the CPU's backlog queue.
|
||||
*
|
||||
* The *flags* argument is reserved and must be 0. The helper is
|
||||
* currently only supported for tc BPF program types at the ingress
|
||||
* hook and for veth device types. The peer device must reside in a
|
||||
* different network namespace.
|
||||
*
|
||||
* Returns
|
||||
* The helper returns **TC_ACT_REDIRECT** on success or
|
||||
* **TC_ACT_SHOT** on error.
|
||||
*/
|
||||
static long (*bpf_redirect_peer)(__u32 ifindex, __u64 flags) = (void *) 155;
|
||||
|
||||
/*
|
||||
* bpf_task_storage_get
|
||||
*
|
||||
* Get a bpf_local_storage from the *task*.
|
||||
*
|
||||
* Logically, it could be thought of as getting the value from
|
||||
* a *map* with *task* as the **key**. From this
|
||||
* perspective, the usage is not much different from
|
||||
* **bpf_map_lookup_elem**\ (*map*, **&**\ *task*) except this
|
||||
* helper enforces the key must be an task_struct and the map must also
|
||||
* be a **BPF_MAP_TYPE_TASK_STORAGE**.
|
||||
*
|
||||
* Underneath, the value is stored locally at *task* instead of
|
||||
* the *map*. The *map* is used as the bpf-local-storage
|
||||
* "type". The bpf-local-storage "type" (i.e. the *map*) is
|
||||
* searched against all bpf_local_storage residing at *task*.
|
||||
*
|
||||
* An optional *flags* (**BPF_LOCAL_STORAGE_GET_F_CREATE**) can be
|
||||
* used such that a new bpf_local_storage will be
|
||||
* created if one does not exist. *value* can be used
|
||||
* together with **BPF_LOCAL_STORAGE_GET_F_CREATE** to specify
|
||||
* the initial value of a bpf_local_storage. If *value* is
|
||||
* **NULL**, the new bpf_local_storage will be zero initialized.
|
||||
*
|
||||
* Returns
|
||||
* A bpf_local_storage pointer is returned on success.
|
||||
*
|
||||
* **NULL** if not found or there was an error in adding
|
||||
* a new bpf_local_storage.
|
||||
*/
|
||||
static void *(*bpf_task_storage_get)(void *map, struct task_struct *task, void *value, __u64 flags) = (void *) 156;
|
||||
|
||||
/*
|
||||
* bpf_task_storage_delete
|
||||
*
|
||||
* Delete a bpf_local_storage from a *task*.
|
||||
*
|
||||
* Returns
|
||||
* 0 on success.
|
||||
*
|
||||
* **-ENOENT** if the bpf_local_storage cannot be found.
|
||||
*/
|
||||
static long (*bpf_task_storage_delete)(void *map, struct task_struct *task) = (void *) 157;
|
||||
|
||||
/*
|
||||
* bpf_get_current_task_btf
|
||||
*
|
||||
* Return a BTF pointer to the "current" task.
|
||||
* This pointer can also be used in helpers that accept an
|
||||
* *ARG_PTR_TO_BTF_ID* of type *task_struct*.
|
||||
*
|
||||
* Returns
|
||||
* Pointer to the current task.
|
||||
*/
|
||||
static struct task_struct *(*bpf_get_current_task_btf)(void) = (void *) 158;
|
||||
|
||||
/*
|
||||
* bpf_bprm_opts_set
|
||||
*
|
||||
* Set or clear certain options on *bprm*:
|
||||
*
|
||||
* **BPF_F_BPRM_SECUREEXEC** Set the secureexec bit
|
||||
* which sets the **AT_SECURE** auxv for glibc. The bit
|
||||
* is cleared if the flag is not specified.
|
||||
*
|
||||
* Returns
|
||||
* **-EINVAL** if invalid *flags* are passed, zero otherwise.
|
||||
*/
|
||||
static long (*bpf_bprm_opts_set)(struct linux_binprm *bprm, __u64 flags) = (void *) 159;
|
||||
|
||||
/*
|
||||
* bpf_ktime_get_coarse_ns
|
||||
*
|
||||
* Return a coarse-grained version of the time elapsed since
|
||||
* system boot, in nanoseconds. Does not include time the system
|
||||
* was suspended.
|
||||
*
|
||||
* See: **clock_gettime**\ (**CLOCK_MONOTONIC_COARSE**)
|
||||
*
|
||||
* Returns
|
||||
* Current *ktime*.
|
||||
*/
|
||||
static __u64 (*bpf_ktime_get_coarse_ns)(void) = (void *) 160;
|
||||
|
||||
/*
|
||||
* bpf_ima_inode_hash
|
||||
*
|
||||
* Returns the stored IMA hash of the *inode* (if it's avaialable).
|
||||
* If the hash is larger than *size*, then only *size*
|
||||
* bytes will be copied to *dst*
|
||||
*
|
||||
* Returns
|
||||
* The **hash_algo** is returned on success,
|
||||
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
|
||||
* invalid arguments are passed.
|
||||
*/
|
||||
static long (*bpf_ima_inode_hash)(struct inode *inode, void *dst, __u32 size) = (void *) 161;
|
||||
|
||||
/*
|
||||
* bpf_sock_from_file
|
||||
*
|
||||
* If the given file represents a socket, returns the associated
|
||||
* socket.
|
||||
*
|
||||
* Returns
|
||||
* A pointer to a struct socket on success or NULL if the file is
|
||||
* not a socket.
|
||||
*/
|
||||
static struct socket *(*bpf_sock_from_file)(struct file *file) = (void *) 162;
|
||||
|
||||
|
||||
|
||||
@@ -32,9 +32,6 @@
|
||||
#ifndef __always_inline
|
||||
#define __always_inline __attribute__((always_inline))
|
||||
#endif
|
||||
#ifndef __noinline
|
||||
#define __noinline __attribute__((noinline))
|
||||
#endif
|
||||
#ifndef __weak
|
||||
#define __weak __attribute__((weak))
|
||||
#endif
|
||||
@@ -53,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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
112
src/btf.h
112
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,49 @@ 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 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,13 +74,10 @@ 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);
|
||||
@@ -65,7 +85,6 @@ 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,62 +95,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_int(struct btf *btf, const char *name, size_t byte_sz, int encoding);
|
||||
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;
|
||||
|
||||
@@ -19,6 +19,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 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;
|
||||
|
||||
@@ -60,14 +63,11 @@ struct btf_dump {
|
||||
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 +93,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 +123,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,
|
||||
@@ -148,8 +154,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,38 +182,9 @@ 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 (btf_ensure_mem((void **)&d->type_states, &d->type_states_cap,
|
||||
sizeof(*d->type_states), last_id + 1))
|
||||
return -ENOMEM;
|
||||
if (btf_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))
|
||||
return;
|
||||
@@ -198,7 +192,7 @@ void btf_dump__free(struct btf_dump *d)
|
||||
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 +232,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 +261,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);
|
||||
|
||||
@@ -326,7 +316,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;
|
||||
@@ -334,7 +323,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;
|
||||
@@ -1013,7 +1003,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;
|
||||
@@ -1070,15 +1061,11 @@ 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
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);
|
||||
@@ -28,18 +25,6 @@ static inline size_t hash_bits(size_t h, int bits)
|
||||
#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;
|
||||
}
|
||||
|
||||
typedef size_t (*hashmap_hash_fn)(const void *key, void *ctx);
|
||||
typedef bool (*hashmap_equal_fn)(const void *key1, const void *key2, void *ctx);
|
||||
|
||||
@@ -177,17 +162,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))
|
||||
|
||||
3969
src/libbpf.c
3969
src/libbpf.c
File diff suppressed because it is too large
Load Diff
13
src/libbpf.h
13
src/libbpf.h
@@ -198,9 +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 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);
|
||||
|
||||
@@ -261,9 +260,6 @@ 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;
|
||||
|
||||
@@ -536,7 +532,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;
|
||||
@@ -593,12 +588,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,
|
||||
|
||||
@@ -299,54 +299,3 @@ LIBBPF_0.1.0 {
|
||||
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;
|
||||
|
||||
@@ -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,15 +9,6 @@
|
||||
#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"
|
||||
|
||||
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
|
||||
@@ -32,12 +23,6 @@
|
||||
#define BTF_PARAM_ENC(name, type) (name), (type)
|
||||
#define BTF_VAR_SECINFO_ENC(type, offset, size) (type), (offset), (size)
|
||||
|
||||
#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
|
||||
@@ -78,37 +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);
|
||||
}
|
||||
|
||||
void *btf_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 btf_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)
|
||||
@@ -140,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 {
|
||||
/*
|
||||
@@ -208,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;
|
||||
@@ -253,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;
|
||||
};
|
||||
|
||||
@@ -278,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.
|
||||
*
|
||||
@@ -342,11 +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;
|
||||
};
|
||||
|
||||
#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);
|
||||
@@ -170,7 +173,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 +232,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;
|
||||
|
||||
128
src/netlink.c
128
src/netlink.c
@@ -15,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);
|
||||
|
||||
@@ -30,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;
|
||||
@@ -282,9 +283,6 @@ static int get_xdp_info(void *cookie, void *msg, struct nlattr **tb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int libbpf_nl_get_link(int sock, unsigned int nl_pid,
|
||||
libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie);
|
||||
|
||||
int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
|
||||
size_t info_size, __u32 flags)
|
||||
{
|
||||
@@ -370,3 +368,121 @@ int libbpf_nl_get_link(int sock, unsigned int nl_pid,
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_link_nlmsg,
|
||||
dump_link_nlmsg, cookie);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct {
|
||||
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);
|
||||
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_class_nlmsg,
|
||||
dump_class_nlmsg, cookie);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct {
|
||||
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);
|
||||
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
return bpf_netlink_recv(sock, nl_pid, seq, __dump_qdisc_nlmsg,
|
||||
dump_qdisc_nlmsg, cookie);
|
||||
}
|
||||
|
||||
static int __dump_filter_nlmsg(struct nlmsghdr *nlh,
|
||||
libbpf_dump_nlmsg_t dump_filter_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_filter_nlmsg(cookie, t, tb);
|
||||
}
|
||||
|
||||
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 {
|
||||
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);
|
||||
|
||||
req.nlh.nlmsg_seq = seq;
|
||||
if (send(sock, &req, req.nlh.nlmsg_len, 0) < 0)
|
||||
return -errno;
|
||||
|
||||
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),
|
||||
|
||||
@@ -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;
|
||||
@@ -278,13 +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;
|
||||
}
|
||||
return cnt < 0 ? -errno : 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;
|
||||
}
|
||||
|
||||
478
src/xsk.c
478
src/xsk.c
@@ -20,8 +20,6 @@
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_xdp.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -34,6 +32,9 @@
|
||||
#include "libbpf_internal.h"
|
||||
#include "xsk.h"
|
||||
|
||||
/* make sure libbpf doesn't use kernel-only integer typedefs */
|
||||
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
|
||||
|
||||
#ifndef SOL_XDP
|
||||
#define SOL_XDP 283
|
||||
#endif
|
||||
@@ -47,35 +48,26 @@
|
||||
#endif
|
||||
|
||||
struct xsk_umem {
|
||||
struct xsk_ring_prod *fill_save;
|
||||
struct xsk_ring_cons *comp_save;
|
||||
struct xsk_ring_prod *fill;
|
||||
struct xsk_ring_cons *comp;
|
||||
char *umem_area;
|
||||
struct xsk_umem_config config;
|
||||
int fd;
|
||||
int refcount;
|
||||
struct list_head ctx_list;
|
||||
};
|
||||
|
||||
struct xsk_ctx {
|
||||
struct xsk_ring_prod *fill;
|
||||
struct xsk_ring_cons *comp;
|
||||
__u32 queue_id;
|
||||
struct xsk_umem *umem;
|
||||
int refcount;
|
||||
int ifindex;
|
||||
struct list_head list;
|
||||
int prog_fd;
|
||||
int xsks_map_fd;
|
||||
char ifname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
struct xsk_socket {
|
||||
struct xsk_ring_cons *rx;
|
||||
struct xsk_ring_prod *tx;
|
||||
__u64 outstanding_tx;
|
||||
struct xsk_ctx *ctx;
|
||||
struct xsk_umem *umem;
|
||||
struct xsk_socket_config config;
|
||||
int fd;
|
||||
int ifindex;
|
||||
int prog_fd;
|
||||
int xsks_map_fd;
|
||||
__u32 queue_id;
|
||||
char ifname[IFNAMSIZ];
|
||||
};
|
||||
|
||||
struct xsk_nl_info {
|
||||
@@ -211,73 +203,15 @@ static int xsk_get_mmap_offsets(int fd, struct xdp_mmap_offsets *off)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int xsk_create_umem_rings(struct xsk_umem *umem, int fd,
|
||||
struct xsk_ring_prod *fill,
|
||||
struct xsk_ring_cons *comp)
|
||||
{
|
||||
struct xdp_mmap_offsets off;
|
||||
void *map;
|
||||
int err;
|
||||
|
||||
err = setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING,
|
||||
&umem->config.fill_size,
|
||||
sizeof(umem->config.fill_size));
|
||||
if (err)
|
||||
return -errno;
|
||||
|
||||
err = setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING,
|
||||
&umem->config.comp_size,
|
||||
sizeof(umem->config.comp_size));
|
||||
if (err)
|
||||
return -errno;
|
||||
|
||||
err = xsk_get_mmap_offsets(fd, &off);
|
||||
if (err)
|
||||
return -errno;
|
||||
|
||||
map = mmap(NULL, off.fr.desc + umem->config.fill_size * sizeof(__u64),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd,
|
||||
XDP_UMEM_PGOFF_FILL_RING);
|
||||
if (map == MAP_FAILED)
|
||||
return -errno;
|
||||
|
||||
fill->mask = umem->config.fill_size - 1;
|
||||
fill->size = umem->config.fill_size;
|
||||
fill->producer = map + off.fr.producer;
|
||||
fill->consumer = map + off.fr.consumer;
|
||||
fill->flags = map + off.fr.flags;
|
||||
fill->ring = map + off.fr.desc;
|
||||
fill->cached_cons = umem->config.fill_size;
|
||||
|
||||
map = mmap(NULL, off.cr.desc + umem->config.comp_size * sizeof(__u64),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd,
|
||||
XDP_UMEM_PGOFF_COMPLETION_RING);
|
||||
if (map == MAP_FAILED) {
|
||||
err = -errno;
|
||||
goto out_mmap;
|
||||
}
|
||||
|
||||
comp->mask = umem->config.comp_size - 1;
|
||||
comp->size = umem->config.comp_size;
|
||||
comp->producer = map + off.cr.producer;
|
||||
comp->consumer = map + off.cr.consumer;
|
||||
comp->flags = map + off.cr.flags;
|
||||
comp->ring = map + off.cr.desc;
|
||||
|
||||
return 0;
|
||||
|
||||
out_mmap:
|
||||
munmap(map, off.fr.desc + umem->config.fill_size * sizeof(__u64));
|
||||
return err;
|
||||
}
|
||||
|
||||
int xsk_umem__create_v0_0_4(struct xsk_umem **umem_ptr, void *umem_area,
|
||||
__u64 size, struct xsk_ring_prod *fill,
|
||||
struct xsk_ring_cons *comp,
|
||||
const struct xsk_umem_config *usr_config)
|
||||
{
|
||||
struct xdp_mmap_offsets off;
|
||||
struct xdp_umem_reg mr;
|
||||
struct xsk_umem *umem;
|
||||
void *map;
|
||||
int err;
|
||||
|
||||
if (!umem_area || !umem_ptr || !fill || !comp)
|
||||
@@ -296,7 +230,6 @@ int xsk_umem__create_v0_0_4(struct xsk_umem **umem_ptr, void *umem_area,
|
||||
}
|
||||
|
||||
umem->umem_area = umem_area;
|
||||
INIT_LIST_HEAD(&umem->ctx_list);
|
||||
xsk_set_umem_config(&umem->config, usr_config);
|
||||
|
||||
memset(&mr, 0, sizeof(mr));
|
||||
@@ -311,16 +244,71 @@ int xsk_umem__create_v0_0_4(struct xsk_umem **umem_ptr, void *umem_area,
|
||||
err = -errno;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
err = xsk_create_umem_rings(umem, umem->fd, fill, comp);
|
||||
if (err)
|
||||
err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_FILL_RING,
|
||||
&umem->config.fill_size,
|
||||
sizeof(umem->config.fill_size));
|
||||
if (err) {
|
||||
err = -errno;
|
||||
goto out_socket;
|
||||
}
|
||||
err = setsockopt(umem->fd, SOL_XDP, XDP_UMEM_COMPLETION_RING,
|
||||
&umem->config.comp_size,
|
||||
sizeof(umem->config.comp_size));
|
||||
if (err) {
|
||||
err = -errno;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
err = xsk_get_mmap_offsets(umem->fd, &off);
|
||||
if (err) {
|
||||
err = -errno;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
map = mmap(NULL, off.fr.desc + umem->config.fill_size * sizeof(__u64),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, umem->fd,
|
||||
XDP_UMEM_PGOFF_FILL_RING);
|
||||
if (map == MAP_FAILED) {
|
||||
err = -errno;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
umem->fill = fill;
|
||||
fill->mask = umem->config.fill_size - 1;
|
||||
fill->size = umem->config.fill_size;
|
||||
fill->producer = map + off.fr.producer;
|
||||
fill->consumer = map + off.fr.consumer;
|
||||
fill->flags = map + off.fr.flags;
|
||||
fill->ring = map + off.fr.desc;
|
||||
fill->cached_prod = *fill->producer;
|
||||
/* cached_cons is "size" bigger than the real consumer pointer
|
||||
* See xsk_prod_nb_free
|
||||
*/
|
||||
fill->cached_cons = *fill->consumer + umem->config.fill_size;
|
||||
|
||||
map = mmap(NULL, off.cr.desc + umem->config.comp_size * sizeof(__u64),
|
||||
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, umem->fd,
|
||||
XDP_UMEM_PGOFF_COMPLETION_RING);
|
||||
if (map == MAP_FAILED) {
|
||||
err = -errno;
|
||||
goto out_mmap;
|
||||
}
|
||||
|
||||
umem->comp = comp;
|
||||
comp->mask = umem->config.comp_size - 1;
|
||||
comp->size = umem->config.comp_size;
|
||||
comp->producer = map + off.cr.producer;
|
||||
comp->consumer = map + off.cr.consumer;
|
||||
comp->flags = map + off.cr.flags;
|
||||
comp->ring = map + off.cr.desc;
|
||||
comp->cached_prod = *comp->producer;
|
||||
comp->cached_cons = *comp->consumer;
|
||||
|
||||
umem->fill_save = fill;
|
||||
umem->comp_save = comp;
|
||||
*umem_ptr = umem;
|
||||
return 0;
|
||||
|
||||
out_mmap:
|
||||
munmap(map, off.fr.desc + umem->config.fill_size * sizeof(__u64));
|
||||
out_socket:
|
||||
close(umem->fd);
|
||||
out_umem_alloc:
|
||||
@@ -354,7 +342,6 @@ DEFAULT_VERSION(xsk_umem__create_v0_0_4, xsk_umem__create, LIBBPF_0.0.4)
|
||||
static int xsk_load_xdp_prog(struct xsk_socket *xsk)
|
||||
{
|
||||
static const int log_buf_size = 16 * 1024;
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
char log_buf[log_buf_size];
|
||||
int err, prog_fd;
|
||||
|
||||
@@ -382,7 +369,7 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
|
||||
/* *(u32 *)(r10 - 4) = r2 */
|
||||
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -4),
|
||||
/* r1 = xskmap[] */
|
||||
BPF_LD_MAP_FD(BPF_REG_1, ctx->xsks_map_fd),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, xsk->xsks_map_fd),
|
||||
/* r3 = XDP_PASS */
|
||||
BPF_MOV64_IMM(BPF_REG_3, 2),
|
||||
/* call bpf_redirect_map */
|
||||
@@ -394,7 +381,7 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
|
||||
/* r2 += -4 */
|
||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
|
||||
/* r1 = xskmap[] */
|
||||
BPF_LD_MAP_FD(BPF_REG_1, ctx->xsks_map_fd),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, xsk->xsks_map_fd),
|
||||
/* call bpf_map_lookup_elem */
|
||||
BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
|
||||
/* r1 = r0 */
|
||||
@@ -406,7 +393,7 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
|
||||
/* r2 = *(u32 *)(r10 - 4) */
|
||||
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_10, -4),
|
||||
/* r1 = xskmap[] */
|
||||
BPF_LD_MAP_FD(BPF_REG_1, ctx->xsks_map_fd),
|
||||
BPF_LD_MAP_FD(BPF_REG_1, xsk->xsks_map_fd),
|
||||
/* r3 = 0 */
|
||||
BPF_MOV64_IMM(BPF_REG_3, 0),
|
||||
/* call bpf_redirect_map */
|
||||
@@ -424,21 +411,19 @@ static int xsk_load_xdp_prog(struct xsk_socket *xsk)
|
||||
return prog_fd;
|
||||
}
|
||||
|
||||
err = bpf_set_link_xdp_fd(xsk->ctx->ifindex, prog_fd,
|
||||
xsk->config.xdp_flags);
|
||||
err = bpf_set_link_xdp_fd(xsk->ifindex, prog_fd, xsk->config.xdp_flags);
|
||||
if (err) {
|
||||
close(prog_fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
ctx->prog_fd = prog_fd;
|
||||
xsk->prog_fd = prog_fd;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xsk_get_max_queues(struct xsk_socket *xsk)
|
||||
{
|
||||
struct ethtool_channels channels = { .cmd = ETHTOOL_GCHANNELS };
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
struct ifreq ifr = {};
|
||||
int fd, err, ret;
|
||||
|
||||
@@ -447,7 +432,7 @@ static int xsk_get_max_queues(struct xsk_socket *xsk)
|
||||
return -errno;
|
||||
|
||||
ifr.ifr_data = (void *)&channels;
|
||||
memcpy(ifr.ifr_name, ctx->ifname, IFNAMSIZ - 1);
|
||||
memcpy(ifr.ifr_name, xsk->ifname, IFNAMSIZ - 1);
|
||||
ifr.ifr_name[IFNAMSIZ - 1] = '\0';
|
||||
err = ioctl(fd, SIOCETHTOOL, &ifr);
|
||||
if (err && errno != EOPNOTSUPP) {
|
||||
@@ -475,7 +460,6 @@ out:
|
||||
|
||||
static int xsk_create_bpf_maps(struct xsk_socket *xsk)
|
||||
{
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
int max_queues;
|
||||
int fd;
|
||||
|
||||
@@ -488,17 +472,15 @@ static int xsk_create_bpf_maps(struct xsk_socket *xsk)
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
ctx->xsks_map_fd = fd;
|
||||
xsk->xsks_map_fd = fd;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xsk_delete_bpf_maps(struct xsk_socket *xsk)
|
||||
{
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
|
||||
bpf_map_delete_elem(ctx->xsks_map_fd, &ctx->queue_id);
|
||||
close(ctx->xsks_map_fd);
|
||||
bpf_map_delete_elem(xsk->xsks_map_fd, &xsk->queue_id);
|
||||
close(xsk->xsks_map_fd);
|
||||
}
|
||||
|
||||
static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
|
||||
@@ -506,11 +488,10 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
|
||||
__u32 i, *map_ids, num_maps, prog_len = sizeof(struct bpf_prog_info);
|
||||
__u32 map_len = sizeof(struct bpf_map_info);
|
||||
struct bpf_prog_info prog_info = {};
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
struct bpf_map_info map_info;
|
||||
int fd, err;
|
||||
|
||||
err = bpf_obj_get_info_by_fd(ctx->prog_fd, &prog_info, &prog_len);
|
||||
err = bpf_obj_get_info_by_fd(xsk->prog_fd, &prog_info, &prog_len);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -524,11 +505,11 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
|
||||
prog_info.nr_map_ids = num_maps;
|
||||
prog_info.map_ids = (__u64)(unsigned long)map_ids;
|
||||
|
||||
err = bpf_obj_get_info_by_fd(ctx->prog_fd, &prog_info, &prog_len);
|
||||
err = bpf_obj_get_info_by_fd(xsk->prog_fd, &prog_info, &prog_len);
|
||||
if (err)
|
||||
goto out_map_ids;
|
||||
|
||||
ctx->xsks_map_fd = -1;
|
||||
xsk->xsks_map_fd = -1;
|
||||
|
||||
for (i = 0; i < prog_info.nr_map_ids; i++) {
|
||||
fd = bpf_map_get_fd_by_id(map_ids[i]);
|
||||
@@ -542,7 +523,7 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
|
||||
}
|
||||
|
||||
if (!strcmp(map_info.name, "xsks_map")) {
|
||||
ctx->xsks_map_fd = fd;
|
||||
xsk->xsks_map_fd = fd;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -550,7 +531,7 @@ static int xsk_lookup_bpf_maps(struct xsk_socket *xsk)
|
||||
}
|
||||
|
||||
err = 0;
|
||||
if (ctx->xsks_map_fd == -1)
|
||||
if (xsk->xsks_map_fd == -1)
|
||||
err = -ENOENT;
|
||||
|
||||
out_map_ids:
|
||||
@@ -560,46 +541,16 @@ out_map_ids:
|
||||
|
||||
static int xsk_set_bpf_maps(struct xsk_socket *xsk)
|
||||
{
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
|
||||
return bpf_map_update_elem(ctx->xsks_map_fd, &ctx->queue_id,
|
||||
return bpf_map_update_elem(xsk->xsks_map_fd, &xsk->queue_id,
|
||||
&xsk->fd, 0);
|
||||
}
|
||||
|
||||
static int xsk_create_xsk_struct(int ifindex, struct xsk_socket *xsk)
|
||||
static int xsk_setup_xdp_prog(struct xsk_socket *xsk)
|
||||
{
|
||||
char ifname[IFNAMSIZ];
|
||||
struct xsk_ctx *ctx;
|
||||
char *interface;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
interface = if_indextoname(ifindex, &ifname[0]);
|
||||
if (!interface) {
|
||||
free(ctx);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ctx->ifindex = ifindex;
|
||||
memcpy(ctx->ifname, ifname, IFNAMSIZ -1);
|
||||
ctx->ifname[IFNAMSIZ - 1] = 0;
|
||||
|
||||
xsk->ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __xsk_setup_xdp_prog(struct xsk_socket *_xdp,
|
||||
int *xsks_map_fd)
|
||||
{
|
||||
struct xsk_socket *xsk = _xdp;
|
||||
struct xsk_ctx *ctx = xsk->ctx;
|
||||
__u32 prog_id = 0;
|
||||
int err;
|
||||
|
||||
err = bpf_get_link_xdp_id(ctx->ifindex, &prog_id,
|
||||
err = bpf_get_link_xdp_id(xsk->ifindex, &prog_id,
|
||||
xsk->config.xdp_flags);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -611,173 +562,41 @@ static int __xsk_setup_xdp_prog(struct xsk_socket *_xdp,
|
||||
|
||||
err = xsk_load_xdp_prog(xsk);
|
||||
if (err) {
|
||||
goto err_load_xdp_prog;
|
||||
xsk_delete_bpf_maps(xsk);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
ctx->prog_fd = bpf_prog_get_fd_by_id(prog_id);
|
||||
if (ctx->prog_fd < 0)
|
||||
xsk->prog_fd = bpf_prog_get_fd_by_id(prog_id);
|
||||
if (xsk->prog_fd < 0)
|
||||
return -errno;
|
||||
err = xsk_lookup_bpf_maps(xsk);
|
||||
if (err) {
|
||||
close(ctx->prog_fd);
|
||||
close(xsk->prog_fd);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (xsk->rx) {
|
||||
if (xsk->rx)
|
||||
err = xsk_set_bpf_maps(xsk);
|
||||
if (err) {
|
||||
if (!prog_id) {
|
||||
goto err_set_bpf_maps;
|
||||
} else {
|
||||
close(ctx->prog_fd);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
xsk_delete_bpf_maps(xsk);
|
||||
close(xsk->prog_fd);
|
||||
return err;
|
||||
}
|
||||
if (xsks_map_fd)
|
||||
*xsks_map_fd = ctx->xsks_map_fd;
|
||||
|
||||
return 0;
|
||||
|
||||
err_set_bpf_maps:
|
||||
close(ctx->prog_fd);
|
||||
bpf_set_link_xdp_fd(ctx->ifindex, -1, 0);
|
||||
err_load_xdp_prog:
|
||||
xsk_delete_bpf_maps(xsk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct xsk_ctx *xsk_get_ctx(struct xsk_umem *umem, int ifindex,
|
||||
__u32 queue_id)
|
||||
{
|
||||
struct xsk_ctx *ctx;
|
||||
|
||||
if (list_empty(&umem->ctx_list))
|
||||
return NULL;
|
||||
|
||||
list_for_each_entry(ctx, &umem->ctx_list, list) {
|
||||
if (ctx->ifindex == ifindex && ctx->queue_id == queue_id) {
|
||||
ctx->refcount++;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void xsk_put_ctx(struct xsk_ctx *ctx)
|
||||
{
|
||||
struct xsk_umem *umem = ctx->umem;
|
||||
struct xdp_mmap_offsets off;
|
||||
int err;
|
||||
|
||||
if (--ctx->refcount == 0) {
|
||||
err = xsk_get_mmap_offsets(umem->fd, &off);
|
||||
if (!err) {
|
||||
munmap(ctx->fill->ring - off.fr.desc,
|
||||
off.fr.desc + umem->config.fill_size *
|
||||
sizeof(__u64));
|
||||
munmap(ctx->comp->ring - off.cr.desc,
|
||||
off.cr.desc + umem->config.comp_size *
|
||||
sizeof(__u64));
|
||||
}
|
||||
|
||||
list_del(&ctx->list);
|
||||
free(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static struct xsk_ctx *xsk_create_ctx(struct xsk_socket *xsk,
|
||||
struct xsk_umem *umem, int ifindex,
|
||||
const char *ifname, __u32 queue_id,
|
||||
struct xsk_ring_prod *fill,
|
||||
struct xsk_ring_cons *comp)
|
||||
{
|
||||
struct xsk_ctx *ctx;
|
||||
int err;
|
||||
|
||||
ctx = calloc(1, sizeof(*ctx));
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
if (!umem->fill_save) {
|
||||
err = xsk_create_umem_rings(umem, xsk->fd, fill, comp);
|
||||
if (err) {
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
} else if (umem->fill_save != fill || umem->comp_save != comp) {
|
||||
/* Copy over rings to new structs. */
|
||||
memcpy(fill, umem->fill_save, sizeof(*fill));
|
||||
memcpy(comp, umem->comp_save, sizeof(*comp));
|
||||
}
|
||||
|
||||
ctx->ifindex = ifindex;
|
||||
ctx->refcount = 1;
|
||||
ctx->umem = umem;
|
||||
ctx->queue_id = queue_id;
|
||||
memcpy(ctx->ifname, ifname, IFNAMSIZ - 1);
|
||||
ctx->ifname[IFNAMSIZ - 1] = '\0';
|
||||
|
||||
umem->fill_save = NULL;
|
||||
umem->comp_save = NULL;
|
||||
ctx->fill = fill;
|
||||
ctx->comp = comp;
|
||||
list_add(&ctx->list, &umem->ctx_list);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void xsk_destroy_xsk_struct(struct xsk_socket *xsk)
|
||||
{
|
||||
free(xsk->ctx);
|
||||
free(xsk);
|
||||
}
|
||||
|
||||
int xsk_socket__update_xskmap(struct xsk_socket *xsk, int fd)
|
||||
{
|
||||
xsk->ctx->xsks_map_fd = fd;
|
||||
return xsk_set_bpf_maps(xsk);
|
||||
}
|
||||
|
||||
int xsk_setup_xdp_prog(int ifindex, int *xsks_map_fd)
|
||||
{
|
||||
struct xsk_socket *xsk;
|
||||
int res;
|
||||
|
||||
xsk = calloc(1, sizeof(*xsk));
|
||||
if (!xsk)
|
||||
return -ENOMEM;
|
||||
|
||||
res = xsk_create_xsk_struct(ifindex, xsk);
|
||||
if (res) {
|
||||
free(xsk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = __xsk_setup_xdp_prog(xsk, xsks_map_fd);
|
||||
|
||||
xsk_destroy_xsk_struct(xsk);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
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 *usr_config)
|
||||
int xsk_socket__create(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,
|
||||
const struct xsk_socket_config *usr_config)
|
||||
{
|
||||
void *rx_map = NULL, *tx_map = NULL;
|
||||
struct sockaddr_xdp sxdp = {};
|
||||
struct xdp_mmap_offsets off;
|
||||
struct xsk_socket *xsk;
|
||||
struct xsk_ctx *ctx;
|
||||
int err, ifindex;
|
||||
int err;
|
||||
|
||||
if (!umem || !xsk_ptr || !(rx || tx))
|
||||
return -EFAULT;
|
||||
@@ -790,10 +609,10 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
if (err)
|
||||
goto out_xsk_alloc;
|
||||
|
||||
xsk->outstanding_tx = 0;
|
||||
ifindex = if_nametoindex(ifname);
|
||||
if (!ifindex) {
|
||||
err = -errno;
|
||||
if (umem->refcount &&
|
||||
!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
|
||||
pr_warn("Error: shared umems not supported by libbpf supplied XDP program.\n");
|
||||
err = -EBUSY;
|
||||
goto out_xsk_alloc;
|
||||
}
|
||||
|
||||
@@ -807,21 +626,16 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
xsk->fd = umem->fd;
|
||||
}
|
||||
|
||||
ctx = xsk_get_ctx(umem, ifindex, queue_id);
|
||||
if (!ctx) {
|
||||
if (!fill || !comp) {
|
||||
err = -EFAULT;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
ctx = xsk_create_ctx(xsk, umem, ifindex, ifname, queue_id,
|
||||
fill, comp);
|
||||
if (!ctx) {
|
||||
err = -ENOMEM;
|
||||
goto out_socket;
|
||||
}
|
||||
xsk->outstanding_tx = 0;
|
||||
xsk->queue_id = queue_id;
|
||||
xsk->umem = umem;
|
||||
xsk->ifindex = if_nametoindex(ifname);
|
||||
if (!xsk->ifindex) {
|
||||
err = -errno;
|
||||
goto out_socket;
|
||||
}
|
||||
xsk->ctx = ctx;
|
||||
memcpy(xsk->ifname, ifname, IFNAMSIZ - 1);
|
||||
xsk->ifname[IFNAMSIZ - 1] = '\0';
|
||||
|
||||
if (rx) {
|
||||
err = setsockopt(xsk->fd, SOL_XDP, XDP_RX_RING,
|
||||
@@ -829,7 +643,7 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
sizeof(xsk->config.rx_size));
|
||||
if (err) {
|
||||
err = -errno;
|
||||
goto out_put_ctx;
|
||||
goto out_socket;
|
||||
}
|
||||
}
|
||||
if (tx) {
|
||||
@@ -838,14 +652,14 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
sizeof(xsk->config.tx_size));
|
||||
if (err) {
|
||||
err = -errno;
|
||||
goto out_put_ctx;
|
||||
goto out_socket;
|
||||
}
|
||||
}
|
||||
|
||||
err = xsk_get_mmap_offsets(xsk->fd, &off);
|
||||
if (err) {
|
||||
err = -errno;
|
||||
goto out_put_ctx;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
if (rx) {
|
||||
@@ -855,7 +669,7 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
xsk->fd, XDP_PGOFF_RX_RING);
|
||||
if (rx_map == MAP_FAILED) {
|
||||
err = -errno;
|
||||
goto out_put_ctx;
|
||||
goto out_socket;
|
||||
}
|
||||
|
||||
rx->mask = xsk->config.rx_size - 1;
|
||||
@@ -894,10 +708,10 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
xsk->tx = tx;
|
||||
|
||||
sxdp.sxdp_family = PF_XDP;
|
||||
sxdp.sxdp_ifindex = ctx->ifindex;
|
||||
sxdp.sxdp_queue_id = ctx->queue_id;
|
||||
sxdp.sxdp_ifindex = xsk->ifindex;
|
||||
sxdp.sxdp_queue_id = xsk->queue_id;
|
||||
if (umem->refcount > 1) {
|
||||
sxdp.sxdp_flags |= XDP_SHARED_UMEM;
|
||||
sxdp.sxdp_flags = XDP_SHARED_UMEM;
|
||||
sxdp.sxdp_shared_umem_fd = umem->fd;
|
||||
} else {
|
||||
sxdp.sxdp_flags = xsk->config.bind_flags;
|
||||
@@ -909,10 +723,10 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
|
||||
goto out_mmap_tx;
|
||||
}
|
||||
|
||||
ctx->prog_fd = -1;
|
||||
xsk->prog_fd = -1;
|
||||
|
||||
if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
|
||||
err = __xsk_setup_xdp_prog(xsk, NULL);
|
||||
err = xsk_setup_xdp_prog(xsk);
|
||||
if (err)
|
||||
goto out_mmap_tx;
|
||||
}
|
||||
@@ -928,8 +742,6 @@ out_mmap_rx:
|
||||
if (rx)
|
||||
munmap(rx_map, off.rx.desc +
|
||||
xsk->config.rx_size * sizeof(struct xdp_desc));
|
||||
out_put_ctx:
|
||||
xsk_put_ctx(ctx);
|
||||
out_socket:
|
||||
if (--umem->refcount)
|
||||
close(xsk->fd);
|
||||
@@ -938,24 +750,25 @@ out_xsk_alloc:
|
||||
return err;
|
||||
}
|
||||
|
||||
int xsk_socket__create(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,
|
||||
const struct xsk_socket_config *usr_config)
|
||||
{
|
||||
return xsk_socket__create_shared(xsk_ptr, ifname, queue_id, umem,
|
||||
rx, tx, umem->fill_save,
|
||||
umem->comp_save, usr_config);
|
||||
}
|
||||
|
||||
int xsk_umem__delete(struct xsk_umem *umem)
|
||||
{
|
||||
struct xdp_mmap_offsets off;
|
||||
int err;
|
||||
|
||||
if (!umem)
|
||||
return 0;
|
||||
|
||||
if (umem->refcount)
|
||||
return -EBUSY;
|
||||
|
||||
err = xsk_get_mmap_offsets(umem->fd, &off);
|
||||
if (!err) {
|
||||
munmap(umem->fill->ring - off.fr.desc,
|
||||
off.fr.desc + umem->config.fill_size * sizeof(__u64));
|
||||
munmap(umem->comp->ring - off.cr.desc,
|
||||
off.cr.desc + umem->config.comp_size * sizeof(__u64));
|
||||
}
|
||||
|
||||
close(umem->fd);
|
||||
free(umem);
|
||||
|
||||
@@ -966,18 +779,14 @@ void xsk_socket__delete(struct xsk_socket *xsk)
|
||||
{
|
||||
size_t desc_sz = sizeof(struct xdp_desc);
|
||||
struct xdp_mmap_offsets off;
|
||||
struct xsk_umem *umem;
|
||||
struct xsk_ctx *ctx;
|
||||
int err;
|
||||
|
||||
if (!xsk)
|
||||
return;
|
||||
|
||||
ctx = xsk->ctx;
|
||||
umem = ctx->umem;
|
||||
if (ctx->prog_fd != -1) {
|
||||
if (xsk->prog_fd != -1) {
|
||||
xsk_delete_bpf_maps(xsk);
|
||||
close(ctx->prog_fd);
|
||||
close(xsk->prog_fd);
|
||||
}
|
||||
|
||||
err = xsk_get_mmap_offsets(xsk->fd, &off);
|
||||
@@ -990,15 +799,14 @@ void xsk_socket__delete(struct xsk_socket *xsk)
|
||||
munmap(xsk->tx->ring - off.tx.desc,
|
||||
off.tx.desc + xsk->config.tx_size * desc_sz);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
xsk_put_ctx(ctx);
|
||||
|
||||
umem->refcount--;
|
||||
xsk->umem->refcount--;
|
||||
/* Do not close an fd that also has an associated umem connected
|
||||
* to it.
|
||||
*/
|
||||
if (xsk->fd != umem->fd)
|
||||
if (xsk->fd != xsk->umem->fd)
|
||||
close(xsk->fd);
|
||||
free(xsk);
|
||||
}
|
||||
|
||||
31
src/xsk.h
31
src/xsk.h
@@ -113,7 +113,8 @@ static inline __u32 xsk_cons_nb_avail(struct xsk_ring_cons *r, __u32 nb)
|
||||
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;
|
||||
@@ -124,7 +125,7 @@ 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.
|
||||
@@ -134,9 +135,10 @@ static inline void xsk_ring_prod__submit(struct xsk_ring_prod *prod, __u32 nb)
|
||||
*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
|
||||
@@ -151,12 +153,7 @@ 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.
|
||||
@@ -204,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)
|
||||
|
||||
@@ -242,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);
|
||||
|
||||
@@ -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,10 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source $(cd $(dirname $0) && pwd)/helpers.sh
|
||||
|
||||
travis_fold start prepare_selftests "Building selftests"
|
||||
set -euxo pipefail
|
||||
|
||||
LLVM_VER=12
|
||||
LIBBPF_PATH="${REPO_ROOT}"
|
||||
@@ -37,5 +33,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)
|
||||
@@ -16,13 +14,11 @@ 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
|
||||
if wget ${SNAPSHOT_URL} ; then
|
||||
tar xf bpf-next-${LINUX_SHA}.tar.gz
|
||||
mv bpf-next-${LINUX_SHA} $(basename ${REPO_PATH})
|
||||
else
|
||||
# but fallback to git fetch approach if that fails
|
||||
@@ -39,6 +35,4 @@ if [ ! -d "${REPO_PATH}" ]; then
|
||||
fi
|
||||
git reset --hard ${LINUX_SHA}
|
||||
fi
|
||||
|
||||
travis_fold end pull_kernel_srcs
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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
|
||||
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-4.9.0.zst https://libbpf-vmtest.s3-us-west-1.amazonaws.com/x86_64/vmlinux-4.9.0.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
|
||||
|
||||
@@ -3,15 +3,19 @@ align # verifier output format changed
|
||||
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
|
||||
|
||||
# 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
|
||||
btf_map_in_map # inner map leak fixed in 5.8
|
||||
btf_skc_cls_ingress # v5.10+ functionality
|
||||
|
||||
cg_storage_multi # v5.9+ functionality
|
||||
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
|
||||
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
|
||||
@@ -20,25 +24,14 @@ fexit_test # bpf_prog_test_tracing missing
|
||||
flow_dissector # bpf_link-based flow dissector is in 5.8+
|
||||
flow_dissector_reattach
|
||||
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
|
||||
link_pinning # bpf_link is missing
|
||||
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+
|
||||
ringbuf # BPF_MAP_TYPE_RINGBUF is supported in 5.8+
|
||||
|
||||
# bug in verifier w/ tracking references
|
||||
@@ -46,28 +39,16 @@ 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
|
||||
skb_helpers # helpers added in 5.8+
|
||||
sk_storage_tracing # missing bpf_sk_storage_get() helper
|
||||
snprintf_btf # v5.10+
|
||||
sock_fields # v5.10+
|
||||
sockmap_basic # uses new socket fields, 5.8+
|
||||
sockmap_listen # no listen socket supportin SOCKMAP
|
||||
sockopt_sk
|
||||
sk_lookup # v5.9+
|
||||
skb_ctx # ctx_{size, }_{in, out} in BPF_PROG_TEST_RUN is missing
|
||||
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+
|
||||
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+
|
||||
udp_limit # no cgroup/sock_release BPF program type (5.9+)
|
||||
varlen # verifier bug fixed in later kernels
|
||||
vmlinux # hrtimer_nanosleep() signature changed incompatibly
|
||||
@@ -78,6 +59,7 @@ 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,7 @@
|
||||
# TEMPORARY
|
||||
# TEMPORARILY DISABLED
|
||||
send_signal # flaky
|
||||
test_lsm # semi-working
|
||||
sk_assign # needs better setup in Travis CI
|
||||
sk_lookup
|
||||
core_reloc # temporary test breakage
|
||||
bpf_verif_scale # clang regression
|
||||
|
||||
@@ -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,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 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
printf "all:\n\ttouch bpf_testmod.ko\n\nclean:\n" > bpf_testmod/Makefile
|
||||
@@ -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,7 +401,7 @@ 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
|
||||
@@ -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,27 @@
|
||||
#!/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"
|
||||
echo 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"
|
||||
echo TEST_PROGS-NO_ALU32
|
||||
./test_progs-no_alu32 ${BLACKLIST:+-b$BLACKLIST} ${WHITELIST:+-t$WHITELIST}
|
||||
travis_fold end test_progs-no_alu32
|
||||
}
|
||||
|
||||
test_maps() {
|
||||
travis_fold start test_maps "Testing test_maps"
|
||||
echo TEST_MAPS
|
||||
./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 +38,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 -
|
||||
echo "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic main" | sudo tee -a /etc/apt/sources.list
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install clang-12 lld-12 llvm-12
|
||||
sudo apt-get -y install python-docutils # for rst2man
|
||||
|
||||
travis_fold end install_clang
|
||||
|
||||
# Build selftests (and latest kernel, if necessary)
|
||||
KERNEL="${KERNEL}" ${VMTEST_ROOT}/prepare_selftests.sh travis-ci/vmtest/bpf-next
|
||||
|
||||
102121
travis-ci/vmtest/vmlinux.h
102121
travis-ci/vmtest/vmlinux.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user