1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/bpf.h> |
3 | #include <linux/version.h> |
4 | |
5 | #include <bpf/bpf_helpers.h> |
6 | #include "netcnt_common.h" |
7 | |
8 | #define MAX_BPS (3 * 1024 * 1024) |
9 | |
10 | #define REFRESH_TIME_NS 100000000 |
11 | #define NS_PER_SEC 1000000000 |
12 | |
13 | struct { |
14 | __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); |
15 | __type(key, struct bpf_cgroup_storage_key); |
16 | __type(value, union percpu_net_cnt); |
17 | } percpu_netcnt SEC(".maps" ); |
18 | |
19 | struct { |
20 | __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); |
21 | __type(key, struct bpf_cgroup_storage_key); |
22 | __type(value, union net_cnt); |
23 | } netcnt SEC(".maps" ); |
24 | |
25 | SEC("cgroup/skb" ) |
26 | int bpf_nextcnt(struct __sk_buff *skb) |
27 | { |
28 | union percpu_net_cnt *percpu_cnt; |
29 | union net_cnt *cnt; |
30 | __u64 ts, dt; |
31 | int ret; |
32 | |
33 | cnt = bpf_get_local_storage(&netcnt, 0); |
34 | percpu_cnt = bpf_get_local_storage(&percpu_netcnt, 0); |
35 | |
36 | percpu_cnt->packets++; |
37 | percpu_cnt->bytes += skb->len; |
38 | |
39 | if (percpu_cnt->packets > MAX_PERCPU_PACKETS) { |
40 | __sync_fetch_and_add(&cnt->packets, |
41 | percpu_cnt->packets); |
42 | percpu_cnt->packets = 0; |
43 | |
44 | __sync_fetch_and_add(&cnt->bytes, |
45 | percpu_cnt->bytes); |
46 | percpu_cnt->bytes = 0; |
47 | } |
48 | |
49 | ts = bpf_ktime_get_ns(); |
50 | dt = ts - percpu_cnt->prev_ts; |
51 | |
52 | dt *= MAX_BPS; |
53 | dt /= NS_PER_SEC; |
54 | |
55 | if (cnt->bytes + percpu_cnt->bytes - percpu_cnt->prev_bytes < dt) |
56 | ret = 1; |
57 | else |
58 | ret = 0; |
59 | |
60 | if (dt > REFRESH_TIME_NS) { |
61 | percpu_cnt->prev_ts = ts; |
62 | percpu_cnt->prev_packets = cnt->packets; |
63 | percpu_cnt->prev_bytes = cnt->bytes; |
64 | } |
65 | |
66 | return !!ret; |
67 | } |
68 | |
69 | char _license[] SEC("license" ) = "GPL" ; |
70 | |