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