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