162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#ifndef _XDP_SAMPLE_BPF_H
362306a36Sopenharmony_ci#define _XDP_SAMPLE_BPF_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include "vmlinux.h"
662306a36Sopenharmony_ci#include <bpf/bpf_tracing.h>
762306a36Sopenharmony_ci#include <bpf/bpf_core_read.h>
862306a36Sopenharmony_ci#include <bpf/bpf_helpers.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "net_shared.h"
1162306a36Sopenharmony_ci#include "xdp_sample_shared.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define EINVAL 22
1462306a36Sopenharmony_ci#define ENETDOWN 100
1562306a36Sopenharmony_ci#define EMSGSIZE 90
1662306a36Sopenharmony_ci#define EOPNOTSUPP 95
1762306a36Sopenharmony_ci#define ENOSPC 28
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_citypedef struct {
2062306a36Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_ARRAY);
2162306a36Sopenharmony_ci	__uint(map_flags, BPF_F_MMAPABLE);
2262306a36Sopenharmony_ci	__type(key, unsigned int);
2362306a36Sopenharmony_ci	__type(value, struct datarec);
2462306a36Sopenharmony_ci} array_map;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciextern array_map rx_cnt;
2762306a36Sopenharmony_ciextern const volatile int nr_cpus;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cienum {
3062306a36Sopenharmony_ci	XDP_REDIRECT_SUCCESS = 0,
3162306a36Sopenharmony_ci	XDP_REDIRECT_ERROR = 1
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistatic __always_inline void swap_src_dst_mac(void *data)
3562306a36Sopenharmony_ci{
3662306a36Sopenharmony_ci	unsigned short *p = data;
3762306a36Sopenharmony_ci	unsigned short dst[3];
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	dst[0] = p[0];
4062306a36Sopenharmony_ci	dst[1] = p[1];
4162306a36Sopenharmony_ci	dst[2] = p[2];
4262306a36Sopenharmony_ci	p[0] = p[3];
4362306a36Sopenharmony_ci	p[1] = p[4];
4462306a36Sopenharmony_ci	p[2] = p[5];
4562306a36Sopenharmony_ci	p[3] = dst[0];
4662306a36Sopenharmony_ci	p[4] = dst[1];
4762306a36Sopenharmony_ci	p[5] = dst[2];
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/*
5162306a36Sopenharmony_ci * Note: including linux/compiler.h or linux/kernel.h for the macros below
5262306a36Sopenharmony_ci * conflicts with vmlinux.h include in BPF files, so we define them here.
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * Following functions are taken from kernel sources and
5562306a36Sopenharmony_ci * break aliasing rules in their original form.
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci * While kernel is compiled with -fno-strict-aliasing,
5862306a36Sopenharmony_ci * perf uses -Wstrict-aliasing=3 which makes build fail
5962306a36Sopenharmony_ci * under gcc 4.4.
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * Using extra __may_alias__ type to allow aliasing
6262306a36Sopenharmony_ci * in this case.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_citypedef __u8  __attribute__((__may_alias__))  __u8_alias_t;
6562306a36Sopenharmony_citypedef __u16 __attribute__((__may_alias__)) __u16_alias_t;
6662306a36Sopenharmony_citypedef __u32 __attribute__((__may_alias__)) __u32_alias_t;
6762306a36Sopenharmony_citypedef __u64 __attribute__((__may_alias__)) __u64_alias_t;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic __always_inline void __read_once_size(const volatile void *p, void *res, int size)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	switch (size) {
7262306a36Sopenharmony_ci	case 1: *(__u8_alias_t  *) res = *(volatile __u8_alias_t  *) p; break;
7362306a36Sopenharmony_ci	case 2: *(__u16_alias_t *) res = *(volatile __u16_alias_t *) p; break;
7462306a36Sopenharmony_ci	case 4: *(__u32_alias_t *) res = *(volatile __u32_alias_t *) p; break;
7562306a36Sopenharmony_ci	case 8: *(__u64_alias_t *) res = *(volatile __u64_alias_t *) p; break;
7662306a36Sopenharmony_ci	default:
7762306a36Sopenharmony_ci		asm volatile ("" : : : "memory");
7862306a36Sopenharmony_ci		__builtin_memcpy((void *)res, (const void *)p, size);
7962306a36Sopenharmony_ci		asm volatile ("" : : : "memory");
8062306a36Sopenharmony_ci	}
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic __always_inline void __write_once_size(volatile void *p, void *res, int size)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	switch (size) {
8662306a36Sopenharmony_ci	case 1: *(volatile  __u8_alias_t *) p = *(__u8_alias_t  *) res; break;
8762306a36Sopenharmony_ci	case 2: *(volatile __u16_alias_t *) p = *(__u16_alias_t *) res; break;
8862306a36Sopenharmony_ci	case 4: *(volatile __u32_alias_t *) p = *(__u32_alias_t *) res; break;
8962306a36Sopenharmony_ci	case 8: *(volatile __u64_alias_t *) p = *(__u64_alias_t *) res; break;
9062306a36Sopenharmony_ci	default:
9162306a36Sopenharmony_ci		asm volatile ("" : : : "memory");
9262306a36Sopenharmony_ci		__builtin_memcpy((void *)p, (const void *)res, size);
9362306a36Sopenharmony_ci		asm volatile ("" : : : "memory");
9462306a36Sopenharmony_ci	}
9562306a36Sopenharmony_ci}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci#define READ_ONCE(x)					\
9862306a36Sopenharmony_ci({							\
9962306a36Sopenharmony_ci	union { typeof(x) __val; char __c[1]; } __u =	\
10062306a36Sopenharmony_ci		{ .__c = { 0 } };			\
10162306a36Sopenharmony_ci	__read_once_size(&(x), __u.__c, sizeof(x));	\
10262306a36Sopenharmony_ci	__u.__val;					\
10362306a36Sopenharmony_ci})
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci#define WRITE_ONCE(x, val)				\
10662306a36Sopenharmony_ci({							\
10762306a36Sopenharmony_ci	union { typeof(x) __val; char __c[1]; } __u =	\
10862306a36Sopenharmony_ci		{ .__val = (val) }; 			\
10962306a36Sopenharmony_ci	__write_once_size(&(x), __u.__c, sizeof(x));	\
11062306a36Sopenharmony_ci	__u.__val;					\
11162306a36Sopenharmony_ci})
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/* Add a value using relaxed read and relaxed write. Less expensive than
11462306a36Sopenharmony_ci * fetch_add when there is no write concurrency.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_ci#define NO_TEAR_ADD(x, val) WRITE_ONCE((x), READ_ONCE(x) + (val))
11762306a36Sopenharmony_ci#define NO_TEAR_INC(x) NO_TEAR_ADD((x), 1)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci#endif
122