]>
Commit | Line | Data |
---|---|---|
d822a192 AS |
1 | /* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com |
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 | #include <linux/skbuff.h> | |
8 | #include <linux/netdevice.h> | |
9 | #include <linux/version.h> | |
10 | #include <uapi/linux/bpf.h> | |
7cf245a3 THJ |
11 | #include <bpf/bpf_helpers.h> |
12 | #include <bpf/bpf_tracing.h> | |
63841bc0 | 13 | #include "trace_common.h" |
d822a192 | 14 | |
59929cd1 DL |
15 | struct { |
16 | __uint(type, BPF_MAP_TYPE_HASH); | |
17 | __type(key, long); | |
18 | __type(value, long); | |
19 | __uint(max_entries, 1024); | |
20 | } my_map SEC(".maps"); | |
d822a192 AS |
21 | |
22 | /* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe | |
23 | * example will no longer be meaningful | |
24 | */ | |
25 | SEC("kprobe/kfree_skb") | |
26 | int bpf_prog2(struct pt_regs *ctx) | |
27 | { | |
28 | long loc = 0; | |
29 | long init_val = 1; | |
30 | long *value; | |
31 | ||
138d6153 | 32 | /* read ip of kfree_skb caller. |
d822a192 AS |
33 | * non-portable version of __builtin_return_address(0) |
34 | */ | |
138d6153 | 35 | BPF_KPROBE_READ_RET_IP(loc, ctx); |
d822a192 AS |
36 | |
37 | value = bpf_map_lookup_elem(&my_map, &loc); | |
38 | if (value) | |
39 | *value += 1; | |
40 | else | |
41 | bpf_map_update_elem(&my_map, &loc, &init_val, BPF_ANY); | |
42 | return 0; | |
43 | } | |
44 | ||
45 | static unsigned int log2(unsigned int v) | |
46 | { | |
47 | unsigned int r; | |
48 | unsigned int shift; | |
49 | ||
50 | r = (v > 0xFFFF) << 4; v >>= r; | |
51 | shift = (v > 0xFF) << 3; v >>= shift; r |= shift; | |
52 | shift = (v > 0xF) << 2; v >>= shift; r |= shift; | |
53 | shift = (v > 0x3) << 1; v >>= shift; r |= shift; | |
54 | r |= (v >> 1); | |
55 | return r; | |
56 | } | |
57 | ||
58 | static unsigned int log2l(unsigned long v) | |
59 | { | |
60 | unsigned int hi = v >> 32; | |
61 | if (hi) | |
62 | return log2(hi) + 32; | |
63 | else | |
64 | return log2(v); | |
65 | } | |
66 | ||
ffeedafb AS |
67 | struct hist_key { |
68 | char comm[16]; | |
69 | u64 pid_tgid; | |
70 | u64 uid_gid; | |
02413cab | 71 | u64 index; |
ffeedafb AS |
72 | }; |
73 | ||
59929cd1 DL |
74 | struct { |
75 | __uint(type, BPF_MAP_TYPE_PERCPU_HASH); | |
76 | __uint(key_size, sizeof(struct hist_key)); | |
77 | __uint(value_size, sizeof(long)); | |
78 | __uint(max_entries, 1024); | |
79 | } my_hist_map SEC(".maps"); | |
d822a192 | 80 | |
63841bc0 | 81 | SEC("kprobe/" SYSCALL(sys_write)) |
d822a192 AS |
82 | int bpf_prog3(struct pt_regs *ctx) |
83 | { | |
d912557b | 84 | long write_size = PT_REGS_PARM3(ctx); |
d822a192 AS |
85 | long init_val = 1; |
86 | long *value; | |
02413cab | 87 | struct hist_key key; |
ffeedafb AS |
88 | |
89 | key.index = log2l(write_size); | |
90 | key.pid_tgid = bpf_get_current_pid_tgid(); | |
91 | key.uid_gid = bpf_get_current_uid_gid(); | |
92 | bpf_get_current_comm(&key.comm, sizeof(key.comm)); | |
d822a192 | 93 | |
ffeedafb | 94 | value = bpf_map_lookup_elem(&my_hist_map, &key); |
d822a192 AS |
95 | if (value) |
96 | __sync_fetch_and_add(value, 1); | |
ffeedafb AS |
97 | else |
98 | bpf_map_update_elem(&my_hist_map, &key, &init_val, BPF_ANY); | |
d822a192 AS |
99 | return 0; |
100 | } | |
101 | char _license[] SEC("license") = "GPL"; | |
102 | u32 _version SEC("version") = LINUX_VERSION_CODE; |