xref: /linux/tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.h (revision eb01fe7abbe2d0b38824d2a93fdb4cc3eaf2ccc1)
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 
35 static inline u16 get_unaligned_be16(const void *p)
36 {
37 	return bpf_ntohs(__get_unaligned_t(__be16, p));
38 }
39 
40 static inline u32 get_unaligned_be32(const void *p)
41 {
42 	return bpf_ntohl(__get_unaligned_t(__be32, p));
43 }
44 
45 /* lib/checksum.c */
46 static 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 
55 static 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 */
71 static 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 
80 static 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 */
87 static 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