From: Jesper Dangaard Brouer Date: Wed, 7 Feb 2018 22:21:14 +0000 (+0100) Subject: ebpf: take clang -target bpf include issue of stdint.h into account X-Git-Tag: suricata-4.1.0-beta1~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7906c521cdde5b1d0eb3ce379b8e343c3055653f;p=thirdparty%2Fsuricata.git 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 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 #endif #if defined __x86_64__ && defined __LP64__ # include #endif #if defined __x86_64__ && defined __ILP32__ # include #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 ^~~~~~~~~~~~~ 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 Sidned-off-by: Eric Leblond --- diff --git a/ebpf/Makefile.am b/ebpf/Makefile.am index 66db35f80c..00d25f936f 100644 --- a/ebpf/Makefile.am +++ b/ebpf/Makefile.am @@ -6,7 +6,7 @@ BPF_CFLAGS = -Iinclude all: lb.bpf filter.bpf bypass_filter.bpf xdp_filter.bpf vlan_filter.bpf %.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 diff --git a/ebpf/bypass_filter.c b/ebpf/bypass_filter.c index d2ce12aa1c..be81032b16 100644 --- a/ebpf/bypass_filter.c +++ b/ebpf/bypass_filter.c @@ -15,7 +15,6 @@ * 02110-1301, USA. */ -#include #include #include @@ -51,9 +50,9 @@ struct flowv6_keys { } __attribute__((__aligned__(8))); struct pair { - uint64_t time; - uint64_t packets; - uint64_t bytes; + __u64 time; + __u64 packets; + __u64 bytes; } __attribute__((__aligned__(8))); 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) { - uint32_t nhoff, verlen; + __u32 nhoff, verlen; struct flowv4_keys tuple; struct pair *value; - uint16_t port; + __u16 port; nhoff = skb->cb[0]; @@ -107,8 +106,8 @@ static __always_inline int ipv4_filter(struct __sk_buff *skb) #if 0 if ((tuple.port16[0] == 22) || (tuple.port16[1] == 22)) { - uint16_t sp = tuple.port16[0]; - //uint16_t dp = tuple.port16[1]; + __u16 sp = tuple.port16[0]; + //__u16 dp = tuple.port16[1]; char fmt[] = "Parsed SSH flow: %u %d -> %u\n"; 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 0 { - uint16_t sp = tuple.port16[0]; - //uint16_t dp = tuple.port16[1]; + __u16 sp = tuple.port16[0]; + //__u16 dp = tuple.port16[1]; char bfmt[] = "Found flow: %u %d -> %u\n"; 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) { - uint32_t nhoff; - uint8_t nhdr; + __u32 nhoff; + __u8 nhdr; struct flowv6_keys tuple; struct pair *value; - uint16_t port; + __u16 port; nhoff = skb->cb[0]; @@ -223,4 +222,4 @@ int SEC("filter") hashfilter(struct __sk_buff *skb) { char __license[] SEC("license") = "GPL"; -uint32_t __version SEC("version") = LINUX_VERSION_CODE; +__u32 __version SEC("version") = LINUX_VERSION_CODE; diff --git a/ebpf/filter.c b/ebpf/filter.c index 1976ffcf18..4fe95d4fb0 100644 --- a/ebpf/filter.c +++ b/ebpf/filter.c @@ -15,7 +15,6 @@ * 02110-1301, USA. */ -#include #include #include @@ -56,4 +55,4 @@ int SEC("filter") hashfilter(struct __sk_buff *skb) { char __license[] SEC("license") = "GPL"; -uint32_t __version SEC("version") = LINUX_VERSION_CODE; +__u32 __version SEC("version") = LINUX_VERSION_CODE; diff --git a/ebpf/hash_func01.h b/ebpf/hash_func01.h index 060346f67a..38255812e3 100644 --- a/ebpf/hash_func01.h +++ b/ebpf/hash_func01.h @@ -4,12 +4,12 @@ * From: http://www.azillionmonkeys.com/qed/hash.html */ -#define get16bits(d) (*((const uint16_t *) (d))) +#define get16bits(d) (*((const __u16 *) (d))) static __always_inline -uint32_t SuperFastHash (const char *data, int len, uint32_t initval) { - uint32_t hash = initval; - uint32_t tmp; +__u32 SuperFastHash (const char *data, int len, __u32 initval) { + __u32 hash = initval; + __u32 tmp; int rem; 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); tmp = (get16bits (data+2) << 11) ^ hash; hash = (hash << 16) ^ tmp; - data += 2*sizeof (uint16_t); + data += 2*sizeof (__u16); hash += hash >> 11; } @@ -31,7 +31,7 @@ uint32_t SuperFastHash (const char *data, int len, uint32_t initval) { switch (rem) { case 3: hash += get16bits (data); hash ^= hash << 16; - hash ^= ((signed char)data[sizeof (uint16_t)]) << 18; + hash ^= ((signed char)data[sizeof (__u16)]) << 18; hash += hash >> 11; break; case 2: hash += get16bits (data); diff --git a/ebpf/lb.c b/ebpf/lb.c index 14974784d9..7551781c5f 100644 --- a/ebpf/lb.c +++ b/ebpf/lb.c @@ -15,7 +15,6 @@ * 02110-1301, USA. */ -#include #include #include @@ -36,8 +35,8 @@ static __always_inline int ipv4_hash(struct __sk_buff *skb) { - uint32_t nhoff; - uint32_t src, dst; + __u32 nhoff; + __u32 src, dst; nhoff = skb->cb[0]; 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) { - uint32_t nhoff; - uint32_t src, dst, hash; + __u32 nhoff; + __u32 src, dst, hash; nhoff = skb->cb[0]; hash = 0; @@ -107,4 +106,4 @@ char __license[] __section("license") = "GPL"; /* libbpf needs version section to check sync of eBPF code and kernel * but socket filter don't need it */ -uint32_t __version __section("version") = LINUX_VERSION_CODE; +__u32 __version __section("version") = LINUX_VERSION_CODE; diff --git a/ebpf/vlan_filter.c b/ebpf/vlan_filter.c index 5c3865273d..d797b94bfb 100644 --- a/ebpf/vlan_filter.c +++ b/ebpf/vlan_filter.c @@ -15,7 +15,6 @@ * 02110-1301, USA. */ -#include #include #include @@ -24,7 +23,7 @@ #define LINUX_VERSION_CODE 263682 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 */ switch (vlan_id) { case 2: @@ -38,4 +37,4 @@ int SEC("filter") hashfilter(struct __sk_buff *skb) { char __license[] SEC("license") = "GPL"; -uint32_t __version SEC("version") = LINUX_VERSION_CODE; +__u32 __version SEC("version") = LINUX_VERSION_CODE; diff --git a/ebpf/xdp_filter.c b/ebpf/xdp_filter.c index 9d3ff0910c..3ee9dd0b11 100644 --- a/ebpf/xdp_filter.c +++ b/ebpf/xdp_filter.c @@ -16,8 +16,6 @@ */ #define KBUILD_MODNAME "foo" -#include -#include #include #include @@ -70,9 +68,9 @@ struct flowv6_keys { } __attribute__((__aligned__(8))); struct pair { - uint64_t time; - uint64_t packets; - uint64_t bytes; + __u64 time; + __u64 packets; + __u64 bytes; } __attribute__((__aligned__(8))); 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, - uint8_t protocol) + __u8 protocol) { struct tcphdr *th; 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, - uint8_t protocol) + __u8 protocol) { struct tcphdr *th; struct udphdr *uh; @@ -178,12 +176,12 @@ static int __always_inline filter_ipv4(void *data, __u64 nh_off, void *data_end) int sport; struct flowv4_keys tuple; struct pair *value; - uint32_t key0 = 0; + __u32 key0 = 0; #if BUILD_CPUMAP - uint32_t cpu_dest; - uint32_t *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0); - uint32_t *cpu_selected; - uint32_t cpu_hash; + __u32 cpu_dest; + __u32 *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0); + __u32 *cpu_selected; + __u32 cpu_hash; #endif int *iface_peer; 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) return XDP_PASS; - tuple.ip_proto = (uint32_t) iph->protocol; + tuple.ip_proto = (__u32) iph->protocol; tuple.src = iph->saddr; 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) return XDP_PASS; - tuple.port16[0] = (uint16_t)sport; - tuple.port16[1] = (uint16_t)dport; + tuple.port16[0] = (__u16)sport; + tuple.port16[1] = (__u16)dport; value = bpf_map_lookup_elem(&flow_table_v4, &tuple); #if 0 { @@ -260,12 +258,12 @@ static int __always_inline filter_ipv6(void *data, __u64 nh_off, void *data_end) int sport; struct flowv6_keys tuple; struct pair *value; - uint32_t key0 = 0; + __u32 key0 = 0; #if BUILD_CPUMAP - uint32_t cpu_dest; + __u32 cpu_dest; int *cpu_max = bpf_map_lookup_elem(&cpus_count, &key0); - uint32_t *cpu_selected; - uint32_t cpu_hash; + __u32 *cpu_selected; + __u32 cpu_hash; #endif int tx_port = 0; int *iface_peer; @@ -336,8 +334,8 @@ int SEC("xdp") xdp_hashfilter(struct xdp_md *ctx) void *data = (void *)(long)ctx->data; struct ethhdr *eth = data; int rc = XDP_PASS; - uint16_t h_proto; - uint64_t nh_off; + __u16 h_proto; + __u64 nh_off; nh_off = sizeof(*eth); if (data + nh_off > data_end) @@ -376,4 +374,4 @@ int SEC("xdp") xdp_hashfilter(struct xdp_md *ctx) char __license[] SEC("license") = "GPL"; -uint32_t __version SEC("version") = LINUX_VERSION_CODE; +__u32 __version SEC("version") = LINUX_VERSION_CODE;