ebpf: take clang -target bpf include issue of stdint.h into account

This patch prepares code before enabling the clang -target bpf.

The clang compiler does not like #include <stdint.h> when
using '-target bpf' it will fail with:

 fatal error: 'gnu/stubs-32.h' file not found

This is because using clang -target bpf, then clang will have '__bpf__'
defined instead of '__x86_64__' hence the gnu/stubs-32.h include
attempt as /usr/include/gnu/stubs.h contains, on x86_64:

  #if !defined __x86_64__
  # include <gnu/stubs-32.h>
  #endif
  #if defined __x86_64__ && defined __LP64__
  # include <gnu/stubs-64.h>
  #endif
  #if defined __x86_64__ && defined __ILP32__
  # include <gnu/stubs-x32.h>
  #endif

This can be worked around by installing the 32-bit version of
glibc-devel.i686 on your distribution.

But the BPF programs does not really need to include stdint.h,
if converting:
  uint64_t -> __u64
  uint32_t -> __u32
  uint16_t -> __u16
  uint8_t  -> __u8

This patch does this type syntax conversion.

The build of a ebpf files had an issue for system like Debian
because they don't have a asm/types.h in the include path if the
architecture is not defined which is the case due to target bpf.

This results in:

 clang-5.0 -Wall -Iinclude -O2 \
         -D__KERNEL__ -D__ASM_SYSREG_H \
         -target bpf -S -emit-llvm vlan_filter.c -o vlan_filter.ll
 In file included from vlan_filter.c:19:
 In file included from include/linux/bpf.h:11:
 /usr/include/linux/types.h:5:10: fatal error: 'asm/types.h' file not
 found
 #include <asm/types.h>
          ^~~~~~~~~~~~~
 1 error generated.
 Makefile:523: recipe for target 'vlan_filter.bpf' failed

This patch fixes the issue by adding a include path setting the
architecture to the one of the builder.

Signed-off-by: Jesper Dangaard Brouer <netoptimizer@brouer.com>
Sidned-off-by: Eric Leblond <eric@regit.org>
pull/3263/head
Jesper Dangaard Brouer 9 years ago committed by Victor Julien
parent ffc847db01
commit 7906c521cd

@ -6,7 +6,7 @@ BPF_CFLAGS = -Iinclude
all: lb.bpf filter.bpf bypass_filter.bpf xdp_filter.bpf vlan_filter.bpf all: lb.bpf filter.bpf bypass_filter.bpf xdp_filter.bpf vlan_filter.bpf
%.bpf: %.c %.bpf: %.c
${CC} -Wall $(BPF_CFLAGS) -O2 -D__KERNEL__ -D__ASM_SYSREG_H -emit-llvm -c $< -o - | ${LLC} -march=bpf -filetype=obj -o $@ ${CC} -Wall $(BPF_CFLAGS) -O2 -I/usr/include/$(build_cpu)-$(build_os)/ -D__KERNEL__ -D__ASM_SYSREG_H -emit-llvm -c $< -o - | ${LLC} -march=bpf -filetype=obj -o $@
CLEANFILES = *.bpf CLEANFILES = *.bpf

