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 _CASSERT(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 typedef enum : uint8_t {
281 SKTC_CLASSQ_DEF_C,
282 SKTC_CLASSQ_DEF_L4S,
283 SKTC_CLASSQ_LL_C,
284 SKTC_CLASSQ_LL_L4S,
285 } sktc_classq_type_t;
286 extern int sktc_set_classq_update_interval(uint64_t ns, sktc_classq_type_t type);
287 extern int sktc_reset_classq_update_interval(sktc_classq_type_t type);
288 extern int sktc_set_classq_target_qdelay(uint64_t ns, sktc_classq_type_t type);
289 extern int sktc_reset_classq_target_qdelay(sktc_classq_type_t type);
290 extern int sktc_set_classq_update_intervals(uint64_t ns);
291 extern int sktc_reset_classq_update_intervals(void);
292 extern int sktc_set_classq_target_qdelays(uint64_t ns);
293 extern int sktc_reset_classq_target_qdelays(void);
294
295 extern void sktc_set_tcp_msl(int);
296 extern void sktc_restore_tcp_msl(void);
297 extern void sktc_enable_ip_reass();
298 extern void sktc_restore_ip_reass();
299 extern bool sktc_is_ip_reass_enabled();
300 extern bool sktc_is_netagent_enabled(void);
301 extern uint64_t sktc_get_channel_attr(const channel_t chd,
302 channel_attr_type_t type);
303 extern void sktc_config_fsw_rx_agg_tcp(uint32_t);
304 extern void sktc_restore_fsw_rx_agg_tcp(void);
305 extern void sktc_enable_channel_buflet_alloc(void);
306 extern void sktc_restore_channel_buflet_alloc(void);
307 extern void skt_process_if_adv(nexus_port_t port, channel_t chan);
308
309 /*
310 * Process a channel event:
311 * - Validate that the event data len matches the event type.
312 * - Validate that a matching handler is passed, and invoke it.
313 * - If no matching handler is defined, the validation fails.
314 */
315 typedef void (^transmit_status_event_handler_t)(
316 const os_channel_event_packet_transmit_status_t *event_data);
317 typedef void (^transmit_expired_event_handler_t)(
318 const os_channel_event_packet_transmit_expired_t *event_data);
319 typedef void (^wildcard_event_handler_t)(
320 os_channel_event_type_t event_type,
321 const uint8_t *event_data,
322 size_t event_dlen);
323
324 extern void skt_process_channel_event(
325 channel_t chan, uint8_t payload_type, uint32_t stream_id,
326 transmit_status_event_handler_t transmit_status_handler,
327 transmit_expired_event_handler_t transmit_expired_handler,
328 wildcard_event_handler_t wildcard_handler);
329 extern int skt_add_arp_entry(struct in_addr host, struct ether_addr *eaddr);
330 void skt_aqstatpr(const char *interface);
331
332 struct protox {
333 void (*pr_cblocks)(uint32_t, char *, int);
334 /* control blocks printing routine */
335 void (*pr_stats)(uint32_t, char *, int);
336 /* statistics printing routine */
337 void (*pr_istats)(char *); /* per/if statistics printing routine */
338 char *pr_name; /* well-known name */
339 int pr_protocol;
340 };
341 extern struct protox protox[];
342 void skt_printproto(register struct protox *tp, char *name);
343
344 const char *BOLD;
345 const char *BOLD_RED;
346 const char *BOLD_GREEN;
347 const char *BOLD_YELLOW;
348 const char *BOLD_BLUE;
349 const char *BOLD_MAGENTA;
350 const char *BOLD_CYAN;
351 const char *BOLD_WHITE;
352 const char *NORMAL;
353
354 #endif /* _SKYWALK_TEST_COMMON_H_ */
355