diff options
author | 2022-12-16 17:24:48 +0530 | |
---|---|---|
committer | 2022-12-19 21:14:08 +0530 | |
commit | 3409364da8fa46eae8ca22a579e219dc74958079 (patch) | |
tree | 83cb1cc72c3c59465d7d3be0f793a896c0ad7a21 /src/bpfswitch/ksrc | |
parent | 34147ac299351c44d4f7d135892457fba38a132b (diff) |
ebpf: This patch adds ebpf-baremetal test support
Remove object files and binaries
Suggestions in systems/Readme.
Add license headers.
Signed-off-by: Sridhar K. N. Rao <srao@linuxfoundation.org>
Change-Id: I5fd481e3ed3eb51e6b8091cbf6d1ec8e3b00cbf0
Diffstat (limited to 'src/bpfswitch/ksrc')
-rw-r--r-- | src/bpfswitch/ksrc/Makefile | 59 | ||||
-rw-r--r-- | src/bpfswitch/ksrc/include/asm_goto_workaround.h | 28 | ||||
-rw-r--r-- | src/bpfswitch/ksrc/xdp_dummy.c | 21 | ||||
-rw-r--r-- | src/bpfswitch/ksrc/xdp_l2fwd.c | 103 |
4 files changed, 211 insertions, 0 deletions
diff --git a/src/bpfswitch/ksrc/Makefile b/src/bpfswitch/ksrc/Makefile new file mode 100644 index 00000000..64bec2f8 --- /dev/null +++ b/src/bpfswitch/ksrc/Makefile @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0 + +include ../config.mk + +ifneq (,$(BUILDDIR)) +OBJDIR = $(BUILDDIR)/ksrc/obj/ +else +OBJDIR = obj/ +endif + +MODS += $(OBJDIR)xdp_l2fwd.o +MODS += $(OBJDIR)xdp_dummy.o + +VPATH := . + +# rule is based on samples/bpf/Makefile +DEFS = -D__KERNEL__ -D__BPF_TRACING__ -D__TARGET_ARCH_x86 $(EXTRA_DEFS) + +CFLAGS += -Wno-unused-value -Wno-pointer-sign +CFLAGS += -Wno-compare-distinct-pointer-types +CFLAGS += -Wno-gnu-variable-sized-type-not-at-end +CFLAGS += -Wno-address-of-packed-member +CFLAGS += -Wno-tautological-compare +CFLAGS += -Wno-unknown-warning-option +CFLAGS += -fno-stack-protector + +INCLUDES = -I../include +INCLUDES += -I$(KSRC)/arch/x86/include +INCLUDES += -I$(KBLD)/arch/x86/include/generated +INCLUDES += -I$(KBLD)/include +INCLUDES += -I$(KSRC)/include +INCLUDES += -I$(KSRC)/arch/x86/include/uapi +INCLUDES += -I$(KBLD)/arch/x86/include/generated/uapi +INCLUDES += -I$(KSRC)/include/uapi +INCLUDES += -I$(KBLD)/include/generated/uapi + +SINCLUDES = -include $(KSRC)/include/linux/kconfig.h +SINCLUDES += -include include/asm_goto_workaround.h + +# this is to find stdarg.h. Ubuntu has this under x86_64-linux-gnu +# and Fedora is under x86_64-redhat-linux. Let's try 'find'. +GCCVER=$(shell gcc -v 2>&1 | awk '{if ($$0 ~ /gcc version/) {ver=split($$3,n,"."); print n[1]}}') +GCC_INC=$(shell find /usr/lib/gcc/x86_64-*linux*/$(GCCVER) -name include) +NOSTDINC_FLAGS = -nostdinc -isystem $(GCC_INC) + +all: build $(MODS) + +build: + @mkdir -p $(OBJDIR) + +$(OBJDIR)%.o: %.c + $(QUIET_CLANG)$(CLANG) $(NOSTDINC_FLAGS) $(INCLUDES) \ + $(SINCLUDES) $(DEFS) $(CFLAGS) \ + -O2 -emit-llvm $(CLANG_FLAGS) -c $< -o $@.cl + $(QUIET_LLC)$(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@ $@.cl + @rm $@.cl + +clean: + @rm -rf $(OBJDIR) diff --git a/src/bpfswitch/ksrc/include/asm_goto_workaround.h b/src/bpfswitch/ksrc/include/asm_goto_workaround.h new file mode 100644 index 00000000..7048bb35 --- /dev/null +++ b/src/bpfswitch/ksrc/include/asm_goto_workaround.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2019 Facebook */ +#ifndef __ASM_GOTO_WORKAROUND_H +#define __ASM_GOTO_WORKAROUND_H + +/* + * This will bring in asm_volatile_goto and asm_inline macro definitions + * if enabled by compiler and config options. + */ +#include <linux/types.h> + +#ifdef asm_volatile_goto +#undef asm_volatile_goto +#define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto") +#endif + +/* + * asm_inline is defined as asm __inline in "include/linux/compiler_types.h" + * if supported by the kernel's CC (i.e CONFIG_CC_HAS_ASM_INLINE) which is not + * supported by CLANG. + */ +#ifdef asm_inline +#undef asm_inline +#define asm_inline asm +#endif + +#define volatile(x...) volatile("") +#endif diff --git a/src/bpfswitch/ksrc/xdp_dummy.c b/src/bpfswitch/ksrc/xdp_dummy.c new file mode 100644 index 00000000..d60c1c07 --- /dev/null +++ b/src/bpfswitch/ksrc/xdp_dummy.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Dummy XDP program + * + * David Ahern <dsahern@gmail.com> + */ +#define KBUILD_MODNAME "xdp_dummy" +#include <uapi/linux/bpf.h> +#include <linux/version.h> +#include <bpf/bpf_helpers.h> + +SEC("xdp_dummy") +int xdp_dummy_prog(struct xdp_md *ctx) +{ + //bpf_debug("ingress: device %u queue %u\n", + // ctx->ingress_ifindex, ctx->rx_queue_index); + + return XDP_PASS; +} + +char _license[] SEC("license") = "GPL"; +int _version SEC("version") = LINUX_VERSION_CODE; diff --git a/src/bpfswitch/ksrc/xdp_l2fwd.c b/src/bpfswitch/ksrc/xdp_l2fwd.c new file mode 100644 index 00000000..750b580d --- /dev/null +++ b/src/bpfswitch/ksrc/xdp_l2fwd.c @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Example of L2 forwarding via XDP. FDB is a <vlan,dmac> hash table + * returning device index to redirect packet. + * + * Copyright (c) 2019-2020 David Ahern <dsahern@gmail.com> + * The code is modified to use 2 mac addresses as key instead of + * mac address and vlan id as key + * + */ +#define KBUILD_MODNAME "xdp_l2fwd" +#include <uapi/linux/bpf.h> +#include <linux/if_ether.h> +#include <linux/if_packet.h> +#include <linux/if_vlan.h> +#include <linux/version.h> +#include <bpf/bpf_helpers.h> +#include <bpf/bpf_endian.h> + +#include "xdp_fdb.h" + +/* For TX-traffic redirect requires net_device ifindex to be in this devmap */ +struct bpf_map_def SEC("maps") xdp_fwd_ports = { + .type = BPF_MAP_TYPE_DEVMAP_HASH, + .key_size = sizeof(u32), + .value_size = sizeof(struct bpf_devmap_val), + .max_entries = 512, +}; + +/* <vlan,dmac> to device index map */ +struct bpf_map_def SEC("maps") fdb_map = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(struct fdb_key), + .value_size = sizeof(u32), + .max_entries = 512, +}; + +SEC("xdp_l2fwd") +int xdp_l2fwd_prog(struct xdp_md *ctx) +{ + void *data_end = (void *)(long)ctx->data_end; + void *data = (void *)(long)ctx->data; + struct bpf_devmap_val *entry; + struct vlan_hdr *vhdr = NULL; + struct ethhdr *eth; + struct fdb_key key; + u8 smac[ETH_ALEN]; + u16 h_proto = 0; + void *nh; + int rc; + + /* data in context points to ethernet header */ + eth = data; + + /* set pointer to header after ethernet header */ + nh = data + sizeof(*eth); + if (nh > data_end) + return XDP_DROP; // malformed packet + + __builtin_memset(&key, 0, sizeof(key)); + __builtin_memcpy(key.dmac, eth->h_dest, ETH_ALEN); + __builtin_memcpy(key.smac, eth->h_source, ETH_ALEN); + + if (eth->h_proto == htons(ETH_P_8021Q)) { + vhdr = nh; + if (vhdr + 1 > data_end) + return XDP_DROP; // malformed packet + + //key.vlan = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + } + + entry = bpf_map_lookup_elem(&fdb_map, &key); + if (!entry || entry->ifindex == 0) + return XDP_PASS; + + /* Verify redirect index exists in port map */ + if (!bpf_map_lookup_elem(&xdp_fwd_ports, &entry->ifindex)) + return XDP_PASS; + + if (vhdr) { + /* remove VLAN header before hand off to VM */ + h_proto = vhdr->h_vlan_encapsulated_proto; + __builtin_memcpy(smac, eth->h_source, ETH_ALEN); + + if (bpf_xdp_adjust_head(ctx, sizeof(*vhdr))) + return XDP_PASS; + + /* reset data pointers after adjust */ + data = (void *)(long)ctx->data; + data_end = (void *)(long)ctx->data_end; + eth = data; + if (eth + 1 > data_end) + return XDP_DROP; + + __builtin_memcpy(eth->h_dest, key.dmac, ETH_ALEN); + __builtin_memcpy(eth->h_source, smac, ETH_ALEN); + eth->h_proto = h_proto; + } + + return bpf_redirect_map(&xdp_fwd_ports, entry->ifindex, 0); +} + +char _license[] SEC("license") = "GPL"; +int _version SEC("version") = LINUX_VERSION_CODE; |