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