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
41struct ifnet_interface_advisory;
42#endif /* KERNEL_PRIVATE */
43
44struct ifnet_traffic_descriptor_common;
45struct 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 */
77typedef 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 */
97typedef uint8_t nexus_name_t[64];
98
99/*
100 * Nexus instance port.
101 */
102typedef 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 */
135struct nexus_controller;
136struct nexus_attr;
137
138typedef struct nexus_controller *nexus_controller_t;
139typedef struct nexus_attr *nexus_attr_t;
140
141/*
142 * Nexus attribute types.
143 */
144typedef 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 */
194typedef enum {
195 NEXUS_EXTENSION_TYPE_MAXTYPE = 0,
196} nexus_extension_t;
197
198/*
199 * Nexus queue mapping types.
200 */
201typedef 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 */
219typedef 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 */
257extern 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 */
265extern 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 */
270extern 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 */
276extern 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 */
282extern 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 */
290extern nexus_controller_t os_nexus_controller_create(void);
291
292/*
293 * Retrieves the file descriptor associated with the Nexus controller.
294 */
295extern 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 */
312extern 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 */
319extern 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 */
325extern 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 */
331extern 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 */
365extern 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 */
375extern 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 */
382extern 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
391extern 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
396extern int os_nexus_controller_remove_traffic_rule(const nexus_controller_t ctl,
397 const uuid_t rule_uuid);
398
399struct 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. */
408typedef boolean_t (nexus_traffic_rule_iterator_t)(void *,
409 const struct nexus_traffic_rule_info *);
410
411extern 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 */
417extern 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 */
430typedef uint8_t nexus_domain_provider_name_t[64];
431
432/*
433 * Opaque handles.
434 */
435struct nxctl;
436struct kern_slot_prop;
437struct kern_nexus;
438struct kern_nexus_provider;
439struct kern_nexus_domain_provider;
440struct kern_channel;
441struct __kern_channel_ring;
442struct __slot_desc;
443struct __pbufpool;
444
445typedef struct kern_pbufpool *kern_pbufpool_t;
446typedef struct kern_nexus *kern_nexus_t;
447typedef struct kern_nexus_provider *kern_nexus_provider_t;
448typedef struct kern_nexus_domain_provider *kern_nexus_domain_provider_t;
449typedef struct kern_channel *kern_channel_t;
450typedef struct __kern_channel_ring *kern_channel_ring_t;
451typedef struct __slot_desc *kern_channel_slot_t;
452typedef struct netif_llink *kern_netif_llink_t;
453typedef struct netif_qset *kern_netif_qset_t;
454typedef 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 */
467typedef 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 */
477typedef void (*nxdom_prov_fini_fn_t)(kern_nexus_domain_provider_t domprov);
478
479/*
480 * Domain provider init.
481 */
482struct 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 */
515typedef 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 */
530typedef 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 */
546typedef 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 */
561typedef 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 */
579typedef 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 */
596typedef 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 */
614typedef 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 */
631typedef 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 */
643typedef 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 */
654typedef 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 */
670typedef 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 */
692typedef 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 */
708typedef 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
715typedef 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
727typedef errno_t (*kern_nexus_capab_interface_advisory_config_fn_t)(
728 void *provider_context, bool enable);
729typedef errno_t (*kern_nexus_capab_interface_advisory_notify_fn_t)(
730 void *kern_context, const struct ifnet_interface_advisory *adv_info);
731struct 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
747typedef 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);
750struct 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 */
759struct 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 */
795typedef 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 */
810typedef 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 */
828typedef 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 */
843typedef 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 */
855typedef 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 */
861struct 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 */
902typedef 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 */
909struct 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 */
926struct 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
941struct 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
959typedef uint64_t kern_nexus_netif_llink_id_t;
960
961struct 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 */
979extern errno_t kern_nexus_attr_create(nexus_attr_t *);
980extern errno_t kern_nexus_attr_clone(const nexus_attr_t attr,
981 nexus_attr_t *);
982extern errno_t kern_nexus_attr_set(nexus_attr_t attr,
983 const nexus_attr_type_t type, const uint64_t value);
984extern errno_t kern_nexus_attr_get(const nexus_attr_t attr,
985 const nexus_attr_type_t type, uint64_t *value);
986extern 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 */
994extern 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);
998extern errno_t kern_nexus_deregister_domain_provider(
999 const uuid_t dom_prov_uuid);
1000extern 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 */
1006typedef void (*nexus_ctx_release_fn_t)(void *const ctx);
1007
1008extern errno_t kern_nexus_controller_create(nexus_controller_t *ctl);
1009extern 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);
1013extern errno_t kern_nexus_controller_deregister_provider(
1014 const nexus_controller_t ctl, const uuid_t nx_prov_uuid);
1015extern 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);
1019extern 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 *);
1023extern errno_t kern_nexus_controller_free_provider_instance(
1024 const nexus_controller_t ctl, const uuid_t nx_uuid);
1025extern 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);
1029extern 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);
1032extern 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);
1035extern void kern_nexus_controller_destroy(nexus_controller_t ctl);
1036extern void kern_nexus_stop(const kern_nexus_t nx);
1037
1038/*
1039 * Netif specific.
1040 */
1041extern 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
1045extern void kern_netif_queue_rx_enqueue(kern_netif_queue_t, uint64_t,
1046 uint32_t, uint32_t);
1047
1048extern errno_t kern_nexus_netif_llink_add(struct kern_nexus *,
1049 struct kern_nexus_netif_llink_init *);
1050
1051extern errno_t kern_nexus_netif_llink_remove(struct kern_nexus *,
1052 kern_nexus_netif_llink_id_t);
1053
1054extern errno_t kern_netif_qset_tx_queue_len(kern_netif_qset_t,
1055 uint32_t, uint32_t *, uint32_t *);
1056
1057extern void kern_netif_set_qset_combined(kern_netif_qset_t qset);
1058
1059extern void kern_netif_set_qset_separate(kern_netif_qset_t qset);
1060
1061/*
1062 * Misc.
1063 */
1064extern void *kern_nexus_get_context(const kern_nexus_t nexus);
1065extern 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 */
1071extern 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);
1074extern int kern_nexus_ifdetach(const nexus_controller_t ctl,
1075 const uuid_t nx_uuid, const uuid_t nx_if_uuid);
1076extern int kern_nexus_get_netif_instance(struct ifnet *ifp, uuid_t nx_uuid);
1077extern int kern_nexus_get_flowswitch_instance(struct ifnet *ifp,
1078 uuid_t nx_uuid);
1079extern nexus_controller_t kern_nexus_shared_controller(void);
1080extern void kern_nexus_register_netagents(void);
1081extern void kern_nexus_deregister_netagents(void);
1082extern void kern_nexus_update_netagents(void);
1083extern int kern_nexus_interface_add_netagent(struct ifnet *);
1084extern int kern_nexus_interface_remove_netagent(struct ifnet *);
1085extern int kern_nexus_set_netif_input_tbr_rate(struct ifnet *ifp,
1086 uint64_t rate);
1087extern 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);
1090extern int kern_nexus_flow_add(const nexus_controller_t ncd,
1091 const uuid_t nx_uuid, void *data, size_t data_len);
1092extern 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