summaryrefslogtreecommitdiff
path: root/src/xdp/common/xdp_stats_kern.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/xdp/common/xdp_stats_kern.h')
-rw-r--r--src/xdp/common/xdp_stats_kern.h44
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 */