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