@ -15,7 +15,6 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <linux/bpf.h> #include <linux/bpf.h>
@ -51,9 +50,9 @@ struct flowv6_keys {
} __attribute__((__aligned__(8))); } __attribute__((__aligned__(8)));
struct pair { struct pair {
uint64_t time; __u64 time;
uint64_t packets; __u64 packets;
uint64_t bytes; __u64 bytes;
} __attribute__((__aligned__(8))); } __attribute__((__aligned__(8)));
struct bpf_map_def SEC("maps") flow_table_v4 = { struct bpf_map_def SEC("maps") flow_table_v4 = {
@ -77,10 +76,10 @@ struct bpf_map_def SEC("maps") flow_table_v6 = {
*/ */
static __always_inline int ipv4_filter(struct __sk_buff *skb) static __always_inline int ipv4_filter(struct __sk_buff *skb)
{ {
uint32_t nhoff, verlen; __u32 nhoff, verlen;
struct flowv4_keys tuple; struct flowv4_keys tuple;
struct pair *value; struct pair *value;
uint16_t port; __u16 port;
nhoff = skb->cb[0]; nhoff = skb->cb[0];
@ -107,8 +106,8 @@ static __always_inline int ipv4_filter(struct __sk_buff *skb)
#if 0 #if 0
if ((tuple.port16[0] == 22) || (tuple.port16[1] == 22)) if ((tuple.port16[0] == 22) || (tuple.port16[1] == 22))
{ {
uint16_t sp = tuple.port16[0]; __u16 sp = tuple.port16[0];
//uint16_t dp = tuple.port16[1]; //__u16 dp = tuple.port16[1];
char fmt[] = "Parsed SSH flow: %u %d -> %u\n"; char fmt[] = "Parsed SSH flow: %u %d -> %u\n";
bpf_trace_printk(fmt, sizeof(fmt), tuple.src, sp, tuple.dst); bpf_trace_printk(fmt, sizeof(fmt), tuple.src, sp, tuple.dst);
} }
@ -118,8 +117,8 @@ static __always_inline int ipv4_filter(struct __sk_buff *skb)
if (value) { if (value) {
#if 0 #if 0
{ {
uint16_t sp = tuple.port16[0]; __u16 sp = tuple.port16[0];
//uint16_t dp = tuple.port16[1]; //__u16 dp = tuple.port16[1];
char bfmt[] = "Found flow: %u %d -> %u\n"; char bfmt[] = "Found flow: %u %d -> %u\n";
bpf_trace_printk(bfmt, sizeof(bfmt), tuple.src, sp, tuple.dst); bpf_trace_printk(bfmt, sizeof(bfmt), tuple.src, sp, tuple.dst);
} }
@ -139,11 +138,11 @@ static __always_inline int ipv4_filter(struct __sk_buff *skb)
*/ */
static __always_inline int ipv6_filter(struct __sk_buff *skb) static __always_inline int ipv6_filter(struct __sk_buff *skb)
{ {
uint32_t nhoff; __u32 nhoff;
uint8_t nhdr; __u8 nhdr;
struct flowv6_keys tuple; struct flowv6_keys tuple;
struct pair *value; struct pair *value;
uint16_t port; __u16 port;
nhoff = skb->cb[0]; nhoff = skb->cb[0];
@ -223,4 +222,4 @@ int SEC("filter") hashfilter(struct __sk_buff *skb) {
char __license[] SEC("license") = "GPL"; char __license[] SEC("license") = "GPL";
uint32_t __version SEC("version") = LINUX_VERSION_CODE; __u32 __version SEC("version") = LINUX_VERSION_CODE;

@ -15,7 +15,6 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <linux/bpf.h> #include <linux/bpf.h>
@ -56,4 +55,4 @@ int SEC("filter") hashfilter(struct __sk_buff *skb) {
char __license[] SEC("license") = "GPL"; char __license[] SEC("license") = "GPL";
uint32_t __version SEC("version") = LINUX_VERSION_CODE; __u32 __version SEC("version") = LINUX_VERSION_CODE;

@ -4,12 +4,12 @@
* From: http://www.azillionmonkeys.com/qed/hash.html * From: http://www.azillionmonkeys.com/qed/hash.html
*/ */
#define get16bits(d) (*((const uint16_t *) (d))) #define get16bits(d) (*((const __u16 *) (d)))
static __always_inline static __always_inline
uint32_t SuperFastHash (const char *data, int len, uint32_t initval) { __u32 SuperFastHash (const char *data, int len, __u32 initval) {
uint32_t hash = initval; __u32 hash = initval;
uint32_t tmp; __u32 tmp;
int rem; int rem;
if (len <= 0 || data == NULL) return 0; if (len <= 0 || data == NULL) return 0;
@ -23,7 +23,7 @@ uint32_t SuperFastHash (const char *data, int len, uint32_t initval) {
hash += get16bits (data); hash += get16bits (data);
tmp = (get16bits (data+2) << 11) ^ hash; tmp = (get16bits (data+2) << 11) ^ hash;
hash = (hash << 16) ^ tmp; hash = (hash << 16) ^ tmp;
data += 2*sizeof (uint16_t); data += 2*sizeof (__u16);
hash += hash >> 11; hash += hash >> 11;
} }
@ -31,7 +31,7 @@ uint32_t SuperFastHash (const char *data, int len, uint32_t initval) {
switch (rem) { switch (rem) {
case 3: hash += get16bits (data); case 3: hash += get16bits (data);
hash ^= hash << 16; hash ^= hash << 16;
hash ^= ((signed char)data[sizeof (uint16_t)]) << 18; hash ^= ((signed char)data[sizeof (__u16)]) << 18;
hash += hash >> 11; hash += hash >> 11;
break; break;
case 2: hash += get16bits (data); case 2: hash += get16bits (data);

@ -15,7 +15,6 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <linux/bpf.h> #include <linux/bpf.h>
@ -36,8 +35,8 @@
static __always_inline int ipv4_hash(struct __sk_buff *skb) static __always_inline int ipv4_hash(struct __sk_buff *skb)
{ {
uint32_t nhoff; __u32 nhoff;
uint32_t src, dst; __u32 src, dst;
nhoff = skb->cb[0]; nhoff = skb->cb[0];
src = load_word(skb, nhoff + offsetof(struct iphdr, saddr)); src = load_word(skb, nhoff + offsetof(struct iphdr, saddr));
@ -54,8 +53,8 @@ static __always_inline int ipv4_hash(struct __sk_buff *skb)
static __always_inline int ipv6_hash(struct __sk_buff *skb) static __always_inline int ipv6_hash(struct __sk_buff *skb)
{ {
uint32_t nhoff; __u32 nhoff;
uint32_t src, dst, hash; __u32 src, dst, hash;
nhoff = skb->cb[0]; nhoff = skb->cb[0];
hash = 0; hash = 0;
@ -107,4 +106,4 @@ char __license[] __section("license") = "GPL";
/* libbpf needs version section to check sync of eBPF code and kernel /* libbpf needs version section to check sync of eBPF code and kernel
* but socket filter don't need it */ * but socket filter don't need it */
uint32_t __version __section("version") = LINUX_VERSION_CODE; __u32 __version __section("version") = LINUX_VERSION_CODE;

@ -15,7 +15,6 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <linux/bpf.h> #include <linux/bpf.h>
@ -24,7 +23,7 @@
#define LINUX_VERSION_CODE 263682 #define LINUX_VERSION_CODE 263682
int SEC("filter") hashfilter(struct __sk_buff *skb) { int SEC("filter") hashfilter(struct __sk_buff *skb) {
uint16_t vlan_id = skb->vlan_tci & 0x0fff; __u16 vlan_id = skb->vlan_tci & 0x0fff;
/* accept VLAN 2 and 4 and drop the rest */ /* accept VLAN 2 and 4 and drop the rest */
switch (vlan_id) { switch (vlan_id) {
case 2: case 2:
@ -38,4 +37,4 @@ int SEC("filter") hashfilter(struct __sk_buff *skb) {
char __license[] SEC("license") = "GPL"; char __license[] SEC("license") = "GPL";
uint32_t __version SEC("version") = LINUX_VERSION_CODE; __u32 __version SEC("version") = LINUX_VERSION_CODE;

@ -16,8 +16,6 @@
*/ */
#define KBUILD_MODNAME "foo" #define KBUILD_MODNAME "foo"
#include <stdint.h>
#include <string.h>
#include <stddef.h> #include <stddef.h>
#include <linux/bpf.h> #include <linux/bpf.h>
@ -70,9 +68,9 @@ struct flowv6_keys {
} __attribute__((__aligned__(8))); } __attribute__((__aligned__(8)));
struct pair { struct pair {
uint64_t time; __u64 time;
uint64_t packets; __u64 packets;
uint64_t bytes; __u64 bytes;
} __attribute__((__aligned__(8))); } __attribute__((__aligned__(8)));
struct bpf_map_def SEC("maps") flow_table_v4 = { struct bpf_map_def SEC("maps") flow_table_v4 = {
@ -128,7 +126,7 @@ struct bpf_map_def SEC("maps") tx_peer_int = {
}; };
static __always_inline int get_sport(void *trans_data, void *data_end, static __always_inline int get_sport(void *trans_data, void *data_end,
uint8_t protocol) __u8 protocol)
{ {
struct tcphdr *th; struct tcphdr *th;
struct udphdr *uh; struct udphdr *uh;
@ -150,7 +148,7 @@ static __always_inline int get_sport(void *trans_data, void *data_end,
} }
static __always_inline int get_dport(void *trans_data, void *data_end, static __always_inline int get_dport(void *trans_data, void *data_end,
uint8_t protocol) __u8 protocol)
{ {
struct tcphdr *th; struct tcphdr *th;
struct udphdr *uh; struct udphdr *uh;
@ -178,12 +176,12 @@ static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end)
int sport; int sport;
struct flowv4_keys tuple; struct flowv4_keys tuple;
struct pair *value; struct pair *value;
uint32_t key0 = 0; __u32 key0 = 0;
#if BUILD_CPUMAP #if BUILD_CPUMAP
uint32_t cpu_dest; __u32 cpu_dest;
uint32_t *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0); __u32 *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0);
uint32_t *cpu_selected; __u32 *cpu_selected;
uint32_t cpu_hash; __u32 cpu_hash;
#endif #endif
int *iface_peer; int *iface_peer;
int tx_port = 0; int tx_port = 0;
@ -191,7 +189,7 @@ static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end)
if ((void *)(iph + 1) > data_end) if ((void *)(iph + 1) > data_end)
return XDP_PASS; return XDP_PASS;
tuple.ip_proto = (uint32_t) iph->protocol; tuple.ip_proto = (__u32) iph->protocol;
tuple.src = iph->saddr; tuple.src = iph->saddr;
tuple.dst = iph->daddr; tuple.dst = iph->daddr;
@ -203,8 +201,8 @@ static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end)
if (sport == -1) if (sport == -1)
return XDP_PASS; return XDP_PASS;
tuple.port16[0] = (uint16_t)sport; tuple.port16[0] = (__u16)sport;
tuple.port16[1] = (uint16_t)dport; tuple.port16[1] = (__u16)dport;
value = bpf_map_lookup_elem(&flow_table_v4, &tuple); value = bpf_map_lookup_elem(&flow_table_v4, &tuple);
#if 0 #if 0
{ {
@ -260,12 +258,12 @@ static int __always_inline filter_ipv6(void *data, __u64 nh_off, void *data_end)
int sport; int sport;
struct flowv6_keys tuple; struct flowv6_keys tuple;
struct pair *value; struct pair *value;
uint32_t key0 = 0; __u32 key0 = 0;
#if BUILD_CPUMAP #if BUILD_CPUMAP
uint32_t cpu_dest; __u32 cpu_dest;
int *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0); int *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0);
uint32_t *cpu_selected; __u32 *cpu_selected;
uint32_t cpu_hash; __u32 cpu_hash;
#endif #endif
int tx_port = 0; int tx_port = 0;
int *iface_peer; int *iface_peer;
@ -336,8 +334,8 @@ int SEC("xdp") xdp_hashfilter(struct xdp_md *ctx)
void *data = (void *)(long)ctx->data; void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data; struct ethhdr *eth = data;
int rc = XDP_PASS; int rc = XDP_PASS;
uint16_t h_proto; __u16 h_proto;
uint64_t nh_off; __u64 nh_off;
nh_off = sizeof(*eth); nh_off = sizeof(*eth);
if (data + nh_off > data_end) if (data + nh_off > data_end)
@ -376,4 +374,4 @@ int SEC("xdp") xdp_hashfilter(struct xdp_md *ctx)
char __license[] SEC("license") = "GPL"; char __license[] SEC("license") = "GPL";
uint32_t __version SEC("version") = LINUX_VERSION_CODE; __u32 __version SEC("version") = LINUX_VERSION_CODE;

Loading…
Cancel
Save