162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci#include <linux/bpf.h> 362306a36Sopenharmony_ci#include <linux/version.h> 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <bpf/bpf_helpers.h> 662306a36Sopenharmony_ci#include "netcnt_common.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#define MAX_BPS (3 * 1024 * 1024) 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#define REFRESH_TIME_NS 100000000 1162306a36Sopenharmony_ci#define NS_PER_SEC 1000000000 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_cistruct { 1462306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE); 1562306a36Sopenharmony_ci __type(key, struct bpf_cgroup_storage_key); 1662306a36Sopenharmony_ci __type(value, union percpu_net_cnt); 1762306a36Sopenharmony_ci} percpu_netcnt SEC(".maps"); 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct { 2062306a36Sopenharmony_ci __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); 2162306a36Sopenharmony_ci __type(key, struct bpf_cgroup_storage_key); 2262306a36Sopenharmony_ci __type(value, union net_cnt); 2362306a36Sopenharmony_ci} netcnt SEC(".maps"); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciSEC("cgroup/skb") 2662306a36Sopenharmony_ciint bpf_nextcnt(struct __sk_buff *skb) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci union percpu_net_cnt *percpu_cnt; 2962306a36Sopenharmony_ci union net_cnt *cnt; 3062306a36Sopenharmony_ci __u64 ts, dt; 3162306a36Sopenharmony_ci int ret; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci cnt = bpf_get_local_storage(&netcnt, 0); 3462306a36Sopenharmony_ci percpu_cnt = bpf_get_local_storage(&percpu_netcnt, 0); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci percpu_cnt->packets++; 3762306a36Sopenharmony_ci percpu_cnt->bytes += skb->len; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (percpu_cnt->packets > MAX_PERCPU_PACKETS) { 4062306a36Sopenharmony_ci __sync_fetch_and_add(&cnt->packets, 4162306a36Sopenharmony_ci percpu_cnt->packets); 4262306a36Sopenharmony_ci percpu_cnt->packets = 0; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci __sync_fetch_and_add(&cnt->bytes, 4562306a36Sopenharmony_ci percpu_cnt->bytes); 4662306a36Sopenharmony_ci percpu_cnt->bytes = 0; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci ts = bpf_ktime_get_ns(); 5062306a36Sopenharmony_ci dt = ts - percpu_cnt->prev_ts; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci dt *= MAX_BPS; 5362306a36Sopenharmony_ci dt /= NS_PER_SEC; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci if (cnt->bytes + percpu_cnt->bytes - percpu_cnt->prev_bytes < dt) 5662306a36Sopenharmony_ci ret = 1; 5762306a36Sopenharmony_ci else 5862306a36Sopenharmony_ci ret = 0; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci if (dt > REFRESH_TIME_NS) { 6162306a36Sopenharmony_ci percpu_cnt->prev_ts = ts; 6262306a36Sopenharmony_ci percpu_cnt->prev_packets = cnt->packets; 6362306a36Sopenharmony_ci percpu_cnt->prev_bytes = cnt->bytes; 6462306a36Sopenharmony_ci } 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci return !!ret; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cichar _license[] SEC("license") = "GPL"; 70