Commit f09b5b8a authored by Alexei Starovoitov's avatar Alexei Starovoitov

get rid of version checks

version checks don't work at all on kernels with backported bpf bits
they also fail when /usr/include/linux/bpf.h doesn't match loaded
kernel.
Fix these issues by embedding bpf.h into libbcc.so and force load it
in clang, so we can remove all version checks and rely on verifier
complaining on unknown function call.
Later patch can make verifier errors less cryptic by converting
'unknown call 12' to strings.

while at it update bpf.h to the latest.
Signed-off-by: default avatarAlexei Starovoitov <ast@fb.com>
parent 63a88006
...@@ -101,12 +101,15 @@ enum bpf_prog_type { ...@@ -101,12 +101,15 @@ enum bpf_prog_type {
#define BPF_NOEXIST 1 /* create new element if it didn't exist */ #define BPF_NOEXIST 1 /* create new element if it didn't exist */
#define BPF_EXIST 2 /* update existing element */ #define BPF_EXIST 2 /* update existing element */
#define BPF_F_NO_PREALLOC (1U << 0)
union bpf_attr { union bpf_attr {
struct { /* anonymous struct used by BPF_MAP_CREATE command */ struct { /* anonymous struct used by BPF_MAP_CREATE command */
__u32 map_type; /* one of enum bpf_map_type */ __u32 map_type; /* one of enum bpf_map_type */
__u32 key_size; /* size of key in bytes */ __u32 key_size; /* size of key in bytes */
__u32 value_size; /* size of value in bytes */ __u32 value_size; /* size of value in bytes */
__u32 max_entries; /* max number of entries in a map */ __u32 max_entries; /* max number of entries in a map */
__u32 map_flags; /* prealloc or not */
}; };
struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */
...@@ -298,6 +301,17 @@ enum bpf_func_id { ...@@ -298,6 +301,17 @@ enum bpf_func_id {
* Return: csum result * Return: csum result
*/ */
BPF_FUNC_csum_diff, BPF_FUNC_csum_diff,
/**
* bpf_skb_[gs]et_tunnel_opt(skb, opt, size)
* retrieve or populate tunnel options metadata
* @skb: pointer to skb
* @opt: pointer to raw tunnel option data
* @size: size of @opt
* Return: 0 on success for set, option size for get
*/
BPF_FUNC_skb_get_tunnel_opt,
BPF_FUNC_skb_set_tunnel_opt,
__BPF_FUNC_MAX_ID, __BPF_FUNC_MAX_ID,
}; };
...@@ -305,6 +319,7 @@ enum bpf_func_id { ...@@ -305,6 +319,7 @@ enum bpf_func_id {
/* BPF_FUNC_skb_store_bytes flags. */ /* BPF_FUNC_skb_store_bytes flags. */
#define BPF_F_RECOMPUTE_CSUM (1ULL << 0) #define BPF_F_RECOMPUTE_CSUM (1ULL << 0)
#define BPF_F_INVALIDATE_HASH (1ULL << 1)
/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags. /* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.
* First 4 bits are for passing the header field size. * First 4 bits are for passing the header field size.
...@@ -327,6 +342,10 @@ enum bpf_func_id { ...@@ -327,6 +342,10 @@ enum bpf_func_id {
#define BPF_F_FAST_STACK_CMP (1ULL << 9) #define BPF_F_FAST_STACK_CMP (1ULL << 9)
#define BPF_F_REUSE_STACKID (1ULL << 10) #define BPF_F_REUSE_STACKID (1ULL << 10)
/* BPF_FUNC_skb_set_tunnel_key flags. */
#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
#define BPF_F_DONT_FRAGMENT (1ULL << 2)
/* user accessible mirror of in-kernel sk_buff. /* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure * new fields can only be added to the end of this structure
*/ */
...@@ -356,6 +375,8 @@ struct bpf_tunnel_key { ...@@ -356,6 +375,8 @@ struct bpf_tunnel_key {
}; };
__u8 tunnel_tos; __u8 tunnel_tos;
__u8 tunnel_ttl; __u8 tunnel_ttl;
__u16 tunnel_ext;
__u32 tunnel_label;
}; };
#endif /* _UAPI__LINUX_BPF_H__ */ #endif /* _UAPI__LINUX_BPF_H__ */
This diff is collapsed.
...@@ -142,7 +142,6 @@ static u32 (*bpf_get_prandom_u32)(void) = ...@@ -142,7 +142,6 @@ static u32 (*bpf_get_prandom_u32)(void) =
static int (*bpf_trace_printk_)(const char *fmt, u64 fmt_size, ...) = static int (*bpf_trace_printk_)(const char *fmt, u64 fmt_size, ...) =
(void *) BPF_FUNC_trace_printk; (void *) BPF_FUNC_trace_printk;
int bpf_trace_printk(const char *fmt, ...) asm("llvm.bpf.extra"); int bpf_trace_printk(const char *fmt, ...) asm("llvm.bpf.extra");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,2,0)
static void bpf_tail_call_(u64 map_fd, void *ctx, int index) { static void bpf_tail_call_(u64 map_fd, void *ctx, int index) {
((void (*)(void *, u64, int))BPF_FUNC_tail_call)(ctx, map_fd, index); ((void (*)(void *, u64, int))BPF_FUNC_tail_call)(ctx, map_fd, index);
} }
...@@ -156,8 +155,6 @@ static u64 (*bpf_get_current_uid_gid)(void) = ...@@ -156,8 +155,6 @@ static u64 (*bpf_get_current_uid_gid)(void) =
(void *) BPF_FUNC_get_current_uid_gid; (void *) BPF_FUNC_get_current_uid_gid;
static int (*bpf_get_current_comm)(void *buf, int buf_size) = static int (*bpf_get_current_comm)(void *buf, int buf_size) =
(void *) BPF_FUNC_get_current_comm; (void *) BPF_FUNC_get_current_comm;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
static u64 (*bpf_get_cgroup_classid)(void *ctx) = static u64 (*bpf_get_cgroup_classid)(void *ctx) =
(void *) BPF_FUNC_get_cgroup_classid; (void *) BPF_FUNC_get_cgroup_classid;
static u64 (*bpf_skb_vlan_push)(void *ctx, u16 proto, u16 vlan_tci) = static u64 (*bpf_skb_vlan_push)(void *ctx, u16 proto, u16 vlan_tci) =
...@@ -170,20 +167,14 @@ static int (*bpf_skb_set_tunnel_key)(void *ctx, void *from, u32 size, u64 flags) ...@@ -170,20 +167,14 @@ static int (*bpf_skb_set_tunnel_key)(void *ctx, void *from, u32 size, u64 flags)
(void *) BPF_FUNC_skb_set_tunnel_key; (void *) BPF_FUNC_skb_set_tunnel_key;
static int (*bpf_perf_event_read)(void *map, u32 index) = static int (*bpf_perf_event_read)(void *map, u32 index) =
(void *) BPF_FUNC_perf_event_read; (void *) BPF_FUNC_perf_event_read;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)
static int (*bpf_redirect)(int ifindex, u32 flags) = static int (*bpf_redirect)(int ifindex, u32 flags) =
(void *) BPF_FUNC_redirect; (void *) BPF_FUNC_redirect;
static u32 (*bpf_get_route_realm)(void *ctx) = static u32 (*bpf_get_route_realm)(void *ctx) =
(void *) BPF_FUNC_get_route_realm; (void *) BPF_FUNC_get_route_realm;
static int (*bpf_perf_event_output)(void *ctx, void *map, u32 index, void *data, u32 size) = static int (*bpf_perf_event_output)(void *ctx, void *map, u32 index, void *data, u32 size) =
(void *) BPF_FUNC_perf_event_output; (void *) BPF_FUNC_perf_event_output;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)
static int (*bpf_skb_load_bytes)(void *ctx, int offset, void *to, u32 len) = static int (*bpf_skb_load_bytes)(void *ctx, int offset, void *to, u32 len) =
(void *) BPF_FUNC_skb_load_bytes; (void *) BPF_FUNC_skb_load_bytes;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
static int (*bpf_get_stackid_)(void *ctx, void *map, u64 flags) = static int (*bpf_get_stackid_)(void *ctx, void *map, u64 flags) =
(void *) BPF_FUNC_get_stackid; (void *) BPF_FUNC_get_stackid;
static inline __attribute__((always_inline)) static inline __attribute__((always_inline))
...@@ -192,7 +183,6 @@ int bpf_get_stackid(uintptr_t map, void *ctx, u64 flags) { ...@@ -192,7 +183,6 @@ int bpf_get_stackid(uintptr_t map, void *ctx, u64 flags) {
} }
static int (*bpf_csum_diff)(void *from, u64 from_size, void *to, u64 to_size, u64 seed) = static int (*bpf_csum_diff)(void *from, u64 from_size, void *to, u64 to_size, u64 seed) =
(void *) BPF_FUNC_csum_diff; (void *) BPF_FUNC_csum_diff;
#endif
/* llvm builtin functions that eBPF C program may use to /* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions * emit BPF_LD_ABS and BPF_LD_IND instructions
......
...@@ -25,6 +25,10 @@ namespace ebpf { ...@@ -25,6 +25,10 @@ namespace ebpf {
// see http://www.stroustrup.com/C++11FAQ.html#raw-strings // see http://www.stroustrup.com/C++11FAQ.html#raw-strings
map<string, const char *> ExportedFiles::headers_ = { map<string, const char *> ExportedFiles::headers_ = {
{
"/virtual/include/bcc/bpf.h",
#include "compat/linux/virtual_bpf.h"
},
{ {
"/virtual/include/bcc/proto.h", "/virtual/include/bcc/proto.h",
#include "export/proto.h" #include "export/proto.h"
......
...@@ -585,18 +585,15 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) { ...@@ -585,18 +585,15 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
diag_.Report(Decl->getLocStart(), diag_id) << table.leaf_desc; diag_.Report(Decl->getLocStart(), diag_id) << table.leaf_desc;
} }
} else if (A->getName() == "maps/prog") { } else if (A->getName() == "maps/prog") {
if (KERNEL_VERSION(major,minor,0) >= KERNEL_VERSION(4,2,0)) map_type = BPF_MAP_TYPE_PROG_ARRAY;
map_type = BPF_MAP_TYPE_PROG_ARRAY;
} else if (A->getName() == "maps/perf_output") { } else if (A->getName() == "maps/perf_output") {
if (KERNEL_VERSION(major,minor,0) >= KERNEL_VERSION(4,3,0)) map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY;
map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY;
int numcpu = sysconf(_SC_NPROCESSORS_ONLN); int numcpu = sysconf(_SC_NPROCESSORS_ONLN);
if (numcpu <= 0) if (numcpu <= 0)
numcpu = 1; numcpu = 1;
table.max_entries = numcpu; table.max_entries = numcpu;
} else if (A->getName() == "maps/perf_array") { } else if (A->getName() == "maps/perf_array") {
if (KERNEL_VERSION(major,minor,0) >= KERNEL_VERSION(4,3,0)) map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY;
map_type = BPF_MAP_TYPE_PERF_EVENT_ARRAY;
} else if (A->getName() == "maps/stacktrace") { } else if (A->getName() == "maps/stacktrace") {
map_type = BPF_MAP_TYPE_STACK_TRACE; map_type = BPF_MAP_TYPE_STACK_TRACE;
} else if (A->getName() == "maps/extern") { } else if (A->getName() == "maps/extern") {
......
...@@ -77,8 +77,6 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -77,8 +77,6 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
using namespace clang; using namespace clang;
string main_path = "/virtual/main.c"; string main_path = "/virtual/main.c";
string proto_path = "/virtual/include/bcc/proto.h";
string helpers_path = "/virtual/include/bcc/helpers.h";
unique_ptr<llvm::MemoryBuffer> main_buf; unique_ptr<llvm::MemoryBuffer> main_buf;
struct utsname un; struct utsname un;
uname(&un); uname(&un);
...@@ -110,6 +108,8 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes ...@@ -110,6 +108,8 @@ int ClangLoader::parse(unique_ptr<llvm::Module> *mod, unique_ptr<vector<TableDes
if (kbuild_helper.get_flags(un.machine, &kflags)) if (kbuild_helper.get_flags(un.machine, &kflags))
return -1; return -1;
kflags.push_back("-include"); kflags.push_back("-include");
kflags.push_back("/virtual/include/bcc/bpf.h");
kflags.push_back("-include");
kflags.push_back("/virtual/include/bcc/helpers.h"); kflags.push_back("/virtual/include/bcc/helpers.h");
kflags.push_back("-isystem"); kflags.push_back("-isystem");
kflags.push_back("/virtual/include"); kflags.push_back("/virtual/include");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment