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