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