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