Skip to content
48 changes: 48 additions & 0 deletions advanced02-BTF/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)

XDP_BTF_TARGETS := xdp_prog_kern
XDP_BTF_OBJ = ${XDP_BTF_TARGETS:=.o}

_all: llvm-check pahole-check $(XDP_BTF_OBJ) xdp_loader

COPY_LOADER := xdp_loader

COMMON_DIR = ../common/
include $(COMMON_DIR)/common.mk

PAHOLE ?= pahole

.PHONY: $(PAHOLE)

TEST_PAHOLE := "$(PAHOLE) --help 2>&1 | grep BTF"

pahole-check: $(PAHOLE)
@for TOOL in $^ ; do \
if [ ! $$(command -v $${TOOL} 2>/dev/null) ]; then \
echo "*** ERROR: Cannot find tool $${TOOL}" ;\
exit 1; \
else true; fi; \
done
@if [ ! $(TEST_PAHOLE) > /dev/null 2>&1 ]; then \
echo "Tool pahole too old, missing BTF support" ;\
exit 1; \
else \
echo "Using pahole to encode BTF info in ELF-object"; \
fi

#LLC_FLAGS += -mcpu=probe
LLC_FLAGS += -mattr=dwarfris

$(XDP_BTF_OBJ): %.o: %.c Makefile $(COMMON_MK)
$(CLANG) -S \
-target bpf \
-D __BPF_TRACING__ \
$(CFLAGS) \
-Wall \
-Wno-unused-value \
-Wno-pointer-sign \
-Wno-compare-distinct-pointer-types \
-Werror \
-O2 -emit-llvm -c -g $<
$(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@ ${@:.o=.ll}
$(PAHOLE) -V --btf_encode $@ > ${@:.o=.pahole-btf-info}
17 changes: 17 additions & 0 deletions advanced02-BTF/common_kern_user.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* This common_kern_user.h is used by kernel side BPF-progs and
* userspace programs, for sharing common struct's and DEFINEs.
*/
#ifndef __COMMON_KERN_USER_H
#define __COMMON_KERN_USER_H

/* This is the data record stored in the map */
struct datarec {
__u64 rx_packets;
__u64 rx_bytes;
};

#ifndef XDP_ACTION_MAX
#define XDP_ACTION_MAX (XDP_REDIRECT + 1)
#endif

#endif /* __COMMON_KERN_USER_H */
59 changes: 59 additions & 0 deletions advanced02-BTF/xdp_prog_kern.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/bpf.h>
#include "bpf_helpers.h"

#include "common_kern_user.h" /* defines: struct datarec; */

#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 = { }

struct bpf_map_def SEC("maps") xdp_stats_map = {
.type = BPF_MAP_TYPE_PERCPU_ARRAY,
.key_size = sizeof(__u32),
.value_size = sizeof(struct datarec),
.max_entries = XDP_ACTION_MAX,
};
_BPF_ANNOTATE_KV_PAIR(xdp_stats_map, int, struct datarec);

static __always_inline
__u32 record_xdp_stats_action(struct xdp_md *ctx, __u32 action)
{
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;

if (action >= XDP_ACTION_MAX)
return XDP_ABORTED;

/* Lookup in kernel BPF-side return pointer to actual data record */
struct datarec *rec = bpf_map_lookup_elem(&xdp_stats_map, &action);
if (!rec)
return XDP_ABORTED;

/* Calculate packet length */
__u64 bytes = data_end - data;

/* BPF_MAP_TYPE_PERCPU_ARRAY returns a data record specific to current
* CPU and XDP hooks runs under Softirq, which makes it safe to update
* without atomic operations.
*/
rec->rx_packets++;
rec->rx_bytes += bytes;

return action;
}

SEC("xdp_pass")
int xdp_pass_func(struct xdp_md *ctx)
{
__u32 action = XDP_PASS; /* XDP_PASS = 2 */

return record_xdp_stats_action(ctx, action);
}

char _license[] SEC("license") = "GPL";
9 changes: 9 additions & 0 deletions headers/bpf_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ struct bpf_map_def {
unsigned int inner_map_idx;
};

#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 = { }

static int (*bpf_skb_load_bytes)(void *ctx, int off, void *to, int len) =
(void *) BPF_FUNC_skb_load_bytes;
static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from, int len, int flags) =
Expand Down