Blame view

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