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