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 "vmlinux.h" 14 #include <bpf/bpf_helpers.h> 15 16 struct { 17 __uint(type, BPF_MAP_TYPE_PERCPU_HASH); 18 __type(key, u64); 19 __type(value, u64); 20 __uint(pinning, LIBBPF_PIN_BY_NAME); 21 __uint(max_entries, 1024); 22 } lwt_len_hist_map SEC(".maps"); 23 24 static unsigned int log2(unsigned int v) 25 { 26 unsigned int r; 27 unsigned int shift; 28 29 r = (v > 0xFFFF) << 4; v >>= r; 30 shift = (v > 0xFF) << 3; v >>= shift; r |= shift; 31 shift = (v > 0xF) << 2; v >>= shift; r |= shift; 32 shift = (v > 0x3) << 1; v >>= shift; r |= shift; 33 r |= (v >> 1); 34 return r; 35 } 36 37 static unsigned int log2l(unsigned long v) 38 { 39 unsigned int hi = v >> 32; 40 if (hi) 41 return log2(hi) + 32; 42 else 43 return log2(v); 44 } 45 46 SEC("len_hist") 47 int do_len_hist(struct __sk_buff *skb) 48 { 49 __u64 *value, key, init_val = 1; 50 51 key = log2l(skb->len); 52 53 value = bpf_map_lookup_elem(&lwt_len_hist_map, &key); 54 if (value) 55 __sync_fetch_and_add(value, 1); 56 else 57 bpf_map_update_elem(&lwt_len_hist_map, &key, &init_val, BPF_ANY); 58 59 return BPF_OK; 60 } 61 62 char _license[] SEC("license") = "GPL"; 63