xref: /xnu-12377.41.6/tests/skywalk/skywalk_test_common.h (revision bbb1b6f9e71b8cdde6e5cd6f4841f207dee3d828)
1 /*
2  * Copyright (c) 2016-2024 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 #ifndef _SKYWALK_TEST_COMMON_H_
29 #define _SKYWALK_TEST_COMMON_H_
30 
31 #include <errno.h>
32 #include <inttypes.h>
33 #include <stdio.h>
34 #include <stdbool.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <uuid/uuid.h>
38 #include <arpa/inet.h>
39 
40 #include <skywalk/os_skywalk_private.h>
41 #include <darwintest.h>
42 
43 #define SKT_LOG(_fmt, ...) do {       \
44 	int skt_errno = errno;        \
45 	T_LOG(_fmt, ##__VA_ARGS__);   \
46 	errno = skt_errno;            \
47 } while (0)
48 
49 /* expects a variable "error" */
50 #define SKTC_ASSERT_ERR(t) do {                                         \
51 	if (!(t))                                                       \
52 	        SKT_LOG("%s:%d Unexpected: error %d errno %d: %s",      \
53 	            __func__, __LINE__, error, errno, strerror(errno)); \
54 	assert(t);                                                      \
55 } while (0)
56 
57 #define SKD(_lvl, _fmt, ...)                          \
58 	do {                                          \
59 	        if (sktc_verbose >= (_lvl)) {         \
60 	                SKT_LOG(_fmt, ##__VA_ARGS__); \
61 	        }                                     \
62 	} while (0)
63 
64 #define SKD0(_fmt, ...) SKD(0, _fmt, ##__VA_ARGS__)
65 #define SKD1(_fmt, ...) SKD(1, _fmt, ##__VA_ARGS__)
66 #define SKD2(_fmt, ...) SKD(2, _fmt, ##__VA_ARGS__)
67 #define SKD3(_fmt, ...) SKD(3, _fmt, ##__VA_ARGS__)
68 
69 extern int sktc_verbose;
70 extern nexus_controller_t sktc_nexus_controller;
71 extern uuid_t sktc_provider_uuid;
72 extern uuid_t sktc_instance_uuid;
73 extern uuid_string_t sktc_instance_uuid_string;
74 
75 void sktc_setup_channel_worker(uuid_t instance_uuid, nexus_port_t channel_port,
76     ring_id_t ringid, char *key, size_t keylen, bool echo, bool defunct_ok);
77 void sktc_cleanup_channel_worker(void);
78 
79 extern void sktc_generic_upipe_nexus_init(void);
80 extern void sktc_generic_upipe_echo_init(void);
81 extern void sktc_generic_upipe_null_init(void);
82 extern void sktc_generic_upipe_fini(void);
83 #define SKTC_GENERIC_UPIPE_ARGV { NULL, NULL, NULL, sktc_instance_uuid_string, NULL}
84 
85 extern void sktc_generic_kpipe_init(void);
86 extern void sktc_generic_kpipe_fini(void);
87 #define SKTC_GENERIC_KPIPE_ARGV { NULL, NULL, NULL, sktc_instance_uuid_string, NULL}
88 
89 extern void sktc_generic_memory_init(void);
90 extern void sktc_generic_memory_fini(void);
91 
92 extern channel_slot_t send_bytes(channel_ring_t, uint32_t);
93 extern int chew_slots(channel_ring_t, uint32_t);
94 extern void set_watermark(channel_t, bool, channel_threshold_unit_t, uint32_t);
95 
96 enum timeout_behavior {
97 	TIMEOUT_FAIL,
98 	TIMEOUT_EXPECT,
99 	TIMEOUT_DONT_CARE,
100 	TIMEOUT_DISABLE
101 };
102 extern int wait_on_fd(int, int16_t, channel_t, uint32_t,
103     enum timeout_behavior);
104 
105 struct stage_ctx {
106 	uint32_t test_stage;
107 	pthread_cond_t change_cond;
108 	pthread_mutex_t change_mtx;
109 };
110 
111 extern void test_stage_init(struct stage_ctx *, uint32_t);
112 extern void test_stage_wait(struct stage_ctx *, uint32_t);
113 extern void test_stage_change(struct stage_ctx *, uint32_t);
114 extern void test_stage_destroy(struct stage_ctx *);
115 
116 struct sktc_nexus_attr {
117 	nexus_name_t    name;
118 	nexus_type_t    type;
119 	uint64_t        ntxrings;
120 	uint64_t        nrxrings;
121 	uint64_t        ntxslots;
122 	uint64_t        nrxslots;
123 	uint64_t        slotsize;
124 	uint64_t        metasize;
125 	uint64_t        anonymous;
126 	uint64_t        userchannel;
127 	uint64_t        maxfrags;
128 	uint64_t        rejectonclose;
129 };
130 
131 #define SKTC_NEXUS_ATTR_INIT()   \
132     {                            \
133 	    .name = {'\0'},      \
134 	    .type = -1,          \
135 	    .ntxrings = -1,      \
136 	    .nrxrings = -1,      \
137 	    .ntxslots = -1,      \
138 	    .nrxslots = -1,      \
139 	    .slotsize = -1,      \
140 	    .metasize = -1,      \
141 	    .anonymous = -1,     \
142 	    .userchannel = -1,   \
143 	    .maxfrags = -1,      \
144 	    .rejectonclose = -1, \
145     }
146 
147 extern void sktc_build_nexus(nexus_controller_t ncd,
148     struct sktc_nexus_attr *sktc_attr, uuid_t *providerp, uuid_t *instancep);
149 
150 extern void sktc_setup_nexus(struct sktc_nexus_attr *);
151 
152 extern void sktc_cleanup_nexus(void);
153 
154 extern int sktc_bind_nexus_key(nexus_port_t, const void *, size_t);
155 extern int sktc_unbind_nexus_key(nexus_port_t);
156 
157 #define FETH_NAME       "feth"
158 #define FETH_FORMAT     FETH_NAME "%d"
159 #define FETH0_NAME      FETH_NAME "0"
160 #define FETH1_NAME      FETH_NAME "1"
161 
162 static inline void
sktc_feth_name_for_unit(char * namebuf,size_t namebuf_size,int unit)163 sktc_feth_name_for_unit(char * namebuf, size_t namebuf_size, int unit)
164 {
165 	snprintf(namebuf, namebuf_size, FETH_FORMAT, unit);
166 }
167 
168 extern int sktc_ifnet_feth_create(int unit);
169 extern int sktc_ifnet_feth_destroy(int unit);
170 
171 extern void sktc_ifnet_feth0_create(void);
172 extern void sktc_ifnet_feth0_destroy(void);
173 extern void sktc_ifnet_feth1_create(void);
174 extern void sktc_ifnet_feth1_destroy(void);
175 
176 extern void sktc_ifnet_feth0_1_create(void);
177 extern void sktc_ifnet_feth0_1_destroy(void);
178 
179 #define FETH_FLAGS_NATIVE       0x1
180 #define FETH_FLAGS_TXSTART      0x2
181 #define FETH_FLAGS_WMM          0x4
182 #define FETH_FLAGS_MULTI_BUFLET 0x8
183 #define FETH_FLAGS_NONSHAREDPOOL 0x10
184 #define FETH_FLAGS_NONSHAREDSPLITPOOLS 0x20
185 #define FETH_FLAGS_TX_HEADROOM  0x40
186 #define FETH_FLAGS_USER_ACCESS  0x80
187 #define FETH_FLAGS_LOW_LATENCY  0x100
188 #define FETH_FLAGS_NXATTACH     0x200
189 #define FETH_FLAGS_FCS          0x400
190 #define FETH_FLAGS_TRAILER      0x800
191 #define FETH_FLAGS_LLINK        0x1000
192 #define FETH_FLAGS_MULTI_LLINK  0x2000
193 
194 extern void sktc_ifnet_feth_pair_create(uint32_t flags);
195 extern void sktc_ifnet_feth_pair_destroy(void);
196 
197 #define RD_NAME         "rd"
198 #define RD_FORMAT       RD_NAME "%d"
199 #define RD0_NAME        RD_NAME "0"
200 
201 extern void sktc_ifnet_rd_create(void);
202 extern void sktc_ifnet_rd_destroy(void);
203 
204 static inline void
sktc_rd_name_for_unit(char * namebuf,size_t namebuf_size,int unit)205 sktc_rd_name_for_unit(char * namebuf, size_t namebuf_size, int unit)
206 {
207 	snprintf(namebuf, namebuf_size, RD_FORMAT, unit);
208 }
209 
210 #define RD_IF_TYPE_ETHERNET  0x1
211 #define RD_IF_TYPE_CELLULAR  0x2
212 
213 extern int sktc_ifnet_add_addr(char *ifname, struct in_addr *addr, struct in_addr *mask, struct in_addr *broadaddr);
214 extern int sktc_ifnet_add_addr6(char *ifname, struct in6_addr *addr, struct in6_addr *dstaddr, int prefix_len, int flags);
215 extern int sktc_ifnet_del_addr(char *ifname, struct in_addr *addr);
216 extern int sktc_ifnet_del_addr6(char *ifname, struct in6_addr *addr);
217 extern int sktc_ifnet_add_scoped_default_route(char * ifname, struct in_addr ifa);
218 
219 static inline struct in_addr
sktc_make_in_addr(uint32_t s)220 sktc_make_in_addr(uint32_t s)
221 {
222 	struct in_addr  ip;
223 
224 	ip.s_addr = htonl(s);
225 	return ip;
226 }
227 
228 #define FETH0_INADDR    0x0a00fa01
229 #define FETH1_INADDR    0x0a00fb01
230 #define NOWHERE_INADDR  0x12345678
231 
232 static inline struct in_addr
sktc_feth0_in_addr(void)233 sktc_feth0_in_addr(void)
234 {
235 	return sktc_make_in_addr(FETH0_INADDR);
236 }
237 
238 static inline struct in_addr
sktc_feth1_in_addr(void)239 sktc_feth1_in_addr(void)
240 {
241 	return sktc_make_in_addr(FETH1_INADDR);
242 }
243 
244 #define RD0_INADDR    0x0a00fa01
245 
246 static inline struct in_addr
sktc_rd0_in_addr(void)247 sktc_rd0_in_addr(void)
248 {
249 	static_assert(RD0_INADDR == FETH0_INADDR);
250 	return sktc_make_in_addr(RD0_INADDR);
251 }
252 
253 static inline struct in_addr
sktc_nowhere_in_addr(void)254 sktc_nowhere_in_addr(void)
255 {
256 	return sktc_make_in_addr(NOWHERE_INADDR);
257 }
258 
259 #define FETH0_INET6_ADDR    "ff02::1:ff00:101"
260 #define FETH1_INET6_ADDR    "ff02::1:ff00:202"
261 
262 static inline void
sktc_feth0_inet6_addr(struct in6_addr * ip6_addr)263 sktc_feth0_inet6_addr(struct in6_addr *ip6_addr)
264 {
265 	assert(inet_pton(AF_INET6, FETH0_INET6_ADDR, ip6_addr) == 1);
266 }
267 
268 static inline void
sktc_feth1_inet6_addr(struct in6_addr * ip6_addr)269 sktc_feth1_inet6_addr(struct in6_addr *ip6_addr)
270 {
271 	assert(inet_pton(AF_INET6, FETH1_INET6_ADDR, ip6_addr) == 1);
272 }
273 
274 extern int sktc_get_mac_addr(const char *ifname, uint8_t *addr);
275 extern bool sktc_get_netif_nexus(const char *ifname, uuid_t netif);
276 extern bool sktc_get_flowswitch_nexus(const char *ifname, uuid_t fsw);
277 extern int sktc_ifnet_feth0_set_dequeue_stall(boolean_t enable);
278 extern int sktc_ifnet_feth1_set_dequeue_stall(boolean_t enable);
279 
280 extern int sktc_set_classq_update_interval(uint64_t ns);
281 extern int sktc_reset_classq_update_interval();
282 extern int sktc_set_classq_target_qdelay(uint64_t ns);
283 extern int sktc_reset_classq_target_qdelay();
284 extern int sktc_set_classq_update_intervals(uint64_t ns);
285 extern int sktc_reset_classq_update_intervals(void);
286 extern int sktc_set_classq_target_qdelays(uint64_t ns);
287 extern int sktc_reset_classq_target_qdelays(void);
288 
289 extern void sktc_set_tcp_msl(int);
290 extern void sktc_restore_tcp_msl(void);
291 extern void sktc_enable_ip_reass();
292 extern void sktc_restore_ip_reass();
293 extern bool sktc_is_ip_reass_enabled();
294 extern bool sktc_is_netagent_enabled(void);
295 extern uint64_t sktc_get_channel_attr(const channel_t chd,
296     channel_attr_type_t type);
297 extern void sktc_config_fsw_rx_agg_tcp(uint32_t);
298 extern void sktc_restore_fsw_rx_agg_tcp(void);
299 extern void sktc_enable_channel_buflet_alloc(void);
300 extern void sktc_restore_channel_buflet_alloc(void);
301 extern void skt_process_if_adv(nexus_port_t port, channel_t chan);
302 
303 /*
304  * Process a channel event:
305  * - Validate that the event data len matches the event type.
306  * - Validate that a matching handler is passed, and invoke it.
307  * - If no matching handler is defined, the validation fails.
308  */
309 typedef void (^transmit_status_event_handler_t)(
310 	const os_channel_event_packet_transmit_status_t *event_data);
311 typedef void (^transmit_expired_event_handler_t)(
312 	const os_channel_event_packet_transmit_expired_t *event_data);
313 typedef void (^wildcard_event_handler_t)(
314 	os_channel_event_type_t event_type,
315 	const uint8_t *event_data,
316 	size_t event_dlen);
317 
318 extern void skt_process_channel_event(
319 	channel_t chan, uint8_t payload_type, uint32_t stream_id,
320 	transmit_status_event_handler_t transmit_status_handler,
321 	transmit_expired_event_handler_t transmit_expired_handler,
322 	wildcard_event_handler_t wildcard_handler);
323 extern int skt_add_arp_entry(struct in_addr host, struct ether_addr *eaddr);
324 void skt_aqstatpr(const char *interface);
325 
326 struct protox {
327 	void    (*pr_cblocks)(uint32_t, char *, int);
328 	/* control blocks printing routine */
329 	void    (*pr_stats)(uint32_t, char *, int);
330 	/* statistics printing routine */
331 	void    (*pr_istats)(char *);   /* per/if statistics printing routine */
332 	char    *pr_name;               /* well-known name */
333 	int     pr_protocol;
334 };
335 extern struct protox protox[];
336 void skt_printproto(register struct protox *tp, char *name);
337 
338 const char *BOLD;
339 const char *BOLD_RED;
340 const char *BOLD_GREEN;
341 const char *BOLD_YELLOW;
342 const char *BOLD_BLUE;
343 const char *BOLD_MAGENTA;
344 const char *BOLD_CYAN;
345 const char *BOLD_WHITE;
346 const char *NORMAL;
347 
348 #endif /* _SKYWALK_TEST_COMMON_H_ */
349