1 /* 2 * Copyright (c) 2019-2021 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 29 #ifndef _SKYWALK_OS_CHANNEL_EVENT_H_ 30 #define _SKYWALK_OS_CHANNEL_EVENT_H_ 31 32 #ifdef PRIVATE 33 #include <stdint.h> 34 #include <mach/vm_types.h> 35 #include <skywalk/os_packet.h> 36 37 38 #define OS_CHANNEL_EVENT_HAS_PACKET_EXPIRY_STATUS (1) 39 40 typedef enum : uint32_t { 41 CHANNEL_EVENT_PACKET_TRANSMIT_STATUS = 1, 42 CHANNEL_EVENT_PACKET_TRANSMIT_EXPIRED = 2, 43 #if defined(LIBSYSCALL_INTERFACE) || defined(BSD_KERNEL_PRIVATE) 44 CHANNEL_EVENT_MIN = CHANNEL_EVENT_PACKET_TRANSMIT_STATUS, 45 CHANNEL_EVENT_MAX = CHANNEL_EVENT_PACKET_TRANSMIT_EXPIRED, 46 #endif /* LIBSYSCALL_INTERFACE || BSD_KERNEL_PRIVATE */ 47 } os_channel_event_type_t; 48 49 50 /* 51 * Subtypes of the `transmission status' channel event. 52 * 53 * NOTE: When adding new event subtypes, check whether 54 * the constant `OS_CHANNEL_EVENT_MAX_SUBEVENT_COUNT' 55 * has to be updated. 56 */ 57 typedef enum : int32_t { 58 CHANNEL_EVENT_SUCCESS = 0, 59 CHANNEL_EVENT_PKT_TRANSMIT_STATUS_ERR_FLUSH = 1, 60 CHANNEL_EVENT_PKT_TRANSMIT_STATUS_ERR_RETRY_FAILED = 2, 61 } os_channel_event_error_t; 62 63 typedef struct os_channel_event_packet_transmit_status { 64 packet_id_t packet_id; 65 int32_t packet_status; 66 } os_channel_event_packet_transmit_status_t; 67 68 /* 69 * Subtypes of the `transmission expired' channel event. 70 * 71 * NOTE: When adding new event subtypes, check whether 72 * the constant `OS_CHANNEL_EVENT_MAX_SUBEVENT_COUNT' 73 * has to be updated. 74 */ 75 typedef enum : uint16_t { 76 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ERR_NOT_EXPIRED = 0, 77 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ERR_EXPIRED_DROPPED = 1, 78 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ERR_EXPIRED_NOT_DROPPED = 2, 79 } os_channel_event_packet_tx_expiration_status_t; 80 81 typedef enum : uint16_t { 82 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_NONE = 0, 83 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_HW = 1, 84 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_DRIVER = 2, 85 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_NETIF = 3, 86 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_FSW = 4, 87 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_AQM = 5, 88 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_CHANNEL = 6, 89 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_PROTO_1 = 7, 90 CHANNEL_EVENT_PKT_TRANSMIT_EXPIRED_ORIGIN_PROTO_2 = 8, 91 } os_channel_packet_tx_expiration_origin_t; 92 93 typedef struct os_channel_event_packet_transmit_expired { 94 packet_id_t packet_id; 95 uint64_t packet_tx_expiration_deadline; 96 uint64_t packet_tx_expiration_timestamp; 97 uint16_t packet_tx_expiration_status; 98 uint16_t packet_tx_expiration_origin; 99 } os_channel_event_packet_transmit_expired_t; 100 101 /* Maximal number of distinct subevent types */ 102 #define OS_CHANNEL_EVENT_MAX_SUBEVENT_COUNT (3) 103 104 union __os_channel_event_largest_event_payload { 105 os_channel_event_packet_transmit_status_t tx; 106 os_channel_event_packet_transmit_expired_t ex; 107 }; 108 #define CHANNEL_EVENT_MAX_PAYLOAD_LEN (sizeof(union __os_channel_event_largest_event_payload)) 109 110 #ifndef KERNEL 111 /* 112 * opaque handles 113 */ 114 typedef uint64_t os_channel_event_handle_t; 115 typedef mach_vm_address_t os_channel_event_t; 116 117 struct os_channel_event_data { 118 os_channel_event_type_t event_type; 119 boolean_t event_more; 120 uint16_t event_data_length; 121 uint8_t *event_data __counted_by(event_data_length); 122 }; 123 124 #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) 125 extern int 126 os_channel_event_get_next_event(const os_channel_event_handle_t event_handle, 127 const os_channel_event_t prev_event, os_channel_event_t *event); 128 extern int os_channel_event_get_event_data(const os_channel_event_t, struct os_channel_event_data *); 129 #endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */ 130 #endif /* KERNEL */ 131 132 #if defined(LIBSYSCALL_INTERFACE) || defined(BSD_KERNEL_PRIVATE) 133 134 /* 135 * The metadata object is placed at the front of every batch of events. 136 * It is followed by `emd_nevents' instances of the `__kern_channel_event' 137 * structure (see below). 138 */ 139 struct __kern_channel_event_metadata { 140 os_channel_event_type_t emd_etype; 141 uint32_t emd_nevents; 142 }; 143 #define __KERN_CHANNEL_EVENT_OFFSET \ 144 (sizeof(struct __kern_channel_event_metadata)) 145 146 /* 147 * Individual channel events are represented by the 148 * `__kern_channel_event' structure, which comprises 149 * the event header fields, plus the opaque event payload 150 * in the `ev_data' flexible array member. 151 * 152 * CHANNEL_EVENT_MAX_PAYLOAD_LEN 153 * <----------------------------> 154 * +----------------------------+------------------------------+ 155 * |struct __kern_channel_event | event payload | 156 * +----------------------------+------------------------------+ 157 * <---------------------------------------------------------> 158 * CHANNEL_EVENT_MAX_LEN 159 */ 160 struct __kern_channel_event { 161 os_channel_event_type_t ev_type; 162 uint32_t ev_flags; 163 uint16_t _reserved; 164 uint16_t ev_dlen; 165 uint8_t ev_data[__counted_by(ev_dlen)]; 166 }; 167 168 /* event_flags */ 169 #define CHANNEL_EVENT_FLAG_MORE_EVENT 0x1 170 171 #define CHANNEL_EVENT_MAX_LEN (sizeof(struct __kern_channel_event) + \ 172 CHANNEL_EVENT_MAX_PAYLOAD_LEN) 173 174 #endif /* LIBSYSCALL_INTERFACE || BSD_KERNEL_PRIVATE */ 175 176 #if defined(BSD_KERNEL_PRIVATE) 177 __BEGIN_DECLS 178 extern errno_t kern_channel_event_transmit_status_with_packet( 179 const kern_packet_t, const ifnet_t); 180 extern void kern_channel_event_notify(struct __kern_channel_ring *); 181 extern int kern_channel_event_sync(struct __kern_channel_ring *, struct proc *, 182 uint32_t); 183 __END_DECLS 184 #endif /* BSD_KERNEL_PRIVATE */ 185 186 #ifdef KERNEL 187 __BEGIN_DECLS 188 /* Post a `packet transmit status' event to an ifnet device */ 189 extern errno_t kern_channel_event_transmit_status(const ifnet_t, 190 os_channel_event_packet_transmit_status_t *, uint32_t); 191 /* Post a `packet transmit status' event to a flowswitch */ 192 extern errno_t kern_channel_event_transmit_status_with_nexus(const uuid_t, 193 os_channel_event_packet_transmit_status_t *, uint32_t); 194 /* Post a `packet transmit expired' event to an ifnet device */ 195 extern errno_t kern_channel_event_transmit_expired(const ifnet_t, 196 os_channel_event_packet_transmit_expired_t *, uint32_t); 197 /* Post a `packet transmit expired' event to a flowswitch */ 198 extern errno_t kern_channel_event_transmit_expired_with_nexus(const uuid_t, 199 os_channel_event_packet_transmit_expired_t *, uint32_t); 200 __END_DECLS 201 #endif /* KERNEL */ 202 203 #endif /* PRIVATE */ 204 #endif /* !_SKYWALK_OS_CHANNEL_EVENT_H_ */ 205