mirror of
https://github.com/xdp-project/bpf-examples.git
synced 2024-05-06 15:54:53 +00:00
It's way too difficult to read packet data in XDP because LLVM will mostly generate code that doesn't pass the verifier. Thankfully, Cilium has a nice workaround for this in the form of hand-written BPF assembly to perform the reads in a way that the verifier will understand. Let's import these helpers so they can be used by the examples in this repository, along with some of the other BPF helpers that it relies on. This commit imports these files wholesale from Cilium: - include/bpf/builtins.h - include/bpf/compiler.h - include/bpf/errno.h And also adds include/xdp/context_helpers.h which only contains the xdp_load_bytes() and xdp_store_bytes() helpers from Cilium's include/bpf/ctx/xdp.h (as the other functions in that file are specific to how the Cilium code is structured). We also extend the maximum size supported by the efficient memcpy() implementation in builtins.h to 280 bytes, and the mask size applied to packet data copies up to 0x3ff. Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
125 lines
2.6 KiB
C
125 lines
2.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright (C) 2016-2020 Authors of Cilium */
|
|
|
|
#ifndef __BPF_COMPILER_H_
|
|
#define __BPF_COMPILER_H_
|
|
|
|
#ifndef __non_bpf_context
|
|
# include "stddef.h"
|
|
#endif
|
|
|
|
#ifndef __section
|
|
# define __section(X) __attribute__((section(X), used))
|
|
#endif
|
|
|
|
#ifndef __maybe_unused
|
|
# define __maybe_unused __attribute__((__unused__))
|
|
#endif
|
|
|
|
#ifndef offsetof
|
|
# define offsetof(T, M) __builtin_offsetof(T, M)
|
|
#endif
|
|
|
|
#ifndef field_sizeof
|
|
# define field_sizeof(T, M) sizeof((((T *)NULL)->M))
|
|
#endif
|
|
|
|
#ifndef __packed
|
|
# define __packed __attribute__((packed))
|
|
#endif
|
|
|
|
#ifndef __nobuiltin
|
|
# if __clang_major__ >= 10
|
|
# define __nobuiltin(X) __attribute__((no_builtin(X)))
|
|
# else
|
|
# define __nobuiltin(X)
|
|
# endif
|
|
#endif
|
|
|
|
#ifndef likely
|
|
# define likely(X) __builtin_expect(!!(X), 1)
|
|
#endif
|
|
|
|
#ifndef unlikely
|
|
# define unlikely(X) __builtin_expect(!!(X), 0)
|
|
#endif
|
|
|
|
#ifndef always_succeeds /* Mainly for documentation purpose. */
|
|
# define always_succeeds(X) likely(X)
|
|
#endif
|
|
|
|
#undef __always_inline /* stddef.h defines its own */
|
|
#define __always_inline inline __attribute__((always_inline))
|
|
|
|
#ifndef __stringify
|
|
# define __stringify(X) #X
|
|
#endif
|
|
|
|
#ifndef __fetch
|
|
# define __fetch(X) (__u32)(__u64)(&(X))
|
|
#endif
|
|
|
|
#ifndef __aligned
|
|
# define __aligned(X) __attribute__((aligned(X)))
|
|
#endif
|
|
|
|
#ifndef build_bug_on
|
|
# define build_bug_on(E) ((void)sizeof(char[1 - 2*!!(E)]))
|
|
#endif
|
|
|
|
#ifndef __throw_build_bug
|
|
# define __throw_build_bug() __builtin_trap()
|
|
#endif
|
|
|
|
#ifndef __printf
|
|
# define __printf(X, Y) __attribute__((__format__(printf, X, Y)))
|
|
#endif
|
|
|
|
#ifndef barrier
|
|
# define barrier() asm volatile("": : :"memory")
|
|
#endif
|
|
|
|
#ifndef barrier_data
|
|
# define barrier_data(ptr) asm volatile("": :"r"(ptr) :"memory")
|
|
#endif
|
|
|
|
static __always_inline void bpf_barrier(void)
|
|
{
|
|
/* Workaround to avoid verifier complaint:
|
|
* "dereference of modified ctx ptr R5 off=48+0, ctx+const is allowed,
|
|
* ctx+const+const is not"
|
|
*/
|
|
barrier();
|
|
}
|
|
|
|
#ifndef ARRAY_SIZE
|
|
# define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
|
|
#endif
|
|
|
|
#ifndef __READ_ONCE
|
|
# define __READ_ONCE(X) (*(volatile typeof(X) *)&X)
|
|
#endif
|
|
|
|
#ifndef __WRITE_ONCE
|
|
# define __WRITE_ONCE(X, V) (*(volatile typeof(X) *)&X) = (V)
|
|
#endif
|
|
|
|
/* {READ,WRITE}_ONCE() with verifier workaround via bpf_barrier(). */
|
|
|
|
#ifndef READ_ONCE
|
|
# define READ_ONCE(X) \
|
|
({ typeof(X) __val = __READ_ONCE(X); \
|
|
bpf_barrier(); \
|
|
__val; })
|
|
#endif
|
|
|
|
#ifndef WRITE_ONCE
|
|
# define WRITE_ONCE(X, V) \
|
|
({ typeof(X) __val = (V); \
|
|
__WRITE_ONCE(X, __val); \
|
|
bpf_barrier(); \
|
|
__val; })
|
|
#endif
|
|
|
|
#endif /* __BPF_COMPILER_H_ */
|