[llvm-dev] bpf compilation using clang (original) (raw)
Sameeh Jubran via llvm-dev llvm-dev at lists.llvm.org
Tue Sep 25 03:48:24 PDT 2018
- Previous message: [llvm-dev] bpf compilation using clang
- Next message: [llvm-dev] bpf compilation using clang
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
The headers can be found here: iproute2$ git remote -v origin https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/ (fetch) origin https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/ (push)
I have more headers which I have created. I can push this to github if needed and you'll have all of the dependencies.
iteration count of 40 is the max key size.
I have mistakenly sent the wrong source code. This is the up-to-date one:
#include <stdint.h> #include <stddef.h> #include <stdbool.h> #include <sys/types.h> #include <sys/socket.h> #include <asm/types.h> #include <linux/in.h> #include <linux/if.h> #include <linux/if_ether.h> #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/if_tunnel.h> #include <linux/filter.h> #include <linux/bpf.h>
#include "bpf_api.h" #include "rss_tap_bpf.h"
/** Create IPv4 address */
#define IPv4(a, b, c, d) ((__u32)(((a) & 0xff) << 24) |
(((b) & 0xff) << 16) |
(((c) & 0xff) << 8) |
((d) & 0xff))
#define PORT(a, b) ((__u16)(((a) & 0xff) << 8) |
((b) & 0xff))
#define KEY_IDX 0
struct vlan_hdr { __be16 h_vlan_TCI; __be16 h_vlan_encapsulated_proto; };
//struct bpf_elf_map attribute((section("maps"), used)) struct bpf_elf_map attribute((section("maps"), used)) map_rss = { .type = BPF_MAP_TYPE_ARRAY, .size_key = sizeof(__u32), .size_value = sizeof(struct rss_key), .max_elem = 1, };
//struct bpf_elf_map attribute((section("maps"), used)) struct bpf_elf_map attribute((section("maps"), used)) map_rss_key = { .type = BPF_MAP_TYPE_ARRAY, .size_key = sizeof(__u32), .size_value = sizeof(__u8), .max_elem = RSS_MAX_KEY_SIZE, };
//struct bpf_elf_map attribute((section("maps"), used)) struct bpf_elf_map attribute((section("maps"), used)) map_rss_indirection = { .type = BPF_MAP_TYPE_ARRAY, .size_key = sizeof(__u32), .size_value = sizeof(__u32), .max_elem = RSS_MAX_INDIRECTION_SIZE, };
struct ipv4_l3_l4_tuple { __u32 src_addr; __u32 dst_addr; __u16 dport; __u16 sport; } attribute((packed));
struct ipv6_l3_l4_tuple { __u8 src_addr[16]; __u8 dst_addr[16]; __u16 dport; __u16 sport; } attribute((packed));
static __u32 attribute((always_inline)) rte_softrss_be(const __u32 *input_tuple, const __u8 *key, __u8 input_len) { __u32 i, j, hash = 0; #pragma unroll for (j = 0; j < input_len; j++) { #pragma unroll for (i = 0; i < 32; i++) { if (input_tuple[j] & (1 << (31 - i))) { hash ^= ((const __u32 *) key)[j] << i | (__u32)((uint64_t) (((const __u32 *) key)[j + 1]) >> (32 - i)); } } } return hash; }
static void attribute((always_inline)) fill_key_to_array(__u8 *array) { __u32 i = 0; __u8 *elem; for(i = 0; i < RSS_MAX_KEY_SIZE; i++) { elem = map_lookup_elem(&map_rss_key, &i); array[i] = elem == NULL ? '0' : *elem; } }
static int attribute((always_inline)) rss_l3_l4(struct __sk_buff *skb) { __u64 proto = load_half(skb, 12); __u64 nhoff = ETH_HLEN; __u32 key_idx = 0xdeadbeef; __u32 hash = 0; int j = 0; __u32 * queue; __u8 key[RSS_MAX_KEY_SIZE]; struct rss_key *rss_key;
rss_key = (struct rss_key *) map_lookup_elem(&map_rss, &key_idx);
if (!rss_key) {
return -1;
}
fill_key_to_array(key);
if (proto == ETH_P_8021AD) { proto = load_half(skb, nhoff + offsetof(struct vlan_hdr, h_vlan_encapsulated_proto)); nhoff += sizeof(struct vlan_hdr); }
if (proto == ETH_P_8021Q) { proto = load_half(skb, nhoff + offsetof(struct vlan_hdr, h_vlan_encapsulated_proto)); nhoff += sizeof(struct vlan_hdr); }
if (likely(proto == ETH_P_IP)) { struct ipv4_l3_l4_tuple v4_tuple = { .src_addr = IPv4(load_byte(skb, nhoff + offsetof(struct iphdr, saddr)), load_byte(skb, nhoff + offsetof(struct iphdr, saddr) + 1), load_byte(skb, nhoff + offsetof(struct iphdr, saddr) + 2), load_byte(skb, nhoff + offsetof(struct iphdr, saddr) + 3)), .dst_addr = IPv4(load_byte(skb, nhoff + offsetof(struct iphdr, daddr)), load_byte(skb, nhoff + offsetof(struct iphdr, daddr) + 1), load_byte(skb, nhoff + offsetof(struct iphdr, daddr) + 2), load_byte(skb, nhoff + offsetof(struct iphdr, daddr) + 3)), .sport = PORT(load_byte(skb, nhoff + sizeof(struct iphdr)), load_byte(skb, nhoff + sizeof(struct iphdr) + 1)), .dport = PORT(load_byte(skb, nhoff + sizeof(struct iphdr) + 2), load_byte(skb, nhoff + sizeof(struct iphdr) + 3)) }; __u8 input_len = sizeof(v4_tuple) / sizeof(__u32); if (rss_key->hash_fields & (1 << HASH_FIELD_IPV4_L3)) input_len--; hash = rte_softrss_be((__u32 *)&v4_tuple, key, 3); } else if (proto == htons(ETH_P_IPV6)) { struct ipv6_l3_l4_tuple v6_tuple; for (j = 0; j < 4; j++) *((uint32_t *)&v6_tuple.src_addr + j) = load_word(skb, nhoff + offsetof(struct ipv6hdr, saddr) + j); for (j = 0; j < 4; j++) *((uint32_t *)&v6_tuple.dst_addr + j) = load_word(skb, nhoff + offsetof(struct ipv6hdr, daddr) + j); v6_tuple.sport = PORT(load_byte(skb, nhoff + sizeof(struct ipv6hdr)), load_byte(skb, nhoff + sizeof(struct ipv6hdr) + 1)); v6_tuple.dport = PORT(load_byte(skb, nhoff + sizeof(struct ipv6hdr) + 2), load_byte(skb, nhoff + sizeof(struct ipv6hdr) + 3));
__u8 input_len = sizeof(v6_tuple) / sizeof(__u32); if (rss_key->hash_fields & (1 << HASH_FIELD_IPV6_L3)) input_len--; hash = rte_softrss_be((__u32 *)&v6_tuple, key, 9); } else { return -1; } __u32 indirection_index = hash % rss_key->nb_queues; queue = (__u32 *) map_lookup_elem(&map_rss_indirection, &indirection_index);
return queue == NULL ? -1 : (int) *queue;
}
#define RSS(L)
__section(#L) int
L ## _hash(struct _sk_buff *skb)
{
return rss ## L(skb);
}
RSS(l3_l4)
BPF_LICENSE("Dual BSD/GPL");On Tue, Sep 25, 2018 at 1:21 PM Tim Northover <t.p.northover at gmail.com> wrote:
On Tue, 25 Sep 2018 at 09:27, Sameeh Jubran <sameeh at daynix.com> wrote: > * Here you can find the source code: I'm afraid I don't have the headers to compile it myself, and couldn't track them down easily. The preprocessed output (with -E as well) would be more useful (as an attachment). At the moment I can't really link that loop back to anything in the source. It seems to have an iteration count of 40 which doesn't match with anything I can see. Cheers. Tim.
-- Respectfully, Sameeh Jubran Linkedin Software Engineer @ Daynix.
- Previous message: [llvm-dev] bpf compilation using clang
- Next message: [llvm-dev] bpf compilation using clang
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]