diff options
Diffstat (limited to 'src/xdp/common/xdp_stats_kern.h')
-rw-r--r-- | src/xdp/common/xdp_stats_kern.h | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/xdp/common/xdp_stats_kern.h b/src/xdp/common/xdp_stats_kern.h new file mode 100644 index 000000000..4e08551a0 --- /dev/null +++ b/src/xdp/common/xdp_stats_kern.h @@ -0,0 +1,44 @@ +/* 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 */ |