1// SPDX-License-Identifier: GPL-2.0
2/* Copyright Amazon.com Inc. or its affiliates. */
3
4#ifndef _TEST_TCP_SYNCOOKIE_H
5#define _TEST_TCP_SYNCOOKIE_H
6
7#define __packed __attribute__((__packed__))
8#define __force
9
10#define ARRAY_SIZE(arr)	(sizeof(arr) / sizeof((arr)[0]))
11
12#define swap(a, b)				\
13	do {					\
14		typeof(a) __tmp = (a);		\
15		(a) = (b);			\
16		(b) = __tmp;			\
17	} while (0)
18
19#define swap_array(a, b)				\
20	do {						\
21		typeof(a) __tmp[sizeof(a)];		\
22		__builtin_memcpy(__tmp, a, sizeof(a));	\
23		__builtin_memcpy(a, b, sizeof(a));	\
24		__builtin_memcpy(b, __tmp, sizeof(a));	\
25	} while (0)
26
27/* asm-generic/unaligned.h */
28#define __get_unaligned_t(type, ptr) ({						\
29	const struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr);	\
30	__pptr->x;								\
31})
32
33#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr))
34
35static inline u16 get_unaligned_be16(const void *p)
36{
37	return bpf_ntohs(__get_unaligned_t(__be16, p));
38}
39
40static inline u32 get_unaligned_be32(const void *p)
41{
42	return bpf_ntohl(__get_unaligned_t(__be32, p));
43}
44
45/* lib/checksum.c */
46static inline u32 from64to32(u64 x)
47{
48	/* add up 32-bit and 32-bit for 32+c bit */
49	x = (x & 0xffffffff) + (x >> 32);
50	/* add up carry.. */
51	x = (x & 0xffffffff) + (x >> 32);
52	return (u32)x;
53}
54
55static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
56					__u32 len, __u8 proto, __wsum sum)
57{
58	unsigned long long s = (__force u32)sum;
59
60	s += (__force u32)saddr;
61	s += (__force u32)daddr;
62#ifdef __BIG_ENDIAN
63	s += proto + len;
64#else
65	s += (proto + len) << 8;
66#endif
67	return (__force __wsum)from64to32(s);
68}
69
70/* asm-generic/checksum.h */
71static inline __sum16 csum_fold(__wsum csum)
72{
73	u32 sum = (__force u32)csum;
74
75	sum = (sum & 0xffff) + (sum >> 16);
76	sum = (sum & 0xffff) + (sum >> 16);
77	return (__force __sum16)~sum;
78}
79
80static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
81					__u8 proto, __wsum sum)
82{
83	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
84}
85
86/* net/ipv6/ip6_checksum.c */
87static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
88				      const struct in6_addr *daddr,
89				      __u32 len, __u8 proto, __wsum csum)
90{
91	int carry;
92	__u32 ulen;
93	__u32 uproto;
94	__u32 sum = (__force u32)csum;
95
96	sum += (__force u32)saddr->in6_u.u6_addr32[0];
97	carry = (sum < (__force u32)saddr->in6_u.u6_addr32[0]);
98	sum += carry;
99
100	sum += (__force u32)saddr->in6_u.u6_addr32[1];
101	carry = (sum < (__force u32)saddr->in6_u.u6_addr32[1]);
102	sum += carry;
103
104	sum += (__force u32)saddr->in6_u.u6_addr32[2];
105	carry = (sum < (__force u32)saddr->in6_u.u6_addr32[2]);
106	sum += carry;
107
108	sum += (__force u32)saddr->in6_u.u6_addr32[3];
109	carry = (sum < (__force u32)saddr->in6_u.u6_addr32[3]);
110	sum += carry;
111
112	sum += (__force u32)daddr->in6_u.u6_addr32[0];
113	carry = (sum < (__force u32)daddr->in6_u.u6_addr32[0]);
114	sum += carry;
115
116	sum += (__force u32)daddr->in6_u.u6_addr32[1];
117	carry = (sum < (__force u32)daddr->in6_u.u6_addr32[1]);
118	sum += carry;
119
120	sum += (__force u32)daddr->in6_u.u6_addr32[2];
121	carry = (sum < (__force u32)daddr->in6_u.u6_addr32[2]);
122	sum += carry;
123
124	sum += (__force u32)daddr->in6_u.u6_addr32[3];
125	carry = (sum < (__force u32)daddr->in6_u.u6_addr32[3]);
126	sum += carry;
127
128	ulen = (__force u32)bpf_htonl((__u32)len);
129	sum += ulen;
130	carry = (sum < ulen);
131	sum += carry;
132
133	uproto = (__force u32)bpf_htonl(proto);
134	sum += uproto;
135	carry = (sum < uproto);
136	sum += carry;
137
138	return csum_fold((__force __wsum)sum);
139}
140#endif
141