/* SPDX-License-Identifier: GPL-2.0 */ /* Used *ONLY* by BPF-prog running kernel side. */ #ifndef __XDP_STATS_KERN_H #define __XDP_STATS_KERN_H /* Data record type 'struct datarec' is defined in common/xdp_stats_kern_user.h, * programs using this header must first include that file. */ #ifndef __XDP_STATS_KERN_USER_H #warning "You forgot to #include <../common/xdp_stats_kern_user.h>" #include <../common/xdp_stats_kern_user.h> #endif /* Keeps stats per (enum) xdp_action */ struct bpf_map_def SEC("maps") xdp_stats_map = { .type = BPF_MAP_TYPE_PERCPU_ARRAY, .key_size = sizeof(__u32), .value_size = sizeof(struct datarec), .max_entries = XDP_ACTION_MAX, }; static __always_inline __u32 xdp_stats_record_action(struct xdp_md *ctx, __u32 action) { if (action >= XDP_ACTION_MAX) return XDP_ABORTED; /* Lookup in kernel BPF-side return pointer to actual data record */ struct datarec *rec = bpf_map_lookup_elem(&xdp_stats_map, &action); if (!rec) return XDP_ABORTED; /* BPF_MAP_TYPE_PERCPU_ARRAY returns a data record specific to current * CPU and XDP hooks runs under Softirq, which makes it safe to update * without atomic operations. */ rec->rx_packets++; rec->rx_bytes += (ctx->data_end - ctx->data); return action; } #endif /* __XDP_STATS_KERN_H */