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_UTILS_H_ 29 #define _SKYWALK_TEST_UTILS_H_ 30 31 #include <skywalk/os_skywalk_private.h> 32 #include <netinet/in.h> 33 #include <netinet/ip.h> 34 #include <netinet/ip6.h> 35 #include <netinet/udp.h> 36 #include <netinet/tcp.h> 37 #include <stdbool.h> 38 #include <stdio.h> 39 40 41 typedef enum sktu_if_type { 42 SKTU_IFT_UTUN = 1, 43 SKTU_IFT_IPSEC = 2, 44 SKTU_IFT_FETH = 3, 45 } sktu_if_type_t; 46 47 #define SKTU_IFF_ENABLE_NETIF 0x00000001 // no-netif (txstart bsd interface) by default 48 #define SKTU_IFF_NO_ATTACH_FSW 0x00000002 // auto-attach fsw for netif by default 49 typedef uint32_t sktu_if_flag_t; 50 51 typedef struct sktc_nexus_handles { 52 nexus_controller_t controller; 53 uuid_t fsw_prov_uuid; 54 uuid_t fsw_nx_uuid; 55 uuid_t fsw_nx_host_attach_uuid; 56 uuid_t fsw_nx_dev_attach_uuid; 57 uuid_t netif_prov_uuid; 58 uuid_t netif_nx_uuid; 59 uuid_t netif_nx_attach_uuid; 60 char netif_ifname[IFNAMSIZ]; 61 struct in_addr netif_addr; 62 struct in_addr netif_mask; 63 struct in6_addr netif_ip6_addr; 64 uint8_t netif_ip6_prefix_len; 65 } * sktu_nexus_t; 66 67 typedef struct ip_udp_hdr { 68 struct ip ip; 69 struct udphdr udp; 70 } ip_udp_header_t; 71 72 typedef struct ip6_udp_hdr { 73 struct ip6_hdr ip6; 74 struct udphdr udp; 75 } ip6_udp_header_t; 76 77 typedef struct udp_pseudo_hdr { 78 struct in_addr src_ip; 79 struct in_addr dst_ip; 80 char zero; 81 char proto; 82 unsigned short length; 83 } udp_pseudo_hdr_t; 84 85 struct ipv4_udp_pseudo_hdr { 86 struct in_addr src_ip; 87 struct in_addr dst_ip; 88 uint8_t zero; 89 uint8_t proto; 90 unsigned short length; 91 }; 92 93 struct ipv6_udp_pseudo_hdr { 94 struct in6_addr src_ip; 95 struct in6_addr dst_ip; 96 uint32_t length; 97 uint8_t zero[3]; 98 uint8_t proto; 99 }; 100 101 typedef struct tcp_pseudo_hdr { 102 struct in_addr src_ip; 103 struct in_addr dst_ip; 104 uint8_t zero; 105 uint8_t proto; 106 unsigned short length; 107 } tcp_pseudo_hdr_t; 108 109 struct ipv4_tcp_pseudo_hdr { 110 struct in_addr src_ip; 111 struct in_addr dst_ip; 112 uint8_t zero; 113 uint8_t proto; 114 uint16_t length; 115 }; 116 117 struct ipv6_tcp_pseudo_hdr { 118 struct in6_addr src_ip; 119 struct in6_addr dst_ip; 120 uint32_t length; 121 uint8_t zero[3]; 122 uint8_t proto; 123 }; 124 125 typedef struct { 126 struct ip ip; 127 struct tcphdr tcp; 128 } ip_tcp_header_t; 129 130 typedef union { 131 ip_udp_header_t udp; 132 ip_tcp_header_t tcp; 133 } ip_udp_tcp_header_u; 134 135 #define SKTU_MAX_MTU_PAYLOAD_LEN (1500 - (sizeof(struct ip6_hdr) + sizeof(struct tcphdr) - sizeof(uint32_t))) 136 typedef struct { 137 uint32_t packet_number; 138 char data[SKTU_MAX_MTU_PAYLOAD_LEN]; 139 } my_payload, *my_payload_t; 140 141 // sktu_frame is a universal container that holds packet buffer and metadata. 142 // It's used when packet_t isn't available (like for utun fd), or isn't 143 // available yet (like before packet gets allocated from channel). 144 #define SKTU_FRAME_BUF_SIZE (16 * 1024) 145 typedef struct sktu_frame { 146 // meta data 147 uuid_t flow_uuid; 148 149 bool csum_offload; 150 uint16_t csum_flags; 151 uint16_t csum_start; 152 uint16_t csum_stuff; 153 154 size_t len; 155 156 // data 157 char bytes[SKTU_FRAME_BUF_SIZE]; 158 } *sktu_frame_t; 159 160 typedef struct { 161 channel_t chan; 162 int fd; 163 nexus_port_t port; 164 channel_ring_t rx_ring; 165 channel_ring_t tx_ring; 166 struct in_addr ip_addr; 167 struct in6_addr ip6_addr; 168 struct ether_addr mac_addr; 169 boolean_t user_packet_pool; 170 } channel_port, *channel_port_t, *sktu_channel_port_t; 171 172 struct sktu_flow; 173 174 #define CSUM_OFFLOAD true 175 #define NO_CSUM_OFFLOAD false 176 177 struct sktu_flow_ops { 178 size_t (*create_input_frames)(struct sktu_flow *flow, 179 struct sktu_frame **frames, size_t max_frames, const void *data, 180 size_t data_len); 181 182 size_t (*create_output_frames)(struct sktu_flow *flow, 183 struct sktu_frame **frames, size_t max_frames, const void *data, 184 size_t data_len, bool csum_offload); 185 }; 186 187 typedef struct sktu_flow { 188 bool is_nexus_flow; 189 190 uint8_t ipver; 191 void *src_ip; 192 void *dst_ip; 193 size_t ip_addr_len; 194 uint16_t sport; 195 uint16_t dport; 196 uint8_t ip_protocol; 197 198 size_t mtu; 199 200 // nexus flow fields 201 struct nx_flow_req nfr; 202 sktu_nexus_t nexus; 203 nexus_port_t nx_port; 204 uuid_t uuid; 205 206 // socket flow fields 207 int sock_fd; 208 209 // ops 210 struct sktu_flow_ops _flow_ops; 211 #define create_input_frames _flow_ops.create_input_frames 212 #define create_output_frames _flow_ops.create_output_frames 213 } *sktu_nexus_flow_t; 214 215 channel_t 216 sktu_channel_create_extended(const uuid_t uuid, 217 const nexus_port_t port, const ring_dir_t dir, 218 const ring_id_t rid, const channel_attr_t attr, 219 uint64_t exclusive, uint64_t monitor, 220 uint64_t txlowatunit, uint64_t txlowatval, 221 uint64_t rxlowatunit, uint64_t rxlowatval, 222 uint64_t userpacketpool, uint64_t defunctok, 223 uint64_t event_ring, uint64_t low_latency); 224 void permutefuncP(int n, int *permute, void (*func)(int, int *permute)); 225 void permutefuncH(int n, int *permute, void (*func)(int, int *permute)); 226 void permutefuncR(int n, int *permute, void (*func)(int, int *permute), int total, unsigned seed); 227 void permutefuncZ(int n, int *permute, void (*func)(int, int *permute)); 228 229 void sktc_create_flowswitch(struct sktc_nexus_handles *handles, int i); 230 void sktc_create_flowswitch_no_address(struct sktc_nexus_handles *handles, 231 uint64_t tx_slots, uint64_t rx_slots, uint64_t buf_size, uint64_t max_frags, 232 uint64_t anonymous); 233 void sktc_nexus_handles_assign_address(struct sktc_nexus_handles *handles); 234 235 void sktc_cleanup_flowswitch(struct sktc_nexus_handles *handles); 236 int sktc_bind_tcp4_flow(nexus_controller_t ncd, const uuid_t fsw, in_port_t in_port, nexus_port_t nx_port, const uuid_t flow); 237 int sktc_unbind_flow(nexus_controller_t ncd, const uuid_t fsw, const uuid_t flow); 238 239 char * skt_nfr_print(struct nx_flow_req *nfr, char *buf, size_t buf_max); 240 241 struct sktu_flow * _sktu_create_nexus_flow(sktu_nexus_t nexus, 242 nexus_port_t nx_port, uint8_t af, void *src, void *dst, uint8_t proto, 243 uint16_t sport, uint16_t dport, uint32_t flags); 244 struct sktu_flow * sktu_create_nexus_flow(sktu_nexus_t nexus, uint8_t af, 245 void *src, void *dst, uint8_t proto, uint16_t sport, uint16_t dport); 246 struct sktu_flow * sktu_create_nexus_low_latency_flow(sktu_nexus_t nexus, 247 uint8_t af, void *src, void *dst, uint8_t proto, uint16_t sport, 248 uint16_t dport); 249 struct sktu_flow * sktu_create_nexus_flow_with_nx_port(sktu_nexus_t nexus, 250 nexus_port_t nx_port, uint8_t af, void *src, void *dst, uint8_t proto, 251 uint16_t sport, uint16_t dport); 252 void _sktu_destroy_nexus_flow(struct sktu_flow *flow); 253 #define sktu_destroy_nexus_flow(f) \ 254 do { \ 255 _sktu_destroy_nexus_flow(f); \ 256 f = NULL; \ 257 } while (0) 258 int sktu_get_nexus_flow_stats(uuid_t flow_uuid, struct sk_stats_flow *sf); 259 int sktu_get_nexus_flowswitch_stats(struct sk_stats_flow_switch **sfsw, size_t *len); 260 void __fsw_stats_print(struct fsw_stats *s); 261 262 uint32_t sktc_chew_random(channel_t channel, channel_ring_t ring, sync_mode_t mode, bool dosync, uint32_t avail); 263 void sktc_pump_ring_nslots_kq(channel_t channel, channel_ring_t ring, sync_mode_t mode, bool dosync, uint64_t nslots, bool verbose); 264 void sktc_pump_ring_nslots_select(channel_t channel, channel_ring_t ring, sync_mode_t mode, bool dosync, uint64_t nslots, bool verbose); 265 void sktc_pump_ring_nslots_poll(channel_t channel, channel_ring_t ring, sync_mode_t mode, bool dosync, uint64_t nslots, bool verbose); 266 267 void sktc_raise_file_limit(int new); 268 269 int sktu_create_interface(sktu_if_type_t type, sktu_if_flag_t flags); 270 channel_t sktu_create_interface_channel(sktu_if_type_t type, int tunsock); 271 void sktu_get_interface_name(sktu_if_type_t type, int s, char name[IFNAMSIZ]); 272 273 void sktu_dump_buffer(FILE *f, const char *title, const void *p, size_t len); 274 int sysctl_buf(char *oid_name, void **buffer, size_t *len, void *newp, size_t newlen); 275 uint32_t sktu_set_inject_error_rmask(uint32_t *); 276 boolean_t sktu_check_interface_ipv4_address(char *ifname, uint32_t ipaddr); 277 int sktu_create_pfkeysock(void); 278 void sktu_create_sa(int keysock, const char ifname[IFXNAMSIZ], uint32_t spi, 279 struct in_addr *src, struct in_addr *dst); 280 281 extern unsigned short in_cksum(void * pkt, int len, int sum0); 282 extern uint16_t in_pseudo(uint32_t a, uint32_t b, uint32_t c); 283 extern uint16_t in6_pseudo(const struct in6_addr *src, const struct in6_addr *dst, uint32_t x); 284 285 extern void sktu_channel_port_init(channel_port_t ch_port, uuid_t instance, 286 nexus_port_t nx_port, bool enable_upp, bool enable_event_ring, bool low_latency); 287 288 extern void skt_channel_port_send(channel_port_t port, uuid_t flow_id, 289 int protocol, uint16_t src_port, struct in_addr dst_ip, uint16_t dst_port, 290 my_payload_t payload, int payload_length, uint32_t limit, 291 boolean_t must_complete_batch, boolean_t connect, 292 packet_svc_class_t svc_class, boolean_t csum_offload, 293 void (^packet_prehook)(packet_t p)); 294 295 extern void skt_channel_port_receive(int child, channel_port_t port, 296 uint16_t our_port, struct in_addr peer_ip, uint32_t limit, 297 uint32_t *receive_count, uint32_t *receive_index, boolean_t errors_ok, 298 uint32_t * pkts_dropped); 299 300 extern void sktu_channel_port_tx_bulk(channel_port_t port, 301 struct sktu_frame **frames, uint32_t n); 302 303 extern packet_t sktu_channel_port_frame_to_pkt(channel_port_t port, 304 struct sktu_frame *frame); 305 extern uint32_t sktu_channel_port_tx_burst_pkt(channel_port_t port, 306 packet_t *frames, uint32_t n); 307 extern uint32_t sktu_channel_port_rx_burst(channel_port_t port, 308 struct sktu_frame **frames, uint32_t n); 309 extern uint32_t sktu_channel_port_tx_burst(channel_port_t port, 310 struct sktu_frame **frames, uint32_t n); 311 312 extern uint32_t sktu_utun_fd_rx_burst(int utun_fd, struct sktu_frame **frames, 313 uint32_t n); 314 315 extern void sktu_utun_fd_tx_burst(int utun_fd, struct sktu_frame **frames, 316 uint32_t n); 317 318 extern struct sktu_frame * sktu_frame_alloc(); 319 #define sktu_frame_free(frame) \ 320 do { \ 321 free(frame); \ 322 frame = NULL; \ 323 } while (0) 324 325 extern void sktu_frames_free(struct sktu_frame **frames, size_t n); 326 327 extern size_t sktu_create_ip_frames(struct sktu_frame **frames, size_t n, 328 void *src_ip, void *dst_ip, uint8_t proto, const void *sdu, size_t sdu_len, 329 size_t mtu, uint16_t csum_flags, uint16_t csum_start, uint16_t csum_stuff); 330 extern size_t sktu_create_ip6_frames(struct sktu_frame **frames, size_t n, 331 void *src_ip, void *dst_ip, uint8_t proto, const void *sdu, size_t sdu_len, 332 size_t mtu, uint16_t csum_flags, uint16_t csum_start, uint16_t csum_stuff); 333 extern size_t sktu_create_tcp_frames(struct sktu_frame **frames, size_t n, 334 uint8_t ipver, void *src_ip, void *dst_ip, uint16_t sport, uint16_t dport, 335 const void *data, size_t data_len, size_t mtu, bool csum_offload); 336 extern size_t sktu_create_udp_frames(struct sktu_frame **frames, size_t n, 337 uint8_t ipver, void *src_ip, void *dst_ip, uint16_t sport, uint16_t dport, 338 const void *data, size_t data_len, size_t mtu, bool csum_offload); 339 340 extern int sktu_parse_ipv4_frame(struct sktu_frame *frame, void *ip_payload, 341 uint32_t *ip_payload_len); 342 extern int sktu_parse_tcp4_frame(struct sktu_frame *frame, void *tcp_payload, 343 uint32_t *tcp_payload_len); 344 extern int sktu_parse_udp4_frame(struct sktu_frame *frame, void *udp_payload, 345 uint32_t *udp_payload_len); 346 347 #endif /* _SKYWALK_TEST_UTILS_H_ */ 348