xref: /xnu-8020.101.4/bsd/skywalk/nexus/os_nexus.h (revision e7776783b89a353188416a9a346c6cdb4928faad)
1 /*
2  * Copyright (c) 2015-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_NEXUS_H_
30 #define _SKYWALK_OS_NEXUS_H_
31 
32 #ifdef PRIVATE
33 
34 #include <stdint.h>
35 #include <sys/types.h>
36 #include <sys/cdefs.h>
37 #include <uuid/uuid.h>
38 #include <mach/boolean.h>
39 
40 #ifdef KERNEL_PRIVATE
41 struct ifnet_interface_advisory;
42 #endif /* KERNEL_PRIVATE */
43 
44 /*
45  * Nexus terminology and overview.  The relationship between the objects are
46  * as follows:
47  *
48  *	domain --> domain_provider --> nexus_provider --> nexus
49  *
50  * Skywalk comes with several nexus domains (types).  Each domain has one or
51  * more domain providers; the system comes with a built-in (default) domain
52  * provider per domain.  Additional domain providers may be attached, but
53  * this ability is reserved to kernel subsystems.  The domain specifies the
54  * nexus semantics, including the permitted topology, number and definition
55  * of ports, memory regions, etc.
56  *
57  * Each domain provider may have one or more nexus providers registered to it.
58  * This allows different parameters (rings, slots, buffer metadata) to be
59  * configured on a per-nexus provider basis.
60  *
61  * Nexus instances can then be allocated based on a registered nexus provider.
62  * All instances associated with a given nexus provider share the same set of
63  * parameters that are configured for that nexus provider.
64  *
65  * Channels are then opened to nexus instances.
66  */
67 
68 /*
69  * Nexus types.
70  *
71  * Userland code may only register Nexus providers against the USER_PIPE
72  * and FLOW_SWITCH types.  The rest are reserved for kernel subsystems.
73  */
74 typedef enum {
75 	NEXUS_TYPE_USER_PIPE,           /* pipe (user) */
76 	NEXUS_TYPE_KERNEL_PIPE,         /* pipe (kernel) */
77 	NEXUS_TYPE_NET_IF,              /* network interface (kernel) */
78 	NEXUS_TYPE_FLOW_SWITCH,         /* flow switch (user/kernel) */
79 #ifdef BSD_KERNEL_PRIVATE
80 	/*
81 	 * Monitor nexus isn't directly usable on its own; we just
82 	 * need a type definition here for it to act as a pseudo
83 	 * domain provider.
84 	 */
85 	NEXUS_TYPE_MONITOR,             /* monitor (user) */
86 	NEXUS_TYPE_MAX,                 /* this needs to be last */
87 	NEXUS_TYPE_UNDEFINED = -1,      /* for kernel internal use */
88 #endif /* BSD_KERNEL_PRIVATE */
89 } nexus_type_t;
90 
91 /*
92  * Nexus provider name.
93  */
94 typedef uint8_t nexus_name_t[64];
95 
96 /*
97  * Nexus instance port.
98  */
99 typedef uint32_t nexus_port_t;
100 
101 /*
102  * User pipe Nexus has at most two ports: one client and server.
103  */
104 #define NEXUS_PORT_USER_PIPE_CLIENT             0
105 #define NEXUS_PORT_USER_PIPE_SERVER             1
106 
107 /*
108  * Kernel pipe Nexus has at most one port for the client.
109  */
110 #define NEXUS_PORT_KERNEL_PIPE_CLIENT           0
111 
112 /*
113  * Network Interface Nexus can have any number of ports.
114  * Port 0 and 1 are reserved for DEV and HOST. The other ports
115  * (2 and above) can be of the types: filter, custom ethertype,
116  * or low latency.
117  */
118 #define NEXUS_PORT_NET_IF_DEV                   0
119 #define NEXUS_PORT_NET_IF_HOST                  1
120 #define NEXUS_PORT_NET_IF_CLIENT                2
121 
122 /*
123  * Flow switch has its first N ports reserved; the following is the first
124  * client usable port.  The last usable depends on the configured number
125  * of nexus ports.
126  */
127 #define NEXUS_PORT_FLOW_SWITCH_CLIENT           2
128 
129 /*
130  * Opaque handles.
131  */
132 struct nexus_controller;
133 struct nexus_attr;
134 
135 typedef struct nexus_controller         *nexus_controller_t;
136 typedef struct nexus_attr               *nexus_attr_t;
137 
138 /*
139  * Nexus attribute types.
140  */
141 typedef enum {
142 	NEXUS_ATTR_TX_RINGS,            /* (g/s) # of transmit rings */
143 	NEXUS_ATTR_RX_RINGS,            /* (g/s) # of receive rings */
144 	NEXUS_ATTR_TX_SLOTS,            /* (g/s) # of slots per transmit ring */
145 	NEXUS_ATTR_RX_SLOTS,            /* (g/s) # of slots per receive ring */
146 	NEXUS_ATTR_SLOT_BUF_SIZE,       /* (g/s) buffer per slot (bytes) */
147 	NEXUS_ATTR_SLOT_META_SIZE,      /* (g) metadata per slot (bytes) */
148 	NEXUS_ATTR_ANONYMOUS,           /* (g/s) allow anonymous clients */
149 	NEXUS_ATTR_MHINTS,              /* (g/s) memory usage hints */
150 	NEXUS_ATTR_PIPES,               /* (g/s) # of pipes */
151 	NEXUS_ATTR_EXTENSIONS,          /* (g/s) extension-specific attr */
152 	NEXUS_ATTR_IFINDEX,             /* (g) network interface index */
153 	NEXUS_ATTR_STATS_SIZE,          /* (g) statistics region size (bytes) */
154 	NEXUS_ATTR_FLOWADV_MAX,         /* (g) max flow advisory entries */
155 	NEXUS_ATTR_QMAP,                /* (g/s) queue mapping type */
156 	NEXUS_ATTR_CHECKSUM_OFFLOAD,    /* (g) partial checksum offload */
157 	NEXUS_ATTR_USER_PACKET_POOL,    /* (g) user packet pool */
158 	NEXUS_ATTR_ADV_SIZE,            /* (g) nexus advisory region size */
159 	NEXUS_ATTR_USER_CHANNEL,        /* (g/s) allow user channel open */
160 	NEXUS_ATTR_MAX_FRAGS,           /* (g/s) max fragments in a packets */
161 	/*
162 	 * (g/s) reject channel operations on nexus if the peer has closed
163 	 * the channel.
164 	 * The os channel will appear as defunct to the active peer.
165 	 */
166 	NEXUS_ATTR_REJECT_ON_CLOSE,
167 } nexus_attr_type_t;
168 
169 /*
170  * XXX: this is temporary and should be removed later.
171  */
172 #define OS_NEXUS_HAS_USER_PACKET_POOL           1
173 
174 /*
175  * Memory usage hint attributes that can be specified for NEXUS_ATTR_MHINTS
176  * These can be OR'ed to specified multiple hints
177  */
178 /* No hint, default behaviour */
179 #define NEXUS_MHINTS_NORMAL     0x0
180 /* Application expects to access the channels soon */
181 #define NEXUS_MHINTS_WILLNEED   0x1
182 /* Application expects low latency for bursty traffic */
183 #define NEXUS_MHINTS_LOWLATENCY 0x2
184 /* Application expects high usage of channel memory */
185 #define NEXUS_MHINTS_HIUSE      0x4
186 
187 /*
188  * Extension attributes.
189  */
190 typedef enum {
191 	NEXUS_EXTENSION_TYPE_MAXTYPE = 0,
192 } nexus_extension_t;
193 
194 /*
195  * Nexus queue mapping types.
196  */
197 typedef enum {
198 	NEXUS_QMAP_TYPE_INVALID = 0,    /* invalid type */
199 	NEXUS_QMAP_TYPE_DEFAULT,        /* 10:1 mapping */
200 	NEXUS_QMAP_TYPE_WMM,            /* 802.11 WMM */
201 } nexus_qmap_type_t;
202 
203 #define NEXUS_NUM_WMM_QUEUES    4       /* number of WMM access categories */
204 
205 /*
206  * Nexus buffer metadata template.
207  *
208  * Each Nexus provider implementation will define an overlay of this structure;
209  * the top of the structure always begins with this common area.  The contents
210  * of this common area, as well as the rest of the per-buffer metadata region
211  * are left to the provider to define.
212  *
213  * This structure is aligned for efficient copy and accesses.
214  */
215 typedef struct nexus_mdata {
216 	union {
217 		uuid_t          __uuid;         /* flow UUID */
218 		uint8_t         __val8[16];
219 		uint16_t        __val16[8];
220 		uint32_t        __val32[4];
221 		uint64_t        __val64[2];
222 	} __flowid_u;
223 #define nm_flowid_uuid  __flowid_u.__uuid
224 #define nm_flowid_val8  __flowid_u.__val8
225 #define nm_flowid_val16 __flowid_u.__val16
226 #define nm_flowid_val32 __flowid_u.__val32
227 #define nm_flowid_val64 __flowid_u.__val64
228 } nexus_mdata_t __attribute((aligned(8)));
229 
230 /*
231  * Nexus bind flags.
232  */
233 #define NEXUS_BIND_PID          0x1     /* bind to a process ID */
234 #define NEXUS_BIND_EXEC_UUID    0x2     /* bind to a process exec's UUID */
235 #define NEXUS_BIND_KEY          0x4     /* bind to a key blob */
236 
237 /*
238  * Maximum length of key blob (in bytes).
239  */
240 #define NEXUS_MAX_KEY_LEN       1024
241 
242 #ifndef KERNEL
243 /*
244  * User APIs.
245  */
246 #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
247 __BEGIN_DECLS
248 /*
249  * Creates a Nexus attribute object.
250  *
251  * This must be paired with a os_nexus_attr_destroy() on the handle.
252  */
253 extern nexus_attr_t os_nexus_attr_create(void);
254 
255 /*
256  * Clones a Nexus attribute object.  If source attribute is NULL
257  * it behaves just like os_nexus_attr_create();
258  *
259  * This must be paired with a os_nexus_attr_destroy() on the handle.
260  */
261 extern nexus_attr_t os_nexus_attr_clone(const nexus_attr_t attr);
262 
263 /*
264  * Sets a value for a given attribute type on a Nexus attribute object.
265  */
266 extern int os_nexus_attr_set(nexus_attr_t attr,
267     const nexus_attr_type_t type, const uint64_t value);
268 
269 /*
270  * Gets a value for a given attribute type on a Nexus attribute object.
271  */
272 extern int os_nexus_attr_get(const nexus_attr_t attr,
273     const nexus_attr_type_t type, uint64_t *value);
274 
275 /*
276  * Destroys a Nexus attribute object.
277  */
278 extern void os_nexus_attr_destroy(nexus_attr_t attr);
279 
280 /*
281  * Opens a handle to the Nexus controller.
282  *
283  * This must be paired with a os_nexus_controller_destroy() on the handle, in
284  * order to remove any remaining active providers and free resources.
285  */
286 extern nexus_controller_t os_nexus_controller_create(void);
287 
288 /*
289  * Retrieves the file descriptor associated with the Nexus controller.
290  */
291 extern int os_nexus_controller_get_fd(const nexus_controller_t ctl);
292 
293 /*
294  * Registers a Nexus provider.
295  *
296  * Anonymous Nexus provider mode implies the freedom to connect to the Nexus
297  * instance from any channel client.  Alternatively, named mode requires the
298  * Nexus provider to explicitly bind a Nexus instance port to a set of client
299  * attributes.  This mode (named) is the default behavior, and is done so to
300  * encourage Nexus providers to explicitly know about the clients that it's
301  * communicating with.  Specifying anonymous mode can be done via the Nexus
302  * attribute NEXUS_ATTR_ANONYMOUS, by setting it to a non-zero value.
303  *
304  * The client binding attributes include the process ID, the executable UUID,
305  * and/or a key blob.  Only a client possessing those will be allowed to open
306  * a channel to the Nexus instance port.
307  */
308 extern int os_nexus_controller_register_provider(const nexus_controller_t ctl,
309     const nexus_name_t name, const nexus_type_t type, const nexus_attr_t attr,
310     uuid_t *prov_uuid);
311 
312 /*
313  * Deregisters a Nexus provider.
314  */
315 extern int os_nexus_controller_deregister_provider(const nexus_controller_t ctl,
316     const uuid_t prov_uuid);
317 
318 /*
319  * Creates a Nexus instance of a registered provider.
320  */
321 extern int os_nexus_controller_alloc_provider_instance(
322 	const nexus_controller_t ctl, const uuid_t prov_uuid, uuid_t *nx_uuid);
323 
324 /*
325  * Destroys a Nexus instance.
326  */
327 extern int os_nexus_controller_free_provider_instance(
328 	const nexus_controller_t ctl, const uuid_t nx_uuid);
329 
330 /*
331  * Bind a port of a Nexus instance to one or more attributes associated with
332  * a channel client: process ID, process executable's UUID, or key blob.
333  * This is only applicable to named Nexus provider.
334  *
335  * Binding to a process ID implies allowing only a channel client with such
336  * PID to open the Nexus port.
337  *
338  * Binding to an executable UUID allows a channel client (regardless of PID
339  * or instance) with such executable UUID to open the Nexus port.  When this
340  * is requested by a provider that doesn't have the client's executable UUID,
341  * a valid client PID must be provided (with the executable UUID zeroed out)
342  * in order for the kernel to retrieve the executable UUID from the process
343  * and to use that as the bind attribute.  Else, a non-zero executable UUID
344  * can be specified (PID is ignored in this case) by the provider.
345  *
346  * Binding to a key blob allows a channel client possessing the identical
347  * key blob to open the Nexus port.  The key blob is opaque to the system,
348  * and is left to the Nexus provider to interpret and relay to its client.
349  *
350  * A Nexus provider must choose to select one or a combination of those
351  * attributes for securing access to a port of a named Nexus instance.
352  * The provider is also responsible for detecting if the client has gone
353  * away, and either to unbind the Nexus instance port indefinitely, or
354  * reissue another bind with the new client binding attributes for that
355  * same port.  This is to handle cases where the client terminates and
356  * is expected to reattach to the same port.
357  *
358  * All port bindings belonging to a Nexus instance will be automatically
359  * removed when the Nexus instance is destroyed.
360  */
361 extern int os_nexus_controller_bind_provider_instance(
362 	const nexus_controller_t ctl, const uuid_t nx_uuid, const nexus_port_t port,
363 	const pid_t pid, const uuid_t exec_uuid, const void *key,
364 	const uint32_t key_len, const uint32_t bind_flags);
365 
366 /*
367  * Unbind a previously-bound port of a Nexus instance.  This is only
368  * applicable to named Nexus provider.  A previously-bound Nexus instance
369  * port cannot be bound again until this call is issued.
370  */
371 extern int os_nexus_controller_unbind_provider_instance(
372 	const nexus_controller_t ctl, const uuid_t nx_uuid,
373 	const nexus_port_t port);
374 
375 /*
376  * Retrieves current Nexus provider attributes into the nexus_attr_t handle.
377  */
378 extern int os_nexus_controller_read_provider_attr(const nexus_controller_t ctl,
379     const uuid_t prov_uuid, nexus_attr_t attr);
380 
381 /*
382  * Destroys a Nexus controller handle.
383  */
384 extern void os_nexus_controller_destroy(nexus_controller_t ctl);
385 __END_DECLS
386 #endif  /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
387 #else /* KERNEL */
388 /*
389  * Kernel APIs.
390  */
391 #include <sys/proc.h>
392 #include <IOKit/skywalk/IOSkywalkSupport.h>
393 
394 /*
395  * Nexus domain provider name.
396  */
397 typedef uint8_t nexus_domain_provider_name_t[64];
398 
399 /*
400  * Opaque handles.
401  */
402 struct nxctl;
403 struct kern_slot_prop;
404 struct kern_nexus;
405 struct kern_nexus_provider;
406 struct kern_nexus_domain_provider;
407 struct kern_channel;
408 struct __kern_channel_ring;
409 struct __slot_desc;
410 struct __pbufpool;
411 
412 typedef struct kern_pbufpool                    *kern_pbufpool_t;
413 typedef struct kern_nexus                       *kern_nexus_t;
414 typedef struct kern_nexus_provider              *kern_nexus_provider_t;
415 typedef struct kern_nexus_domain_provider       *kern_nexus_domain_provider_t;
416 typedef struct kern_channel                     *kern_channel_t;
417 typedef struct __kern_channel_ring              *kern_channel_ring_t;
418 typedef struct __slot_desc                      *kern_channel_slot_t;
419 typedef struct netif_llink                      *kern_netif_llink_t;
420 typedef struct netif_qset                       *kern_netif_qset_t;
421 typedef struct netif_queue                      *kern_netif_queue_t;
422 
423 /*
424  * Domain provider callback routines.
425  */
426 
427 /*
428  * @typedef nxdom_prov_init_fn_t
429  * @abstract Domain provider initializer callback.
430  * @param domprov Domain provider handle.
431  * @discussion This will be called after kern_nexus_register_domain_provider().
432  * @result Non-zero result will abort the domain provider registration.
433  */
434 typedef errno_t (*nxdom_prov_init_fn_t)(kern_nexus_domain_provider_t domprov);
435 
436 /*
437  * @typedef nxdom_prov_fini_fn_t
438  * @abstract Domain provider teardown callback.
439  * @param domprov Domain provider handle.
440  * @discussion This will happen after kern_nexus_deregister_domain_provider().
441  *	A provider must not unload or free resources associated to the domain
442  *	provider instance until this callback is invoked.
443  */
444 typedef void (*nxdom_prov_fini_fn_t)(kern_nexus_domain_provider_t domprov);
445 
446 /*
447  * Domain provider init.
448  */
449 struct kern_nexus_domain_provider_init {
450 	uint32_t                nxdpi_version;          /* current version */
451 	uint32_t                nxdpi_flags;            /* for future */
452 	nxdom_prov_init_fn_t    nxdpi_init;             /* required */
453 	nxdom_prov_fini_fn_t    nxdpi_fini;             /* required */
454 };
455 
456 #define KERN_NEXUS_DOMAIN_PROVIDER_VERSION_1            1
457 #define KERN_NEXUS_DOMAIN_PROVIDER_NETIF                2
458 #define KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION      \
459 	KERN_NEXUS_DOMAIN_PROVIDER_VERSION_1
460 
461 /*
462  * Nexus provider callback routines.
463  */
464 
465 /*
466  * @typedef nxprov_pre_connect_fn_t
467  * @abstract Nexus provider channel connecting callback.
468  * @param nexus_prov Nexus provider handle.
469  * @param proc The process associated with the channel.
470  * @param nexus The nexus instance.
471  * @param channel The channel that has been created and being connected
472  *      to the nexus instances's port.
473  * @param channel_context Pointer to provider-specific context that can be
474  *      associated with the channel.  Upon a successful return, this can
475  *      later be retrieved via subsequent calls to kern_channel_get_context().
476  * @result Non-zero result will deny the channel from being connected.
477  * @discussion This is invoked when a channel is opened to the nexus port.
478  *      Upon success, client's ring and slot callbacks will be called.
479  *      The channel is not usable until the nxprov_connected_fn_t() is
480  *      invoked.  Client must refrain from channel activities until then.
481  */
482 typedef errno_t (*nxprov_pre_connect_fn_t)(kern_nexus_provider_t nexus_prov,
483     proc_t proc, kern_nexus_t nexus, nexus_port_t port, kern_channel_t channel,
484     void **channel_context);
485 
486 /*
487  * @typedef nxprov_connected_fn_t
488  * @abstract Nexus provider channel connected callback.
489  * @param nexus_prov Nexus provider handle.
490  * @param nexus The nexus instance.
491  * @param channel The channel that has been created and fully connected
492  *      to the nexus instances's port.
493  * @result Non-zero result will deny the channel from being connected.
494  * @discussion This is invoked when all ring and slot initializations have
495  *      been completed, and that the channel is ready for activities.
496  */
497 typedef errno_t (*nxprov_connected_fn_t)(kern_nexus_provider_t nexus_prov,
498     kern_nexus_t nexus, kern_channel_t channel);
499 
500 /*
501  * @typedef nxprov_pre_disconnect_fn_t
502  * @abstract Nexus provider channel disconnecting callback.
503  * @param nexus_prov Nexus provider handle.
504  * @param nexus The nexus instance.
505  * @param channel The channel that has been decommissioned.
506  * @param channel_context The context that was originally set o the channel
507  *      at the time nxprov_pre_connect_fn_t() callback was invoked.
508  * @discussion Following this call, all ring and slot finish callbacks will
509  *      be invoked.  Client must quiesce all channel activities upon getting
510  *      this callback.  The final disconnect completion will be indicated
511  *      through a call to the nxprov_disconnected_fn_t() callback.
512  */
513 typedef void (*nxprov_pre_disconnect_fn_t)(kern_nexus_provider_t nexus_prov,
514     kern_nexus_t nexus, kern_channel_t channel);
515 
516 /*
517  * @typedef nxprov_disconnected_fn_t
518  * @abstract Nexus provider channel disconnect callback.
519  * @param nexus_prov Nexus provider handle.
520  * @param nexus The nexus instance.
521  * @param channel The channel that has been decommissioned.
522  * @param channel_context The context that was originally set o the channel
523  *      at the time nxprov_pre_connect_fn_t() callback was invoked.
524  * @discussion The provider must free any resources associated with the
525  *      channel context set at nxprov_pre_connect_fn_t() time, since the channel
526  *      instance is no longer valid upon return.
527  */
528 typedef void (*nxprov_disconnected_fn_t)(kern_nexus_provider_t nexus_prov,
529     kern_nexus_t nexus, kern_channel_t channel);
530 
531 /*
532  * @typedef nxprov_ring_init_fn_t
533  * @abstract Nexus provider ring setup callback.
534  * @param nexus_prov Nexus provider handle.
535  * @param nexus The nexus instance.
536  * @param channel The channel associated with the ring.
537  * @param ring The ring that has been prepared.
538  * @param is_tx_ring True if ring is used for TX direction, otherwise RX.
539  * @param ring_id Ring identification number.
540  * @param ring_context Pointer to provider-specific context that can be
541  *      associated with the ring.  Upon a successful return, this context
542  *      can later be retrieved via subsequent calls to
543  *      kern_channel_ring_get_context().
544  * @result Non-zero result will abort the ring initialization.
545  */
546 typedef errno_t (*nxprov_ring_init_fn_t)(kern_nexus_provider_t nexus_prov,
547     kern_nexus_t nexus, kern_channel_t channel, kern_channel_ring_t ring,
548     boolean_t is_tx_ring, void **ring_context);
549 
550 /*
551  * @typedef nxprov_ring_fini_fn_t
552  * @abstract Nexus provider ring teardown callback.
553  * @param nexus_prov Nexus provider handle.
554  * @param nexus The nexus instance.
555  * @param channel The channel associated with the ring.
556  * @param ring The ring that has been decommissioned.
557  * @discussion The provider must free any resources associated with the
558  *      ring context set at nxprov_ring_init_fn_t() time, since the ring is
559  *      no longer valid upon return.  This call will be issued after all
560  *      slots belonging to the ring has been decommisioned, via
561  *      nxprov_slot_fini_fn_t().
562  */
563 typedef void (*nxprov_ring_fini_fn_t)(kern_nexus_provider_t nexus_prov,
564     kern_nexus_t nexus, kern_channel_ring_t ring);
565 
566 /*
567  * @typedef nxprov_slot_init_fn_t
568  * @abstract Nexus provider channel slot setup callback.
569  * @param nexus_prov Nexus provider handle.
570  * @param nexus The nexus instance.
571  * @param ring The ring associated with the slot.
572  * @param slot The slot that has been prepared.
573  * @param slot_index The index of the slot in the ring.
574  * @param slot_prop_addr This has been deprecated; callee must set to NULL.
575  * @param slot_context Pointer to provider-specific context that can be
576  *      associated with the slot in the given ring.  Upon a successful return,
577  *      this context can later be retrieved via subsequent calls to
578  *      kern_channel_slot_get_context().
579  * @result Non-zero result will abort the slot initialization.
580  */
581 typedef errno_t (*nxprov_slot_init_fn_t)(kern_nexus_provider_t nexus_prov,
582     kern_nexus_t nexus, kern_channel_ring_t ring, kern_channel_slot_t slot,
583     uint32_t slot_index, struct kern_slot_prop **slot_prop_addr,
584     void **slot_context);
585 
586 /*
587  * @typedef nxprov_slot_fini_fn_t
588  * @abstract Nexus provider channel slot teardown callback.
589  * @param nexus_prov Nexus provider handle.
590  * @param nexus The nexus instance.
591  * @param ring The ring associated with the slot.
592  * @param slot The slot that has been decommissioned.
593  * @param slot_index The index of the slot in the ring.
594  * @discussion The provider must free any resources associated with the
595  *      slot context set at nxprov_slot_init_fn_t() time, since the slot
596  *      instance is no longer valid upon return.
597  */
598 typedef void (*nxprov_slot_fini_fn_t)(kern_nexus_provider_t nexus_prov,
599     kern_nexus_t nexus, kern_channel_ring_t ring, kern_channel_slot_t slot,
600     uint32_t slot_index);
601 
602 /*
603  * @typedef nxprov_sync_tx_fn_t
604  * @abstract Nexus provider channel sync (TX) callback.
605  * @param nexus_prov Nexus provider handle.
606  * @param nexus The nexus instance.
607  * @param ring The ring associated with the slot.
608  * @param flags See KERN_NEXUS_SYNCF flags.
609  */
610 typedef errno_t (*nxprov_sync_tx_fn_t)(kern_nexus_provider_t nexus_prov,
611     kern_nexus_t nexus, kern_channel_ring_t ring, uint32_t flags);
612 
613 /*
614  * @typedef nxprov_sync_rx_fn_t
615  * @abstract Nexus provider channel sync (RX) callback.
616  * @param nexus_prov Nexus provider handle.
617  * @param nexus The nexus instance.
618  * @param ring The ring associated with the slot.
619  * @param flags See KERN_NEXUS_SYNCF flags.
620  */
621 typedef errno_t (*nxprov_sync_rx_fn_t)(kern_nexus_provider_t nexus_prov,
622     kern_nexus_t nexus, kern_channel_ring_t ring, uint32_t flags);
623 
624 /*
625  * Valid flags for {tx,rx}sync callbacks.
626  */
627 #define KERN_NEXUS_SYNCF_COMMIT         0x1     /* force reclaim/update */
628 
629 /*
630  * @typedef nxprov_tx_doorbell_fn_t
631  * @abstract Nexus provider TX doorbell callback, required for netif.
632  * @param nexus_prov Nexus provider handle.
633  * @param nexus The nexus instance.
634  * @param ring The ring associated with the doorbell.
635  * @param flags See KERN_NEXUS_TXDOORBELLF flags.
636  */
637 typedef errno_t (*nxprov_tx_doorbell_fn_t)(kern_nexus_provider_t nexus_prov,
638     kern_nexus_t nexus, kern_channel_ring_t ring, uint32_t flags);
639 
640 /*
641  * Valid flags for tx doorbell callback.
642  */
643 /* call kern_channel_tx_refill() in async context */
644 #define KERN_NEXUS_TXDOORBELLF_ASYNC_REFILL     0x1
645 
646 /*
647  * @typedef nxprov_sync_packets_fn_t
648  * @abstract Nexus provider get packets callback, required for netif.
649  * @param nexus_prov Nexus provider handle.
650  * @param nexus The nexus instance.
651  * @param ring The device ring.
652  * @param packets Array of packet chains
653  * @param count:
654  *      RX: caller sets this to the array size. on return, this count
655  *          is set to actual number of packets returned.
656  *      TX: not implemented
657  * @param flags none for now.
658  */
659 typedef errno_t (*nxprov_sync_packets_fn_t)(kern_nexus_provider_t nexus_prov,
660     kern_nexus_t nexus, kern_channel_ring_t ring, uint64_t packets[],
661     uint32_t *count, uint32_t flags);
662 
663 
664 /*
665  * @typedef nxprov_capab_config_fn_t
666  * @abstract Nexus provider capabilities configuration callback,
667  *           required for netif.
668  * @param nexus_prov Nexus provider handle.
669  * @param nexus The nexus instance.
670  * @param capab The capability being queried.
671  * @param contents Structure describing the capability.
672  * @param len Input: length of buffer for holding contents.
673  *            Output: length of actual size of contents.
674  */
675 typedef enum {
676 	/* periodic interface advisory notifications */
677 	KERN_NEXUS_CAPAB_INTERFACE_ADVISORY = 1,
678 } kern_nexus_capab_t;
679 
680 typedef errno_t (*nxprov_capab_config_fn_t)(kern_nexus_provider_t nexus_prov,
681     kern_nexus_t nexus, kern_nexus_capab_t capab, void *contents,
682     uint32_t *len);
683 
684 /*
685  * struct kern_nexus_capab_interface_advisory
686  * @abstract Interface advisory capability configuration callback.
687  * @param kncia_version Version of the capability structure.
688  * @param kncia_notify The notification interface provided by kernel.
689  * @param kncia_config The configuration interface provided by nexus provider.
690  */
691 #define KERN_NEXUS_CAPAB_INTERFACE_ADVISORY_VERSION_1 1
692 typedef errno_t (*kern_nexus_capab_interface_advisory_config_fn_t)(
693 	void *provider_context, bool enable);
694 typedef errno_t (*kern_nexus_capab_interface_advisory_notify_fn_t)(
695 	void *kern_context, const struct ifnet_interface_advisory *adv_info);
696 struct kern_nexus_capab_interface_advisory {
697 	uint32_t kncia_version;
698 	void * const kncia_kern_context;
699 	void *kncia_provider_context;
700 	const kern_nexus_capab_interface_advisory_notify_fn_t kncia_notify;
701 	kern_nexus_capab_interface_advisory_config_fn_t kncia_config;
702 };
703 
704 /*
705  * Nexus provider init (version 1)
706  */
707 struct kern_nexus_provider_init {
708 	uint32_t                nxpi_version;           /* current version */
709 	uint32_t                nxpi_flags;             /* see NXPIF_* */
710 	nxprov_pre_connect_fn_t nxpi_pre_connect;       /* required */
711 	nxprov_connected_fn_t   nxpi_connected;         /* required */
712 	nxprov_pre_disconnect_fn_t nxpi_pre_disconnect; /* required */
713 	nxprov_disconnected_fn_t nxpi_disconnected;     /* required */
714 	nxprov_ring_init_fn_t   nxpi_ring_init;         /* optional */
715 	nxprov_ring_fini_fn_t   nxpi_ring_fini;         /* optional */
716 	nxprov_slot_init_fn_t   nxpi_slot_init;         /* optional */
717 	nxprov_slot_fini_fn_t   nxpi_slot_fini;         /* optional */
718 	nxprov_sync_tx_fn_t     nxpi_sync_tx;           /* required */
719 	nxprov_sync_rx_fn_t     nxpi_sync_rx;           /* required */
720 	nxprov_tx_doorbell_fn_t nxpi_tx_doorbell;       /* required (netif) */
721 	nxprov_sync_packets_fn_t nxpi_rx_sync_packets;  /* optional (netif) */
722 	nxprov_sync_packets_fn_t nxpi_tx_sync_packets;  /* optional (netif) */
723 	nxprov_capab_config_fn_t nxpi_config_capab;     /* optional (netif) */
724 };
725 
726 /*
727  * @typedef nxprov_qset_init_fn_t
728  * @abstract Nexus provider netif qset setup callback.
729  * @param nexus_prov Nexus provider handle.
730  * @param nexus The nexus instance.
731  * @param llink_ctx The context associated with the logical link owning this
732  *                  qset (provider owned). Retreived during logical link
733  *                  creation.
734  * @param qset_idx The index of the qset within this logical link.
735  * @param qset_id  The encoded id of the qset. Meant to be propagated to userspace
736  *                 and passed down later during qset selection.
737  * @param qset The netif qset to be initialized (xnu owned). Meant to be
738  *             used for upcalls to xnu.
739  * @param qset_ctx The qset context (provider owned output arg). Meant to
740  *                 be used for downcalls to the provider involving this qset.
741  * @result Non-zero result will abort the queue initialization.
742  */
743 typedef errno_t (*nxprov_qset_init_fn_t)(kern_nexus_provider_t nexus_prov,
744     kern_nexus_t nexus, void *llink_ctx, uint8_t qset_idx,
745     uint64_t qset_id, kern_netif_qset_t qset, void **qset_ctx);
746 
747 /*
748  * @typedef nxprov_qset_fini_fn_t
749  * @abstract Nexus provider netif qset teardown callback.
750  * @param nexus_prov Nexus provider handle.
751  * @param nexus The nexus instance.
752  * @param qset_ctx The qset context retrieved from nxprov_qset_init_fn_t
753  *                 (provider owned).
754  * @discussion The provider must free any resources associated with the
755  *      qset context set at nxprov_qset_init_fn_t() time, since the qset is
756  *      no longer valid upon return.
757  */
758 typedef void (*nxprov_qset_fini_fn_t)(kern_nexus_provider_t nexus_prov,
759     kern_nexus_t nexus, void *qset_ctx);
760 
761 /*
762  * @typedef nxprov_queue_init_fn_t
763  * @abstract Nexus provider netif queue setup callback.
764  * @param nexus_prov Nexus provider handle.
765  * @param nexus The nexus instance.
766  * @param qset_ctx The context associated with the qset owning this queue
767  *                 (provider owned). Retreived from nxprov_qset_init_fn_t.
768  * @param qidx The index of the queue within this qset.
769  * @param queue The netif queue to be initialized (xnu owned). Meant to be
770  *              used for upcalls to xnu.
771  * @param tx True if the queue is used for TX direction, otherwise RX.
772  * @param queue_ctx The queue context (provider owned output arg). Meant to
773  *                  be used for downcalls to the provider involving this queue.
774  * @result Non-zero result will abort the queue initialization.
775  */
776 typedef errno_t (*nxprov_queue_init_fn_t)(kern_nexus_provider_t nexus_prov,
777     kern_nexus_t nexus, void *qset_ctx, uint8_t qidx, bool tx,
778     kern_netif_queue_t queue, void **queue_ctx);
779 
780 /*
781  * @typedef nxprov_queue_fini_fn_t
782  * @abstract Nexus provider netif queue teardown callback.
783  * @param nexus_prov Nexus provider handle.
784  * @param nexus The nexus instance.
785  * @param queue_ctx The queue context retrieved from nxprov_queue_init_fn_t
786  *                  (provider owned).
787  * @discussion The provider must free any resources associated with the
788  *      queue context set at nxprov_queue_init_fn_t() time, since the queue is
789  *      no longer valid upon return.
790  */
791 typedef void (*nxprov_queue_fini_fn_t)(kern_nexus_provider_t nexus_prov,
792     kern_nexus_t nexus, void *queue_ctx);
793 
794 /*
795  * @typedef nxprov_tx_qset_notify_fn_t
796  * @abstract Nexus provider TX notify callback, required for netif.
797  * @param nexus_prov Nexus provider handle.
798  * @param nexus The nexus instance.
799  * @param qset_ctx The qset_ctx owned by the qset to be notified (provider
800  *                 owned). Retrieved from nxprov_qset_init_fn_t.
801  * @param flags unused for now.
802  */
803 typedef errno_t (*nxprov_tx_qset_notify_fn_t)(kern_nexus_provider_t
804     nexus_prov, kern_nexus_t nexus, void *qset_ctx, uint32_t flags);
805 
806 /*
807  * Nexus provider initialization parameters specific to netif (version 2)
808  */
809 struct kern_nexus_netif_provider_init {
810 	uint32_t                      nxnpi_version;       /* current version */
811 	uint32_t                      nxnpi_flags;             /* see NXPIF_* */
812 	nxprov_pre_connect_fn_t       nxnpi_pre_connect;       /* required */
813 	nxprov_connected_fn_t         nxnpi_connected;         /* required */
814 	nxprov_pre_disconnect_fn_t    nxnpi_pre_disconnect;    /* required */
815 	nxprov_disconnected_fn_t      nxnpi_disconnected;      /* required */
816 	nxprov_qset_init_fn_t         nxnpi_qset_init;         /* required */
817 	nxprov_qset_fini_fn_t         nxnpi_qset_fini;         /* required */
818 	nxprov_queue_init_fn_t        nxnpi_queue_init;        /* required */
819 	nxprov_queue_fini_fn_t        nxnpi_queue_fini;        /* required */
820 	nxprov_tx_qset_notify_fn_t    nxnpi_tx_qset_notify;    /* required */
821 	nxprov_capab_config_fn_t      nxnpi_config_capab;      /* required */
822 };
823 
824 #define KERN_NEXUS_PROVIDER_VERSION_1         1
825 #define KERN_NEXUS_PROVIDER_VERSION_NETIF     2 /* specific to netif */
826 #define KERN_NEXUS_PROVIDER_CURRENT_VERSION   KERN_NEXUS_PROVIDER_VERSION_1
827 
828 /*
829  * Valid values for nxpi_flags.
830  */
831 #define NXPIF_VIRTUAL_DEVICE    0x1     /* device is virtual (no DMA) */
832 #define NXPIF_MONOLITHIC        0x4     /* single segment mode */
833 #define NXPIF_INHIBIT_CACHE     0x8     /* caching-inhibited */
834 
835 /*
836  * Network Interface Nexus instance callback routines.
837  */
838 
839 /*
840  * @typedef nxnet_prepare_fn_t
841  * @abstract Network Interface nexus instance preparer callback.
842  * @param nexus The nexus instance.
843  * @param ifp The interface associated with the nexus instance.
844  * @discussion The prepare callback routine specified by nxneti_prepare will
845  *      be invoked on a newly-allocated interface that is not yet attached.
846  *      A non-zero value returned by the callback routine will abort the
847  *      operation; otherwise, the interface will then be associated with
848  *      the nexus prior to being fully attached to the system.
849  */
850 typedef errno_t (*nxnet_prepare_fn_t)(kern_nexus_t nexus, ifnet_t ifp);
851 
852 /*
853  * Nexus (Non-Networking) instance init.
854  *
855  * If supplied, packet buffer pool must have been created as KBIF_QUANTUM.
856  */
857 struct kern_nexus_init {
858 	uint32_t                nxi_version;            /* current version */
859 	uint32_t                nxi_flags;              /* see NXIF_* */
860 	kern_pbufpool_t         nxi_tx_pbufpool;        /* optional */
861 	kern_pbufpool_t         nxi_rx_pbufpool;        /* optional */
862 };
863 
864 #define KERN_NEXUS_VERSION_1                    1
865 #define KERN_NEXUS_CURRENT_VERSION              KERN_NEXUS_VERSION_1
866 
867 /*
868  * Network Interface Nexus instance init.
869  *
870  * If supplied, packet buffer pool must NOT have been created as KBIF_QUANTUM.
871  * packet buffer pool is a required parameter if the nexus provider is
872  * operating in netif logical link mode.
873  */
874 struct kern_nexus_net_init {
875 	uint32_t                nxneti_version;         /* current version */
876 	uint32_t                nxneti_flags;           /* see NXNETF_* */
877 	struct ifnet_init_eparams *nxneti_eparams;      /* required */
878 	struct sockaddr_dl      *nxneti_lladdr;         /* optional */
879 	nxnet_prepare_fn_t      nxneti_prepare;         /* optional */
880 	kern_pbufpool_t         nxneti_tx_pbufpool;     /* optional */
881 	kern_pbufpool_t         nxneti_rx_pbufpool;     /* optional */
882 	struct kern_nexus_netif_llink_init *nxneti_llink; /* optional */
883 };
884 
885 #define KERN_NEXUS_NET_VERSION_1                1
886 #define KERN_NEXUS_NET_VERSION_2                2
887 #define KERN_NEXUS_NET_CURRENT_VERSION          KERN_NEXUS_NET_VERSION_1
888 
889 struct kern_nexus_netif_llink_qset_init {
890 	uint32_t    nlqi_flags;
891 	uint8_t     nlqi_num_rxqs;
892 	uint8_t     nlqi_num_txqs;
893 };
894 
895 /*
896  * nxnetllq_flags values.
897  */
898 /* default qset of the logical link */
899 #define KERN_NEXUS_NET_LLINK_QSET_DEFAULT        0x1
900 /* qset needs AQM */
901 #define KERN_NEXUS_NET_LLINK_QSET_AQM            0x2
902 /* qset is low latency */
903 #define KERN_NEXUS_NET_LLINK_QSET_LOW_LATENCY    0x4
904 /* qset in WMM mode */
905 #define KERN_NEXUS_NET_LLINK_QSET_WMM_MODE       0x8
906 
907 typedef uint64_t kern_nexus_netif_llink_id_t;
908 
909 struct kern_nexus_netif_llink_init {
910 	uint32_t        nli_flags;
911 	uint8_t         nli_num_qsets;
912 	void            *nli_ctx;
913 	kern_nexus_netif_llink_id_t nli_link_id;
914 	struct kern_nexus_netif_llink_qset_init *nli_qsets;
915 };
916 
917 /*
918  * nxnetll_flags values.
919  */
920 /* default logical link */
921 #define KERN_NEXUS_NET_LLINK_DEFAULT        0x1
922 
923 __BEGIN_DECLS
924 /*
925  * Attributes.
926  */
927 extern errno_t kern_nexus_attr_create(nexus_attr_t *);
928 extern errno_t kern_nexus_attr_clone(const nexus_attr_t attr,
929     nexus_attr_t *);
930 extern errno_t kern_nexus_attr_set(nexus_attr_t attr,
931     const nexus_attr_type_t type, const uint64_t value);
932 extern errno_t kern_nexus_attr_get(const nexus_attr_t attr,
933     const nexus_attr_type_t type, uint64_t *value);
934 extern void kern_nexus_attr_destroy(nexus_attr_t attr);
935 
936 /*
937  * Domain provider.
938  *
939  * At present we allow only NEXUS_TYPE_{KERNEL_PIPE,NET_IF} external
940  * providers to be registered.
941  */
942 extern errno_t kern_nexus_register_domain_provider(const nexus_type_t type,
943     const nexus_domain_provider_name_t name,
944     const struct kern_nexus_domain_provider_init *init,
945     const uint32_t init_len, uuid_t *dom_prov_uuid);
946 extern errno_t kern_nexus_deregister_domain_provider(
947 	const uuid_t dom_prov_uuid);
948 extern errno_t kern_nexus_get_default_domain_provider(const nexus_type_t type,
949     uuid_t *dom_prov_uuid);
950 
951 /*
952  * Nexus provider.
953  */
954 typedef void (*nexus_ctx_release_fn_t)(void *const ctx);
955 
956 extern errno_t kern_nexus_controller_create(nexus_controller_t *ctl);
957 extern errno_t kern_nexus_controller_register_provider(
958 	const nexus_controller_t ctl, const uuid_t dom_prov_uuid,
959 	const nexus_name_t, const struct kern_nexus_provider_init *init,
960 	const uint32_t init_len, const nexus_attr_t nxa, uuid_t *nx_prov_uuid);
961 extern errno_t kern_nexus_controller_deregister_provider(
962 	const nexus_controller_t ctl, const uuid_t nx_prov_uuid);
963 extern errno_t kern_nexus_controller_alloc_provider_instance(
964 	const nexus_controller_t ctl, const uuid_t nx_prov_uuid,
965 	const void *nexus_context, nexus_ctx_release_fn_t nexus_context_release,
966 	uuid_t *nx_uuid, const struct kern_nexus_init *init);
967 extern errno_t kern_nexus_controller_alloc_net_provider_instance(
968 	const nexus_controller_t ctl, const uuid_t nx_prov_uuid,
969 	const void *nexus_context, nexus_ctx_release_fn_t nexus_context_release,
970 	uuid_t *nx_uuid, const struct kern_nexus_net_init *init, ifnet_t *);
971 extern errno_t kern_nexus_controller_free_provider_instance(
972 	const nexus_controller_t ctl, const uuid_t nx_uuid);
973 extern errno_t kern_nexus_controller_bind_provider_instance(
974 	const nexus_controller_t ctl, const uuid_t nx_uuid, nexus_port_t *port,
975 	const pid_t pid, const uuid_t exec_uuid, const void *key,
976 	const uint32_t key_len, const uint32_t bind_flags);
977 extern errno_t kern_nexus_controller_unbind_provider_instance(
978 	const nexus_controller_t ctl, const uuid_t nx_uuid,
979 	const nexus_port_t port);
980 extern errno_t kern_nexus_controller_read_provider_attr(
981 	const nexus_controller_t ctl, const uuid_t nx_prov_uuid,
982 	nexus_attr_t attr);
983 extern void kern_nexus_controller_destroy(nexus_controller_t ctl);
984 extern void kern_nexus_stop(const kern_nexus_t nx);
985 
986 /*
987  * Netif specific.
988  */
989 extern errno_t kern_netif_queue_tx_dequeue(kern_netif_queue_t, uint32_t,
990     uint32_t, boolean_t *, uint64_t *);
991 
992 #define KERN_NETIF_QUEUE_RX_ENQUEUE_FLAG_FLUSH     0x0001
993 extern void kern_netif_queue_rx_enqueue(kern_netif_queue_t, uint64_t,
994     uint32_t, uint32_t);
995 
996 extern errno_t kern_nexus_netif_llink_add(struct kern_nexus *,
997     struct kern_nexus_netif_llink_init *);
998 
999 extern errno_t kern_nexus_netif_llink_remove(struct kern_nexus *,
1000     kern_nexus_netif_llink_id_t);
1001 
1002 /*
1003  * Misc.
1004  */
1005 extern void *kern_nexus_get_context(const kern_nexus_t nexus);
1006 extern errno_t kern_nexus_get_pbufpool(const kern_nexus_t nexus,
1007     kern_pbufpool_t *tx_pbufpool, kern_pbufpool_t *rx_pbufpool);
1008 
1009 /*
1010  * Non-exported KPIs.
1011  */
1012 extern int kern_nexus_ifattach(nexus_controller_t, const uuid_t nx_uuid,
1013     struct ifnet *ifp, const uuid_t nx_attachee, boolean_t host,
1014     uuid_t *nx_if_uuid);
1015 extern int kern_nexus_ifdetach(const nexus_controller_t ctl,
1016     const uuid_t nx_uuid, const uuid_t nx_if_uuid);
1017 extern int kern_nexus_get_netif_instance(struct ifnet *ifp, uuid_t nx_uuid);
1018 extern int kern_nexus_get_flowswitch_instance(struct ifnet *ifp,
1019     uuid_t nx_uuid);
1020 extern nexus_controller_t kern_nexus_shared_controller(void);
1021 extern void kern_nexus_register_netagents(void);
1022 extern void kern_nexus_deregister_netagents(void);
1023 extern void kern_nexus_update_netagents(void);
1024 extern int kern_nexus_interface_add_netagent(struct ifnet *);
1025 extern int kern_nexus_interface_remove_netagent(struct ifnet *);
1026 extern int kern_nexus_set_netif_input_tbr_rate(struct ifnet *ifp,
1027     uint64_t rate);
1028 extern int kern_nexus_set_if_netem_params(
1029 	const nexus_controller_t ctl, const uuid_t nx_uuid,
1030 	void *data, size_t data_len);
1031 extern int kern_nexus_flow_add(const nexus_controller_t ncd,
1032     const uuid_t nx_uuid, void *data, size_t data_len);
1033 extern int kern_nexus_flow_del(const nexus_controller_t ncd,
1034     const uuid_t nx_uuid, void *data, size_t data_len);
1035 
1036 __END_DECLS
1037 #endif /* KERNEL */
1038 #endif /* PRIVATE */
1039 #endif /* !_SKYWALK_OS_NEXUS_H_ */
1040