lwt_len_hist_kern.c (1738B)
1/* Copyright (c) 2016 Thomas Graf <tgraf@tgraf.ch> 2 * 3 * This program is free software; you can redistribute it and/or 4 * modify it under the terms of version 2 of the GNU General Public 5 * License as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, but 8 * WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 * General Public License for more details. 11 */ 12 13#include <uapi/linux/bpf.h> 14#include <uapi/linux/if_ether.h> 15#include <uapi/linux/ip.h> 16#include <uapi/linux/in.h> 17#include <bpf/bpf_helpers.h> 18 19struct bpf_elf_map { 20 __u32 type; 21 __u32 size_key; 22 __u32 size_value; 23 __u32 max_elem; 24 __u32 flags; 25 __u32 id; 26 __u32 pinning; 27}; 28 29struct bpf_elf_map SEC("maps") lwt_len_hist_map = { 30 .type = BPF_MAP_TYPE_PERCPU_HASH, 31 .size_key = sizeof(__u64), 32 .size_value = sizeof(__u64), 33 .pinning = 2, 34 .max_elem = 1024, 35}; 36 37static unsigned int log2(unsigned int v) 38{ 39 unsigned int r; 40 unsigned int shift; 41 42 r = (v > 0xFFFF) << 4; v >>= r; 43 shift = (v > 0xFF) << 3; v >>= shift; r |= shift; 44 shift = (v > 0xF) << 2; v >>= shift; r |= shift; 45 shift = (v > 0x3) << 1; v >>= shift; r |= shift; 46 r |= (v >> 1); 47 return r; 48} 49 50static unsigned int log2l(unsigned long v) 51{ 52 unsigned int hi = v >> 32; 53 if (hi) 54 return log2(hi) + 32; 55 else 56 return log2(v); 57} 58 59SEC("len_hist") 60int do_len_hist(struct __sk_buff *skb) 61{ 62 __u64 *value, key, init_val = 1; 63 64 key = log2l(skb->len); 65 66 value = bpf_map_lookup_elem(&lwt_len_hist_map, &key); 67 if (value) 68 __sync_fetch_and_add(value, 1); 69 else 70 bpf_map_update_elem(&lwt_len_hist_map, &key, &init_val, BPF_ANY); 71 72 return BPF_OK; 73} 74 75char _license[] SEC("license") = "GPL";