/* 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 #ifndef XDP_STATS_MAP_PINNING #define XDP_STATS_MAP_PINNING LIBBPF_PIN_BY_NAME #endif /* Keeps stats per (enum) xdp_action */ struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(max_entries, XDP_ACTION_MAX); __type(key, __u32); __type(value, struct xdp_stats_record); __uint(pinning, LIBBPF_PIN_BY_NAME); } XDP_STATS_MAP_NAME SEC(".maps"); 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 xdp_stats_record *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 */