Skip to content

Commit

Permalink
Use bpftool instead of iproute2 to load eBPF and XDP maps.
Browse files Browse the repository at this point in the history
Signed-off-by: fruffy <fruffy@nyu.edu>
  • Loading branch information
fruffy committed Dec 22, 2024
1 parent a250fbd commit eb1ef3d
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 146 deletions.
8 changes: 4 additions & 4 deletions backends/ebpf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ if(NOT APPLE)
set(FETCHCONTENT_QUIET OFF)
fetchcontent_declare(
bpfrepo
URL https://github.com/libbpf/libbpf/archive/refs/tags/v1.4.1.tar.gz
URL_HASH SHA256=cc01a3a05d25e5978c20be7656f14eb8b6fcb120bb1c7e8041e497814fc273cb
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/runtime/contrib/libbpf
URL https://github.com/libbpf/bpftool/releases/download/v7.5.0/bpftool-libbpf-v7.5.0-sources.tar.gz
# URL_HASH SHA256=cc01a3a05d25e5978c20be7656f14eb8b6fcb120bb1c7e8041e497814fc273cb
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/runtime/contrib/bpftool
USES_TERMINAL_DOWNLOAD TRUE
GIT_PROGRESS TRUE
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
fetchcontent_makeavailable(bpfrepo)
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})
# Check if we have already built the libbpf library.
find_library(LIBBPF NAMES bpf HINTS "${CMAKE_CURRENT_SOURCE_DIR}/runtime/usr/lib64/")
find_library(LIBBPF NAMES bpf HINTS "${CMAKE_CURRENT_SOURCE_DIR}/runtime/install/libbpf/")
if (NOT LIBBPF)
message("Building libbpf...")
execute_process(
Expand Down
27 changes: 15 additions & 12 deletions backends/ebpf/build_libbpf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
""" This programs builds a libbpf static library and places it in the runtime
""" This programs builds a bpftool binary and the libbpf static library and places it in the runtime
folder. The library and its headers are required by the kernel target.
"""

Expand All @@ -31,21 +31,24 @@ def main() -> int:
level=logging.WARN,
filemode="w",
)
libbpf_dir = FILE_DIR.joinpath("runtime/contrib/libbpf")
libbpf_src_dir = libbpf_dir.joinpath("src")
libbpf_build_dir = libbpf_src_dir.joinpath("build")
libbpf_target_dir = FILE_DIR.joinpath("runtime")
# Create the libbpf build directory
testutils.check_and_create_dir(libbpf_build_dir)
# Build libbpf
mk_cmd = f"make -C {libbpf_src_dir} install "
bpftool_dir = FILE_DIR.joinpath("runtime/contrib/bpftool")
bpftool_src_dir = bpftool_dir.joinpath("src")
bpftool_build_dir = bpftool_src_dir.joinpath("build")
bpftool_target_dir = FILE_DIR.joinpath("runtime/install/")
bpftool_target_dir.mkdir(parents=True, exist_ok=True)
# Create the bpftool build directory
testutils.check_and_create_dir(bpftool_build_dir)
# Build bpftool
mk_cmd = f"make -C {bpftool_src_dir} install "
mk_cmd += f"OUTPUT={bpftool_target_dir}/ "
mk_cmd += "BUILD_STATIC_ONLY=y "
mk_cmd += f"OBJDIR={libbpf_build_dir} "
mk_cmd += f"DESTDIR={libbpf_target_dir} "
mk_cmd += f"OBJDIR={bpftool_build_dir} "
mk_cmd += f"DESTDIR={bpftool_target_dir} "
mk_cmd += "EXTRA_CFLAGS=-fPIE"
print(mk_cmd)
result = testutils.exec_process(args=mk_cmd)
if result.returncode != testutils.SUCCESS:
testutils.log.error("Could not build libbpf")
testutils.log.error("Could not build bpftool")
return result.returncode


Expand Down
4 changes: 2 additions & 2 deletions backends/ebpf/run-ebpf-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ def __init__(self):
self.replace = False # Replace previous outputs.
self.target = "test" # The name of the target compiler.
# Actual location of the test framework.
self.testdir = str(FILE_DIR)
self.testdir = FILE_DIR
# The location of the eBPF runtime, some targets may overwrite this.
self.runtimedir = str(FILE_DIR.joinpath("runtime"))
self.runtimedir = FILE_DIR.joinpath("runtime")
self.extern = "" # Path to C file with extern definition.


Expand Down
1 change: 1 addition & 0 deletions backends/ebpf/runtime/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
install
1 change: 1 addition & 0 deletions backends/ebpf/runtime/contrib/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
libbpf
bpftool
76 changes: 3 additions & 73 deletions backends/ebpf/runtime/ebpf_kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,92 +61,23 @@ limitations under the License.
// This file contains the definitions of all the kernel bpf essentials
#include <bpf/bpf_helpers.h>

/// A helper structure used by an eBPF C program
/// to describe map attributes for the elf_bpf loader
/// FIXME: We only need this because we are loading with iproute2
struct bpf_elf_map {
__u32 type;
__u32 size_key;
__u32 size_value;
__u32 max_elem;
__u32 flags;
__u32 id;
__u32 pinning;
__u32 inner_id;
__u32 inner_idx;
};

/// Simple descriptor which replaces the kernel sk_buff structure.
#define SK_BUFF struct __sk_buff

/// From iproute2, annotate table with BTF which allows to read types at runtime.
#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
struct ____btf_map_##name { \
type_key key; \
type_val value; \
}; \
struct ____btf_map_##name \
__attribute__ ((section(".maps." #name), used)) \
____btf_map_##name = {};

#define REGISTER_START()
#ifndef BTF
/// Note: pinning exports the table name globally, do not remove.
#define REGISTER_TABLE(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
};
#define REGISTER_TABLE_INNER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, ID, INNER_IDX) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
.id = ID, \
.inner_idx = INNER_IDX, \
};
#define REGISTER_TABLE_OUTER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, INNER_ID, INNER_NAME) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = 0, \
.inner_id = INNER_ID, \
};
#define REGISTER_TABLE_FLAGS(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, FLAGS) \
struct bpf_elf_map SEC("maps") NAME = { \
.type = TYPE, \
.size_key = sizeof(KEY_TYPE), \
.size_value = sizeof(VALUE_TYPE), \
.max_elem = MAX_ENTRIES, \
.pinning = 2, \
.flags = FLAGS, \
};
#else
#define REGISTER_TABLE(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES) \
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
} NAME SEC(".maps");
#define REGISTER_TABLE_FLAGS(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, FLAGS) \
struct { \
__uint(type, TYPE); \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__uint(map_flags, FLAGS); \
} NAME SEC(".maps");
#define REGISTER_TABLE_INNER(NAME, TYPE, KEY_TYPE, VALUE_TYPE, MAX_ENTRIES, ID, INNER_IDX) \
Expand All @@ -162,18 +93,17 @@ struct { \
KEY_TYPE *key; \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
__array(values, struct INNER_NAME); \
} NAME SEC(".maps");
} NAME SEC(".maps") = { \
.values = { &INNER_NAME } \
};
#define REGISTER_TABLE_NO_KEY_TYPE(NAME, TYPE, KEY_SIZE, VALUE_TYPE, MAX_ENTRIES) \
struct { \
__uint(type, TYPE); \
__uint(key_size, KEY_SIZE); \
VALUE_TYPE *value; \
__uint(max_entries, MAX_ENTRIES); \
__uint(pinning, LIBBPF_PIN_BY_NAME); \
} NAME SEC(".maps");
#endif
#define REGISTER_END()

#define BPF_MAP_LOOKUP_ELEM(table, key) \
Expand Down
2 changes: 1 addition & 1 deletion backends/ebpf/runtime/kernel.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
# Argument for the CLANG compiler
LLC ?= llc
CLANG ?= clang
override INCLUDES+= -I$(ROOT_DIR) -I$(ROOT_DIR)usr/include/ -I$(ROOT_DIR)contrib/libbpf/include/uapi/
override INCLUDES+= -I$(ROOT_DIR) -I$(ROOT_DIR)usr/include/ -I$(ROOT_DIR)install/libbpf/include/
override LIBS+=
# Optimization flags to save space
override CFLAGS+= -O2 -g -c -D__KERNEL__ -D__ASM_SYSREG_H \
Expand Down
9 changes: 0 additions & 9 deletions backends/ebpf/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ void KernelSamplesTarget::emitTableDecl(Util::SourceCodeBuilder *builder, cstrin
flags);
}
builder->newline();
annotateTableWithBTF(builder, tblName, keyType, valueType);
}

void KernelSamplesTarget::emitTableDeclSpinlock(Util::SourceCodeBuilder *builder, cstring tblName,
Expand Down Expand Up @@ -131,14 +130,12 @@ void KernelSamplesTarget::emitMapInMapDecl(Util::SourceCodeBuilder *builder, cst
builder->appendFormat(registerInnerTable, innerName, kind, innerKeyType, innerValueType,
innerSize, innerMapIndex, innerMapIndex);
builder->newline();
annotateTableWithBTF(builder, innerName, innerKeyType, innerValueType);

kind = getBPFMapType(outerTableKind);
cstring keyType = outerTableKind == TableArray ? "__u32"_cs : outerKeyType;
builder->appendFormat(registerOuterTable, outerName, kind, keyType, "__u32", outerSize,
innerMapIndex, innerName);
builder->newline();
annotateTableWithBTF(builder, outerName, keyType, "__u32"_cs);
}

void KernelSamplesTarget::emitLicense(Util::SourceCodeBuilder *builder, cstring license) const {
Expand Down Expand Up @@ -202,12 +199,6 @@ void KernelSamplesTarget::emitTraceMessage(Util::SourceCodeBuilder *builder, con
builder->newline();
}

void KernelSamplesTarget::annotateTableWithBTF(Util::SourceCodeBuilder *builder, cstring name,
cstring keyType, cstring valueType) const {
builder->appendFormat("BPF_ANNOTATE_KV_PAIR(%v, %v, %v)", name, keyType, valueType);
builder->newline();
}

//////////////////////////////////////////////////////////////
void XdpTarget::emitResizeBuffer(Util::SourceCodeBuilder *builder, cstring buffer,
cstring offsetVar) const {
Expand Down
3 changes: 0 additions & 3 deletions backends/ebpf/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,6 @@ class KernelSamplesTarget : public Target {
cstring sysMapPath() const override { return "/sys/fs/bpf/tc/globals"_cs; }

cstring packetDescriptorType() const override { return "struct __sk_buff"_cs; }

void annotateTableWithBTF(Util::SourceCodeBuilder *builder, cstring name, cstring keyType,
cstring valueType) const;
};

class P4TCTarget : public KernelSamplesTarget {
Expand Down
6 changes: 3 additions & 3 deletions backends/ebpf/targets/ebpfenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def ns_proc_append(self, proc: subprocess.Popen, cmd: str) -> int:
def ns_proc_close(self, proc: subprocess.Popen, **extra_args: Any) -> int:
"""Close and actually run the process in the namespace. Returns the
exit code."""
testutils.log.info("Executing command: %s", proc)
testutils.log.info("Executing command: %s", proc.args)
result = testutils.run_process(proc, timeout=testutils.TIMEOUT, **extra_args)
if result.returncode != testutils.SUCCESS:
testutils.log.error(
Expand All @@ -109,7 +109,7 @@ def _configure_bridge(self, br_name: str) -> int:
avoid ICMPv6 spam."""
# We do not care about failures here
self.ns_exec(f"ip link set dev {br_name} up")
self.ns_exec(f"ip link set dev {br_name} mtu 9000")
self.ns_exec(f"ip link set dev {br_name} mtu 1500")
# Prevent the broadcasting of ipv6 link discovery messages
self.ns_exec("sysctl -w net.ipv6.conf.all.disable_ipv6=1")
self.ns_exec("sysctl -w net.ipv6.conf.default.disable_ipv6=1")
Expand All @@ -130,7 +130,7 @@ def _configure_bridge_port(self, port_name: str) -> int:
result = self.ns_exec(cmd)
if result != testutils.SUCCESS:
return result
cmd = f"ip link set dev {port_name} mtu 9000"
cmd = f"ip link set dev {port_name} mtu 1500"
return self.ns_exec(cmd)

def attach_interfaces(self, num_ifaces: int) -> int:
Expand Down
Loading

0 comments on commit eb1ef3d

Please sign in to comment.