xref: /xnu-10063.141.1/bsd/skywalk/channel/os_channel_event.h (revision d8b80295118ef25ac3a784134bcf95cd8e88109f)
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