1099 lines
42 KiB
C
1099 lines
42 KiB
C
|
/*
|
||
|
* Copyright (c) 2015-2022 Apple Inc. All rights reserved.
|
||
|
*
|
||
|
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. The rights granted to you under the License
|
||
|
* may not be used to create, or enable the creation or redistribution of,
|
||
|
* unlawful or unlicensed copies of an Apple operating system, or to
|
||
|
* circumvent, violate, or enable the circumvention or violation of, any
|
||
|
* terms of an Apple operating system software license agreement.
|
||
|
*
|
||
|
* Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
||
|
*/
|
||
|
|
||
|
#ifndef _SKYWALK_OS_NEXUS_H_
|
||
|
#define _SKYWALK_OS_NEXUS_H_
|
||
|
|
||
|
#ifdef PRIVATE
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/cdefs.h>
|
||
|
#include <uuid/uuid.h>
|
||
|
#include <mach/boolean.h>
|
||
|
|
||
|
#ifdef KERNEL_PRIVATE
|
||
|
struct ifnet_interface_advisory;
|
||
|
#endif /* KERNEL_PRIVATE */
|
||
|
|
||
|
struct ifnet_traffic_descriptor_common;
|
||
|
struct ifnet_traffic_rule_action;
|
||
|
|
||
|
/*
|
||
|
* Nexus terminology and overview. The relationship between the objects are
|
||
|
* as follows:
|
||
|
*
|
||
|
* domain --> domain_provider --> nexus_provider --> nexus
|
||
|
*
|
||
|
* Skywalk comes with several nexus domains (types). Each domain has one or
|
||
|
* more domain providers; the system comes with a built-in (default) domain
|
||
|
* provider per domain. Additional domain providers may be attached, but
|
||
|
* this ability is reserved to kernel subsystems. The domain specifies the
|
||
|
* nexus semantics, including the permitted topology, number and definition
|
||
|
* of ports, memory regions, etc.
|
||
|
*
|
||
|
* Each domain provider may have one or more nexus providers registered to it.
|
||
|
* This allows different parameters (rings, slots, buffer metadata) to be
|
||
|
* configured on a per-nexus provider basis.
|
||
|
*
|
||
|
* Nexus instances can then be allocated based on a registered nexus provider.
|
||
|
* All instances associated with a given nexus provider share the same set of
|
||
|
* parameters that are configured for that nexus provider.
|
||
|
*
|
||
|
* Channels are then opened to nexus instances.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Nexus types.
|
||
|
*
|
||
|
* Userland code may only register Nexus providers against the USER_PIPE
|
||
|
* and FLOW_SWITCH types. The rest are reserved for kernel subsystems.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
NEXUS_TYPE_USER_PIPE, /* pipe (user) */
|
||
|
NEXUS_TYPE_KERNEL_PIPE, /* pipe (kernel) */
|
||
|
NEXUS_TYPE_NET_IF, /* network interface (kernel) */
|
||
|
NEXUS_TYPE_FLOW_SWITCH, /* flow switch (user/kernel) */
|
||
|
#ifdef BSD_KERNEL_PRIVATE
|
||
|
/*
|
||
|
* Monitor nexus isn't directly usable on its own; we just
|
||
|
* need a type definition here for it to act as a pseudo
|
||
|
* domain provider.
|
||
|
*/
|
||
|
NEXUS_TYPE_MONITOR, /* monitor (user) */
|
||
|
NEXUS_TYPE_MAX, /* this needs to be last */
|
||
|
NEXUS_TYPE_UNDEFINED = -1, /* for kernel internal use */
|
||
|
#endif /* BSD_KERNEL_PRIVATE */
|
||
|
} nexus_type_t;
|
||
|
|
||
|
/*
|
||
|
* Nexus provider name.
|
||
|
*/
|
||
|
typedef uint8_t nexus_name_t[64];
|
||
|
|
||
|
/*
|
||
|
* Nexus instance port.
|
||
|
*/
|
||
|
typedef uint16_t nexus_port_t;
|
||
|
|
||
|
/*
|
||
|
* User pipe Nexus has at most two ports: one client and server.
|
||
|
*/
|
||
|
#define NEXUS_PORT_USER_PIPE_CLIENT 0
|
||
|
#define NEXUS_PORT_USER_PIPE_SERVER 1
|
||
|
|
||
|
/*
|
||
|
* Kernel pipe Nexus has at most one port for the client.
|
||
|
*/
|
||
|
#define NEXUS_PORT_KERNEL_PIPE_CLIENT 0
|
||
|
|
||
|
/*
|
||
|
* Network Interface Nexus can have any number of ports.
|
||
|
* Port 0 and 1 are reserved for DEV and HOST. The other ports
|
||
|
* (2 and above) can be of the types: filter, custom ethertype,
|
||
|
* or low latency.
|
||
|
*/
|
||
|
#define NEXUS_PORT_NET_IF_DEV 0
|
||
|
#define NEXUS_PORT_NET_IF_HOST 1
|
||
|
#define NEXUS_PORT_NET_IF_CLIENT 2
|
||
|
|
||
|
/*
|
||
|
* Flow switch has its first N ports reserved; the following is the first
|
||
|
* client usable port. The last usable depends on the configured number
|
||
|
* of nexus ports.
|
||
|
*/
|
||
|
#define NEXUS_PORT_FLOW_SWITCH_CLIENT 2
|
||
|
|
||
|
/*
|
||
|
* Opaque handles.
|
||
|
*/
|
||
|
struct nexus_controller;
|
||
|
struct nexus_attr;
|
||
|
|
||
|
typedef struct nexus_controller *nexus_controller_t;
|
||
|
typedef struct nexus_attr *nexus_attr_t;
|
||
|
|
||
|
/*
|
||
|
* Nexus attribute types.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
NEXUS_ATTR_TX_RINGS, /* (g/s) # of transmit rings */
|
||
|
NEXUS_ATTR_RX_RINGS, /* (g/s) # of receive rings */
|
||
|
NEXUS_ATTR_TX_SLOTS, /* (g/s) # of slots per transmit ring */
|
||
|
NEXUS_ATTR_RX_SLOTS, /* (g/s) # of slots per receive ring */
|
||
|
NEXUS_ATTR_SLOT_BUF_SIZE, /* (g/s) buffer per slot (bytes) */
|
||
|
NEXUS_ATTR_SLOT_META_SIZE, /* (g) metadata per slot (bytes) */
|
||
|
NEXUS_ATTR_ANONYMOUS, /* (g/s) allow anonymous clients */
|
||
|
NEXUS_ATTR_MHINTS, /* (g/s) memory usage hints */
|
||
|
NEXUS_ATTR_PIPES, /* (g/s) # of pipes */
|
||
|
NEXUS_ATTR_EXTENSIONS, /* (g/s) extension-specific attr */
|
||
|
NEXUS_ATTR_IFINDEX, /* (g) network interface index */
|
||
|
NEXUS_ATTR_STATS_SIZE, /* (g) statistics region size (bytes) */
|
||
|
NEXUS_ATTR_FLOWADV_MAX, /* (g) max flow advisory entries */
|
||
|
NEXUS_ATTR_QMAP, /* (g/s) queue mapping type */
|
||
|
NEXUS_ATTR_CHECKSUM_OFFLOAD, /* (g) partial checksum offload */
|
||
|
NEXUS_ATTR_USER_PACKET_POOL, /* (g) user packet pool */
|
||
|
NEXUS_ATTR_ADV_SIZE, /* (g) nexus advisory region size */
|
||
|
NEXUS_ATTR_USER_CHANNEL, /* (g/s) allow user channel open */
|
||
|
NEXUS_ATTR_MAX_FRAGS, /* (g/s) max fragments in a packets */
|
||
|
/*
|
||
|
* (g/s) reject channel operations on nexus if the peer has closed
|
||
|
* the channel.
|
||
|
* The os channel will appear as defunct to the active peer.
|
||
|
*/
|
||
|
NEXUS_ATTR_REJECT_ON_CLOSE,
|
||
|
NEXUS_ATTR_LARGE_BUF_SIZE, /* (g/s) size of large buffer (bytes) */
|
||
|
} nexus_attr_type_t;
|
||
|
|
||
|
/*
|
||
|
* XXX: this is temporary and should be removed later.
|
||
|
*/
|
||
|
#define OS_NEXUS_HAS_USER_PACKET_POOL 1
|
||
|
|
||
|
/*
|
||
|
* Memory usage hint attributes that can be specified for NEXUS_ATTR_MHINTS
|
||
|
* These can be OR'ed to specified multiple hints
|
||
|
*/
|
||
|
/* No hint, default behaviour */
|
||
|
#define NEXUS_MHINTS_NORMAL 0x0
|
||
|
/* Application expects to access the channels soon */
|
||
|
#define NEXUS_MHINTS_WILLNEED 0x1
|
||
|
/* Application expects low latency for bursty traffic */
|
||
|
#define NEXUS_MHINTS_LOWLATENCY 0x2
|
||
|
/* Application expects high usage of channel memory */
|
||
|
#define NEXUS_MHINTS_HIUSE 0x4
|
||
|
|
||
|
/*
|
||
|
* Extension attributes.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
NEXUS_EXTENSION_TYPE_MAXTYPE = 0,
|
||
|
} nexus_extension_t;
|
||
|
|
||
|
/*
|
||
|
* Nexus queue mapping types.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
NEXUS_QMAP_TYPE_INVALID = 0, /* invalid type */
|
||
|
NEXUS_QMAP_TYPE_DEFAULT, /* 10:1 mapping */
|
||
|
NEXUS_QMAP_TYPE_WMM, /* 802.11 WMM */
|
||
|
} nexus_qmap_type_t;
|
||
|
|
||
|
#define NEXUS_NUM_WMM_QUEUES 4 /* number of WMM access categories */
|
||
|
|
||
|
/*
|
||
|
* Nexus buffer metadata template.
|
||
|
*
|
||
|
* Each Nexus provider implementation will define an overlay of this structure;
|
||
|
* the top of the structure always begins with this common area. The contents
|
||
|
* of this common area, as well as the rest of the per-buffer metadata region
|
||
|
* are left to the provider to define.
|
||
|
*
|
||
|
* This structure is aligned for efficient copy and accesses.
|
||
|
*/
|
||
|
typedef struct nexus_mdata {
|
||
|
union {
|
||
|
uuid_t __uuid; /* flow UUID */
|
||
|
uint8_t __val8[16];
|
||
|
uint16_t __val16[8];
|
||
|
uint32_t __val32[4];
|
||
|
uint64_t __val64[2];
|
||
|
} __flowid_u;
|
||
|
#define nm_flowid_uuid __flowid_u.__uuid
|
||
|
#define nm_flowid_val8 __flowid_u.__val8
|
||
|
#define nm_flowid_val16 __flowid_u.__val16
|
||
|
#define nm_flowid_val32 __flowid_u.__val32
|
||
|
#define nm_flowid_val64 __flowid_u.__val64
|
||
|
} nexus_mdata_t __attribute((aligned(8)));
|
||
|
|
||
|
/*
|
||
|
* Nexus bind flags.
|
||
|
*/
|
||
|
#define NEXUS_BIND_PID 0x1 /* bind to a process ID */
|
||
|
#define NEXUS_BIND_EXEC_UUID 0x2 /* bind to a process exec's UUID */
|
||
|
#define NEXUS_BIND_KEY 0x4 /* bind to a key blob */
|
||
|
|
||
|
/*
|
||
|
* Maximum length of key blob (in bytes).
|
||
|
*/
|
||
|
#define NEXUS_MAX_KEY_LEN 1024
|
||
|
|
||
|
#ifndef KERNEL
|
||
|
/*
|
||
|
* User APIs.
|
||
|
*/
|
||
|
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
|
||
|
__BEGIN_DECLS
|
||
|
/*
|
||
|
* Creates a Nexus attribute object.
|
||
|
*
|
||
|
* This must be paired with a os_nexus_attr_destroy() on the handle.
|
||
|
*/
|
||
|
extern nexus_attr_t os_nexus_attr_create(void);
|
||
|
|
||
|
/*
|
||
|
* Clones a Nexus attribute object. If source attribute is NULL
|
||
|
* it behaves just like os_nexus_attr_create();
|
||
|
*
|
||
|
* This must be paired with a os_nexus_attr_destroy() on the handle.
|
||
|
*/
|
||
|
extern nexus_attr_t os_nexus_attr_clone(const nexus_attr_t attr);
|
||
|
|
||
|
/*
|
||
|
* Sets a value for a given attribute type on a Nexus attribute object.
|
||
|
*/
|
||
|
extern int os_nexus_attr_set(nexus_attr_t attr,
|
||
|
const nexus_attr_type_t type, const uint64_t value);
|
||
|
|
||
|
/*
|
||
|
* Gets a value for a given attribute type on a Nexus attribute object.
|
||
|
*/
|
||
|
extern int os_nexus_attr_get(const nexus_attr_t attr,
|
||
|
const nexus_attr_type_t type, uint64_t *value);
|
||
|
|
||
|
/*
|
||
|
* Destroys a Nexus attribute object.
|
||
|
*/
|
||
|
extern void os_nexus_attr_destroy(nexus_attr_t attr);
|
||
|
|
||
|
/*
|
||
|
* Opens a handle to the Nexus controller.
|
||
|
*
|
||
|
* This must be paired with a os_nexus_controller_destroy() on the handle, in
|
||
|
* order to remove any remaining active providers and free resources.
|
||
|
*/
|
||
|
extern nexus_controller_t os_nexus_controller_create(void);
|
||
|
|
||
|
/*
|
||
|
* Retrieves the file descriptor associated with the Nexus controller.
|
||
|
*/
|
||
|
extern int os_nexus_controller_get_fd(const nexus_controller_t ctl);
|
||
|
|
||
|
/*
|
||
|
* Registers a Nexus provider.
|
||
|
*
|
||
|
* Anonymous Nexus provider mode implies the freedom to connect to the Nexus
|
||
|
* instance from any channel client. Alternatively, named mode requires the
|
||
|
* Nexus provider to explicitly bind a Nexus instance port to a set of client
|
||
|
* attributes. This mode (named) is the default behavior, and is done so to
|
||
|
* encourage Nexus providers to explicitly know about the clients that it's
|
||
|
* communicating with. Specifying anonymous mode can be done via the Nexus
|
||
|
* attribute NEXUS_ATTR_ANONYMOUS, by setting it to a non-zero value.
|
||
|
*
|
||
|
* The client binding attributes include the process ID, the executable UUID,
|
||
|
* and/or a key blob. Only a client possessing those will be allowed to open
|
||
|
* a channel to the Nexus instance port.
|
||
|
*/
|
||
|
extern int os_nexus_controller_register_provider(const nexus_controller_t ctl,
|
||
|
const nexus_name_t name, const nexus_type_t type, const nexus_attr_t attr,
|
||
|
uuid_t *prov_uuid);
|
||
|
|
||
|
/*
|
||
|
* Deregisters a Nexus provider.
|
||
|
*/
|
||
|
extern int os_nexus_controller_deregister_provider(const nexus_controller_t ctl,
|
||
|
const uuid_t prov_uuid);
|
||
|
|
||
|
/*
|
||
|
* Creates a Nexus instance of a registered provider.
|
||
|
*/
|
||
|
extern int os_nexus_controller_alloc_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t prov_uuid, uuid_t *nx_uuid);
|
||
|
|
||
|
/*
|
||
|
* Destroys a Nexus instance.
|
||
|
*/
|
||
|
extern int os_nexus_controller_free_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid);
|
||
|
|
||
|
/*
|
||
|
* Bind a port of a Nexus instance to one or more attributes associated with
|
||
|
* a channel client: process ID, process executable's UUID, or key blob.
|
||
|
* This is only applicable to named Nexus provider.
|
||
|
*
|
||
|
* Binding to a process ID implies allowing only a channel client with such
|
||
|
* PID to open the Nexus port.
|
||
|
*
|
||
|
* Binding to an executable UUID allows a channel client (regardless of PID
|
||
|
* or instance) with such executable UUID to open the Nexus port. When this
|
||
|
* is requested by a provider that doesn't have the client's executable UUID,
|
||
|
* a valid client PID must be provided (with the executable UUID zeroed out)
|
||
|
* in order for the kernel to retrieve the executable UUID from the process
|
||
|
* and to use that as the bind attribute. Else, a non-zero executable UUID
|
||
|
* can be specified (PID is ignored in this case) by the provider.
|
||
|
*
|
||
|
* Binding to a key blob allows a channel client possessing the identical
|
||
|
* key blob to open the Nexus port. The key blob is opaque to the system,
|
||
|
* and is left to the Nexus provider to interpret and relay to its client.
|
||
|
*
|
||
|
* A Nexus provider must choose to select one or a combination of those
|
||
|
* attributes for securing access to a port of a named Nexus instance.
|
||
|
* The provider is also responsible for detecting if the client has gone
|
||
|
* away, and either to unbind the Nexus instance port indefinitely, or
|
||
|
* reissue another bind with the new client binding attributes for that
|
||
|
* same port. This is to handle cases where the client terminates and
|
||
|
* is expected to reattach to the same port.
|
||
|
*
|
||
|
* All port bindings belonging to a Nexus instance will be automatically
|
||
|
* removed when the Nexus instance is destroyed.
|
||
|
*/
|
||
|
extern int os_nexus_controller_bind_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid, const nexus_port_t port,
|
||
|
const pid_t pid, const uuid_t exec_uuid, const void *key,
|
||
|
const uint32_t key_len, const uint32_t bind_flags);
|
||
|
|
||
|
/*
|
||
|
* Unbind a previously-bound port of a Nexus instance. This is only
|
||
|
* applicable to named Nexus provider. A previously-bound Nexus instance
|
||
|
* port cannot be bound again until this call is issued.
|
||
|
*/
|
||
|
extern int os_nexus_controller_unbind_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid,
|
||
|
const nexus_port_t port);
|
||
|
|
||
|
/*
|
||
|
* Retrieves current Nexus provider attributes into the nexus_attr_t handle.
|
||
|
*/
|
||
|
extern int os_nexus_controller_read_provider_attr(const nexus_controller_t ctl,
|
||
|
const uuid_t prov_uuid, nexus_attr_t attr);
|
||
|
|
||
|
/*
|
||
|
* Traffic rules APIs.
|
||
|
*/
|
||
|
|
||
|
/* Persist after controller close. */
|
||
|
#define NXCTL_ADD_TRAFFIC_RULE_FLAG_PERSIST 0x0001
|
||
|
extern int os_nexus_controller_add_traffic_rule(const nexus_controller_t ctl,
|
||
|
const char *ifname, const struct ifnet_traffic_descriptor_common *td,
|
||
|
const struct ifnet_traffic_rule_action *ra, const uint32_t flags,
|
||
|
uuid_t *rule_uuid);
|
||
|
|
||
|
extern int os_nexus_controller_remove_traffic_rule(const nexus_controller_t ctl,
|
||
|
const uuid_t rule_uuid);
|
||
|
|
||
|
struct nexus_traffic_rule_info {
|
||
|
uuid_t *nri_rule_uuid;
|
||
|
char *nri_owner;
|
||
|
char *nri_ifname;
|
||
|
struct ifnet_traffic_descriptor_common *nri_td;
|
||
|
struct ifnet_traffic_rule_action *nri_ra;
|
||
|
uint32_t nri_flags;
|
||
|
};
|
||
|
/* Return TRUE to continue, FALSE to exit. */
|
||
|
typedef boolean_t (nexus_traffic_rule_iterator_t)(void *,
|
||
|
const struct nexus_traffic_rule_info *);
|
||
|
|
||
|
extern int os_nexus_controller_iterate_traffic_rules(const nexus_controller_t ctl,
|
||
|
nexus_traffic_rule_iterator_t itr, void *itr_arg);
|
||
|
|
||
|
/*
|
||
|
* Destroys a Nexus controller handle.
|
||
|
*/
|
||
|
extern void os_nexus_controller_destroy(nexus_controller_t ctl);
|
||
|
__END_DECLS
|
||
|
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
|
||
|
#else /* KERNEL */
|
||
|
/*
|
||
|
* Kernel APIs.
|
||
|
*/
|
||
|
#include <sys/proc.h>
|
||
|
#include <IOKit/skywalk/IOSkywalkSupport.h>
|
||
|
|
||
|
/*
|
||
|
* Nexus domain provider name.
|
||
|
*/
|
||
|
typedef uint8_t nexus_domain_provider_name_t[64];
|
||
|
|
||
|
/*
|
||
|
* Opaque handles.
|
||
|
*/
|
||
|
struct nxctl;
|
||
|
struct kern_slot_prop;
|
||
|
struct kern_nexus;
|
||
|
struct kern_nexus_provider;
|
||
|
struct kern_nexus_domain_provider;
|
||
|
struct kern_channel;
|
||
|
struct __kern_channel_ring;
|
||
|
struct __slot_desc;
|
||
|
struct __pbufpool;
|
||
|
|
||
|
typedef struct kern_pbufpool *kern_pbufpool_t;
|
||
|
typedef struct kern_nexus *kern_nexus_t;
|
||
|
typedef struct kern_nexus_provider *kern_nexus_provider_t;
|
||
|
typedef struct kern_nexus_domain_provider *kern_nexus_domain_provider_t;
|
||
|
typedef struct kern_channel *kern_channel_t;
|
||
|
typedef struct __kern_channel_ring *kern_channel_ring_t;
|
||
|
typedef struct __slot_desc *kern_channel_slot_t;
|
||
|
typedef struct netif_llink *kern_netif_llink_t;
|
||
|
typedef struct netif_qset *kern_netif_qset_t;
|
||
|
typedef struct netif_queue *kern_netif_queue_t;
|
||
|
|
||
|
/*
|
||
|
* Domain provider callback routines.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @typedef nxdom_prov_init_fn_t
|
||
|
* @abstract Domain provider initializer callback.
|
||
|
* @param domprov Domain provider handle.
|
||
|
* @discussion This will be called after kern_nexus_register_domain_provider().
|
||
|
* @result Non-zero result will abort the domain provider registration.
|
||
|
*/
|
||
|
typedef errno_t (*nxdom_prov_init_fn_t)(kern_nexus_domain_provider_t domprov);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxdom_prov_fini_fn_t
|
||
|
* @abstract Domain provider teardown callback.
|
||
|
* @param domprov Domain provider handle.
|
||
|
* @discussion This will happen after kern_nexus_deregister_domain_provider().
|
||
|
* A provider must not unload or free resources associated to the domain
|
||
|
* provider instance until this callback is invoked.
|
||
|
*/
|
||
|
typedef void (*nxdom_prov_fini_fn_t)(kern_nexus_domain_provider_t domprov);
|
||
|
|
||
|
/*
|
||
|
* Domain provider init.
|
||
|
*/
|
||
|
struct kern_nexus_domain_provider_init {
|
||
|
uint32_t nxdpi_version; /* current version */
|
||
|
uint32_t nxdpi_flags; /* for future */
|
||
|
nxdom_prov_init_fn_t nxdpi_init; /* required */
|
||
|
nxdom_prov_fini_fn_t nxdpi_fini; /* required */
|
||
|
};
|
||
|
|
||
|
#define KERN_NEXUS_DOMAIN_PROVIDER_VERSION_1 1
|
||
|
#define KERN_NEXUS_DOMAIN_PROVIDER_NETIF 2
|
||
|
#define KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION \
|
||
|
KERN_NEXUS_DOMAIN_PROVIDER_VERSION_1
|
||
|
|
||
|
/*
|
||
|
* Nexus provider callback routines.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_pre_connect_fn_t
|
||
|
* @abstract Nexus provider channel connecting callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param proc The process associated with the channel.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param channel The channel that has been created and being connected
|
||
|
* to the nexus instances's port.
|
||
|
* @param channel_context Pointer to provider-specific context that can be
|
||
|
* associated with the channel. Upon a successful return, this can
|
||
|
* later be retrieved via subsequent calls to kern_channel_get_context().
|
||
|
* @result Non-zero result will deny the channel from being connected.
|
||
|
* @discussion This is invoked when a channel is opened to the nexus port.
|
||
|
* Upon success, client's ring and slot callbacks will be called.
|
||
|
* The channel is not usable until the nxprov_connected_fn_t() is
|
||
|
* invoked. Client must refrain from channel activities until then.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_pre_connect_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
proc_t proc, kern_nexus_t nexus, nexus_port_t port, kern_channel_t channel,
|
||
|
void **channel_context);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_connected_fn_t
|
||
|
* @abstract Nexus provider channel connected callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param channel The channel that has been created and fully connected
|
||
|
* to the nexus instances's port.
|
||
|
* @result Non-zero result will deny the channel from being connected.
|
||
|
* @discussion This is invoked when all ring and slot initializations have
|
||
|
* been completed, and that the channel is ready for activities.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_connected_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_t channel);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_pre_disconnect_fn_t
|
||
|
* @abstract Nexus provider channel disconnecting callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param channel The channel that has been decommissioned.
|
||
|
* @param channel_context The context that was originally set o the channel
|
||
|
* at the time nxprov_pre_connect_fn_t() callback was invoked.
|
||
|
* @discussion Following this call, all ring and slot finish callbacks will
|
||
|
* be invoked. Client must quiesce all channel activities upon getting
|
||
|
* this callback. The final disconnect completion will be indicated
|
||
|
* through a call to the nxprov_disconnected_fn_t() callback.
|
||
|
*/
|
||
|
typedef void (*nxprov_pre_disconnect_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_t channel);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_disconnected_fn_t
|
||
|
* @abstract Nexus provider channel disconnect callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param channel The channel that has been decommissioned.
|
||
|
* @param channel_context The context that was originally set o the channel
|
||
|
* at the time nxprov_pre_connect_fn_t() callback was invoked.
|
||
|
* @discussion The provider must free any resources associated with the
|
||
|
* channel context set at nxprov_pre_connect_fn_t() time, since the channel
|
||
|
* instance is no longer valid upon return.
|
||
|
*/
|
||
|
typedef void (*nxprov_disconnected_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_t channel);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_ring_init_fn_t
|
||
|
* @abstract Nexus provider ring setup callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param channel The channel associated with the ring.
|
||
|
* @param ring The ring that has been prepared.
|
||
|
* @param is_tx_ring True if ring is used for TX direction, otherwise RX.
|
||
|
* @param ring_id Ring identification number.
|
||
|
* @param ring_context Pointer to provider-specific context that can be
|
||
|
* associated with the ring. Upon a successful return, this context
|
||
|
* can later be retrieved via subsequent calls to
|
||
|
* kern_channel_ring_get_context().
|
||
|
* @result Non-zero result will abort the ring initialization.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_ring_init_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_t channel, kern_channel_ring_t ring,
|
||
|
boolean_t is_tx_ring, void **ring_context);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_ring_fini_fn_t
|
||
|
* @abstract Nexus provider ring teardown callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param channel The channel associated with the ring.
|
||
|
* @param ring The ring that has been decommissioned.
|
||
|
* @discussion The provider must free any resources associated with the
|
||
|
* ring context set at nxprov_ring_init_fn_t() time, since the ring is
|
||
|
* no longer valid upon return. This call will be issued after all
|
||
|
* slots belonging to the ring has been decommisioned, via
|
||
|
* nxprov_slot_fini_fn_t().
|
||
|
*/
|
||
|
typedef void (*nxprov_ring_fini_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_slot_init_fn_t
|
||
|
* @abstract Nexus provider channel slot setup callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ring The ring associated with the slot.
|
||
|
* @param slot The slot that has been prepared.
|
||
|
* @param slot_index The index of the slot in the ring.
|
||
|
* @param slot_prop_addr This has been deprecated; callee must set to NULL.
|
||
|
* @param slot_context Pointer to provider-specific context that can be
|
||
|
* associated with the slot in the given ring. Upon a successful return,
|
||
|
* this context can later be retrieved via subsequent calls to
|
||
|
* kern_channel_slot_get_context().
|
||
|
* @result Non-zero result will abort the slot initialization.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_slot_init_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring, kern_channel_slot_t slot,
|
||
|
uint32_t slot_index, struct kern_slot_prop **slot_prop_addr,
|
||
|
void **slot_context);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_slot_fini_fn_t
|
||
|
* @abstract Nexus provider channel slot teardown callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ring The ring associated with the slot.
|
||
|
* @param slot The slot that has been decommissioned.
|
||
|
* @param slot_index The index of the slot in the ring.
|
||
|
* @discussion The provider must free any resources associated with the
|
||
|
* slot context set at nxprov_slot_init_fn_t() time, since the slot
|
||
|
* instance is no longer valid upon return.
|
||
|
*/
|
||
|
typedef void (*nxprov_slot_fini_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring, kern_channel_slot_t slot,
|
||
|
uint32_t slot_index);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_sync_tx_fn_t
|
||
|
* @abstract Nexus provider channel sync (TX) callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ring The ring associated with the slot.
|
||
|
* @param flags See KERN_NEXUS_SYNCF flags.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_sync_tx_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring, uint32_t flags);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_sync_rx_fn_t
|
||
|
* @abstract Nexus provider channel sync (RX) callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ring The ring associated with the slot.
|
||
|
* @param flags See KERN_NEXUS_SYNCF flags.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_sync_rx_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring, uint32_t flags);
|
||
|
|
||
|
/*
|
||
|
* Valid flags for {tx,rx}sync callbacks.
|
||
|
*/
|
||
|
#define KERN_NEXUS_SYNCF_COMMIT 0x1 /* force reclaim/update */
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_tx_doorbell_fn_t
|
||
|
* @abstract Nexus provider TX doorbell callback, required for netif.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ring The ring associated with the doorbell.
|
||
|
* @param flags See KERN_NEXUS_TXDOORBELLF flags.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_tx_doorbell_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring, uint32_t flags);
|
||
|
|
||
|
/*
|
||
|
* Valid flags for tx doorbell callback.
|
||
|
*/
|
||
|
/* call kern_channel_tx_refill() in async context */
|
||
|
#define KERN_NEXUS_TXDOORBELLF_ASYNC_REFILL 0x1
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_sync_packets_fn_t
|
||
|
* @abstract Nexus provider get packets callback, required for netif.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ring The device ring.
|
||
|
* @param packets Array of packet chains
|
||
|
* @param count:
|
||
|
* RX: caller sets this to the array size. on return, this count
|
||
|
* is set to actual number of packets returned.
|
||
|
* TX: not implemented
|
||
|
* @param flags none for now.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_sync_packets_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_channel_ring_t ring, uint64_t packets[],
|
||
|
uint32_t *count, uint32_t flags);
|
||
|
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_capab_config_fn_t
|
||
|
* @abstract Nexus provider capabilities configuration callback,
|
||
|
* required for netif.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param capab The capability being queried.
|
||
|
* @param contents Structure describing the capability.
|
||
|
* @param len Input: length of buffer for holding contents.
|
||
|
* Output: length of actual size of contents.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
/* periodic interface advisory notifications */
|
||
|
KERN_NEXUS_CAPAB_INTERFACE_ADVISORY = 1,
|
||
|
/* extends queue set functionality: e.g. notify steering info */
|
||
|
KERN_NEXUS_CAPAB_QSET_EXTENSIONS,
|
||
|
} kern_nexus_capab_t;
|
||
|
|
||
|
typedef errno_t (*nxprov_capab_config_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, kern_nexus_capab_t capab, void *contents,
|
||
|
uint32_t *len);
|
||
|
|
||
|
/*
|
||
|
* struct kern_nexus_capab_interface_advisory
|
||
|
* @abstract Interface advisory capability configuration callback.
|
||
|
* @param kncia_version Version of the capability structure.
|
||
|
* @param kncia_notify The notification interface provided by kernel.
|
||
|
* @param kncia_config The configuration interface provided by nexus provider.
|
||
|
*/
|
||
|
#define KERN_NEXUS_CAPAB_INTERFACE_ADVISORY_VERSION_1 1
|
||
|
typedef errno_t (*kern_nexus_capab_interface_advisory_config_fn_t)(
|
||
|
void *provider_context, bool enable);
|
||
|
typedef errno_t (*kern_nexus_capab_interface_advisory_notify_fn_t)(
|
||
|
void *kern_context, const struct ifnet_interface_advisory *adv_info);
|
||
|
struct kern_nexus_capab_interface_advisory {
|
||
|
uint32_t kncia_version;
|
||
|
void * const kncia_kern_context;
|
||
|
void *kncia_provider_context;
|
||
|
const kern_nexus_capab_interface_advisory_notify_fn_t kncia_notify;
|
||
|
kern_nexus_capab_interface_advisory_config_fn_t kncia_config;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* struct kern_nexus_capab_qset_extensions
|
||
|
* @abstract qset extensions configuration callback.
|
||
|
* @param cqe_version Version of the capability structure.
|
||
|
* @param cqe_notify_steering_info callback provided by nexus provider.
|
||
|
* @param cqe_prov_ctx provider context for the above callback.
|
||
|
*/
|
||
|
#define KERN_NEXUS_CAPAB_QSET_EXTENSIONS_VERSION_1 1
|
||
|
typedef errno_t (*kern_nexus_capab_qsext_notify_steering_info_fn_t)(
|
||
|
void *provider_context, void *qset_context,
|
||
|
struct ifnet_traffic_descriptor_common *td, bool add);
|
||
|
struct kern_nexus_capab_qset_extensions {
|
||
|
uint32_t cqe_version;
|
||
|
void *cqe_prov_ctx;
|
||
|
kern_nexus_capab_qsext_notify_steering_info_fn_t cqe_notify_steering_info;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* Nexus provider init (version 1)
|
||
|
*/
|
||
|
struct kern_nexus_provider_init {
|
||
|
uint32_t nxpi_version; /* current version */
|
||
|
uint32_t nxpi_flags; /* see NXPIF_* */
|
||
|
nxprov_pre_connect_fn_t nxpi_pre_connect; /* required */
|
||
|
nxprov_connected_fn_t nxpi_connected; /* required */
|
||
|
nxprov_pre_disconnect_fn_t nxpi_pre_disconnect; /* required */
|
||
|
nxprov_disconnected_fn_t nxpi_disconnected; /* required */
|
||
|
nxprov_ring_init_fn_t nxpi_ring_init; /* optional */
|
||
|
nxprov_ring_fini_fn_t nxpi_ring_fini; /* optional */
|
||
|
nxprov_slot_init_fn_t nxpi_slot_init; /* optional */
|
||
|
nxprov_slot_fini_fn_t nxpi_slot_fini; /* optional */
|
||
|
nxprov_sync_tx_fn_t nxpi_sync_tx; /* required */
|
||
|
nxprov_sync_rx_fn_t nxpi_sync_rx; /* required */
|
||
|
nxprov_tx_doorbell_fn_t nxpi_tx_doorbell; /* required (netif) */
|
||
|
nxprov_sync_packets_fn_t nxpi_rx_sync_packets; /* optional (netif) */
|
||
|
nxprov_sync_packets_fn_t nxpi_tx_sync_packets; /* optional (netif) */
|
||
|
nxprov_capab_config_fn_t nxpi_config_capab; /* optional (netif) */
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_qset_init_fn_t
|
||
|
* @abstract Nexus provider netif qset setup callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param llink_ctx The context associated with the logical link owning this
|
||
|
* qset (provider owned). Retreived during logical link
|
||
|
* creation.
|
||
|
* @param qset_idx The index of the qset within this logical link.
|
||
|
* @param qset_id The encoded id of the qset. Meant to be propagated to userspace
|
||
|
* and passed down later during qset selection.
|
||
|
* @param qset The netif qset to be initialized (xnu owned). Meant to be
|
||
|
* used for upcalls to xnu.
|
||
|
* @param qset_ctx The qset context (provider owned output arg). Meant to
|
||
|
* be used for downcalls to the provider involving this qset.
|
||
|
* @result Non-zero result will abort the queue initialization.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_qset_init_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, void *llink_ctx, uint8_t qset_idx,
|
||
|
uint64_t qset_id, kern_netif_qset_t qset, void **qset_ctx);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_qset_fini_fn_t
|
||
|
* @abstract Nexus provider netif qset teardown callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param qset_ctx The qset context retrieved from nxprov_qset_init_fn_t
|
||
|
* (provider owned).
|
||
|
* @discussion The provider must free any resources associated with the
|
||
|
* qset context set at nxprov_qset_init_fn_t() time, since the qset is
|
||
|
* no longer valid upon return.
|
||
|
*/
|
||
|
typedef void (*nxprov_qset_fini_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, void *qset_ctx);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_queue_init_fn_t
|
||
|
* @abstract Nexus provider netif queue setup callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param qset_ctx The context associated with the qset owning this queue
|
||
|
* (provider owned). Retreived from nxprov_qset_init_fn_t.
|
||
|
* @param qidx The index of the queue within this qset.
|
||
|
* @param queue The netif queue to be initialized (xnu owned). Meant to be
|
||
|
* used for upcalls to xnu.
|
||
|
* @param tx True if the queue is used for TX direction, otherwise RX.
|
||
|
* @param queue_ctx The queue context (provider owned output arg). Meant to
|
||
|
* be used for downcalls to the provider involving this queue.
|
||
|
* @result Non-zero result will abort the queue initialization.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_queue_init_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, void *qset_ctx, uint8_t qidx, bool tx,
|
||
|
kern_netif_queue_t queue, void **queue_ctx);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_queue_fini_fn_t
|
||
|
* @abstract Nexus provider netif queue teardown callback.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param queue_ctx The queue context retrieved from nxprov_queue_init_fn_t
|
||
|
* (provider owned).
|
||
|
* @discussion The provider must free any resources associated with the
|
||
|
* queue context set at nxprov_queue_init_fn_t() time, since the queue is
|
||
|
* no longer valid upon return.
|
||
|
*/
|
||
|
typedef void (*nxprov_queue_fini_fn_t)(kern_nexus_provider_t nexus_prov,
|
||
|
kern_nexus_t nexus, void *queue_ctx);
|
||
|
|
||
|
/*
|
||
|
* @typedef nxprov_tx_qset_notify_fn_t
|
||
|
* @abstract Nexus provider TX notify callback, required for netif.
|
||
|
* @param nexus_prov Nexus provider handle.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param qset_ctx The qset_ctx owned by the qset to be notified (provider
|
||
|
* owned). Retrieved from nxprov_qset_init_fn_t.
|
||
|
* @param flags unused for now.
|
||
|
*/
|
||
|
typedef errno_t (*nxprov_tx_qset_notify_fn_t)(kern_nexus_provider_t
|
||
|
nexus_prov, kern_nexus_t nexus, void *qset_ctx, uint32_t flags);
|
||
|
|
||
|
/*
|
||
|
* Nexus provider initialization parameters specific to netif (version 2)
|
||
|
*/
|
||
|
struct kern_nexus_netif_provider_init {
|
||
|
uint32_t nxnpi_version; /* current version */
|
||
|
uint32_t nxnpi_flags; /* see NXPIF_* */
|
||
|
nxprov_pre_connect_fn_t nxnpi_pre_connect; /* required */
|
||
|
nxprov_connected_fn_t nxnpi_connected; /* required */
|
||
|
nxprov_pre_disconnect_fn_t nxnpi_pre_disconnect; /* required */
|
||
|
nxprov_disconnected_fn_t nxnpi_disconnected; /* required */
|
||
|
nxprov_qset_init_fn_t nxnpi_qset_init; /* required */
|
||
|
nxprov_qset_fini_fn_t nxnpi_qset_fini; /* required */
|
||
|
nxprov_queue_init_fn_t nxnpi_queue_init; /* required */
|
||
|
nxprov_queue_fini_fn_t nxnpi_queue_fini; /* required */
|
||
|
nxprov_tx_qset_notify_fn_t nxnpi_tx_qset_notify; /* required */
|
||
|
nxprov_capab_config_fn_t nxnpi_config_capab; /* required */
|
||
|
};
|
||
|
|
||
|
#define KERN_NEXUS_PROVIDER_VERSION_1 1
|
||
|
#define KERN_NEXUS_PROVIDER_VERSION_NETIF 2 /* specific to netif */
|
||
|
#define KERN_NEXUS_PROVIDER_CURRENT_VERSION KERN_NEXUS_PROVIDER_VERSION_1
|
||
|
|
||
|
/*
|
||
|
* Valid values for nxpi_flags.
|
||
|
*/
|
||
|
#define NXPIF_VIRTUAL_DEVICE 0x1 /* device is virtual (no DMA) */
|
||
|
#define NXPIF_MONOLITHIC 0x4 /* single segment mode */
|
||
|
#define NXPIF_INHIBIT_CACHE 0x8 /* caching-inhibited */
|
||
|
|
||
|
/*
|
||
|
* Network Interface Nexus instance callback routines.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* @typedef nxnet_prepare_fn_t
|
||
|
* @abstract Network Interface nexus instance preparer callback.
|
||
|
* @param nexus The nexus instance.
|
||
|
* @param ifp The interface associated with the nexus instance.
|
||
|
* @discussion The prepare callback routine specified by nxneti_prepare will
|
||
|
* be invoked on a newly-allocated interface that is not yet attached.
|
||
|
* A non-zero value returned by the callback routine will abort the
|
||
|
* operation; otherwise, the interface will then be associated with
|
||
|
* the nexus prior to being fully attached to the system.
|
||
|
*/
|
||
|
typedef errno_t (*nxnet_prepare_fn_t)(kern_nexus_t nexus, ifnet_t ifp);
|
||
|
|
||
|
/*
|
||
|
* Nexus (Non-Networking) instance init.
|
||
|
*
|
||
|
* If supplied, packet buffer pool must have been created as KBIF_QUANTUM.
|
||
|
*/
|
||
|
struct kern_nexus_init {
|
||
|
uint32_t nxi_version; /* current version */
|
||
|
uint32_t nxi_flags; /* see NXIF_* */
|
||
|
kern_pbufpool_t nxi_tx_pbufpool; /* optional */
|
||
|
kern_pbufpool_t nxi_rx_pbufpool; /* optional */
|
||
|
};
|
||
|
|
||
|
#define KERN_NEXUS_VERSION_1 1
|
||
|
#define KERN_NEXUS_CURRENT_VERSION KERN_NEXUS_VERSION_1
|
||
|
|
||
|
/*
|
||
|
* Network Interface Nexus instance init.
|
||
|
*
|
||
|
* If supplied, packet buffer pool must NOT have been created as KBIF_QUANTUM.
|
||
|
* packet buffer pool is a required parameter if the nexus provider is
|
||
|
* operating in netif logical link mode.
|
||
|
*/
|
||
|
struct kern_nexus_net_init {
|
||
|
uint32_t nxneti_version; /* current version */
|
||
|
uint32_t nxneti_flags; /* see NXNETF_* */
|
||
|
struct ifnet_init_eparams *nxneti_eparams; /* required */
|
||
|
struct sockaddr_dl *nxneti_lladdr; /* optional */
|
||
|
nxnet_prepare_fn_t nxneti_prepare; /* optional */
|
||
|
kern_pbufpool_t nxneti_tx_pbufpool; /* optional */
|
||
|
kern_pbufpool_t nxneti_rx_pbufpool; /* optional */
|
||
|
struct kern_nexus_netif_llink_init *nxneti_llink; /* optional */
|
||
|
};
|
||
|
|
||
|
#define KERN_NEXUS_NET_VERSION_1 1
|
||
|
#define KERN_NEXUS_NET_VERSION_2 2
|
||
|
#define KERN_NEXUS_NET_CURRENT_VERSION KERN_NEXUS_NET_VERSION_1
|
||
|
|
||
|
struct kern_nexus_netif_llink_qset_init {
|
||
|
uint32_t nlqi_flags;
|
||
|
uint8_t nlqi_num_rxqs;
|
||
|
uint8_t nlqi_num_txqs;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* nxnetllq_flags values.
|
||
|
*/
|
||
|
/* default qset of the logical link */
|
||
|
#define KERN_NEXUS_NET_LLINK_QSET_DEFAULT 0x1
|
||
|
/* qset needs AQM */
|
||
|
#define KERN_NEXUS_NET_LLINK_QSET_AQM 0x2
|
||
|
/* qset is low latency */
|
||
|
#define KERN_NEXUS_NET_LLINK_QSET_LOW_LATENCY 0x4
|
||
|
/* qset in WMM mode */
|
||
|
#define KERN_NEXUS_NET_LLINK_QSET_WMM_MODE 0x8
|
||
|
|
||
|
typedef uint64_t kern_nexus_netif_llink_id_t;
|
||
|
|
||
|
struct kern_nexus_netif_llink_init {
|
||
|
uint32_t nli_flags;
|
||
|
uint8_t nli_num_qsets;
|
||
|
void *nli_ctx;
|
||
|
kern_nexus_netif_llink_id_t nli_link_id;
|
||
|
struct kern_nexus_netif_llink_qset_init *nli_qsets;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* nxnetll_flags values.
|
||
|
*/
|
||
|
/* default logical link */
|
||
|
#define KERN_NEXUS_NET_LLINK_DEFAULT 0x1
|
||
|
|
||
|
__BEGIN_DECLS
|
||
|
/*
|
||
|
* Attributes.
|
||
|
*/
|
||
|
extern errno_t kern_nexus_attr_create(nexus_attr_t *);
|
||
|
extern errno_t kern_nexus_attr_clone(const nexus_attr_t attr,
|
||
|
nexus_attr_t *);
|
||
|
extern errno_t kern_nexus_attr_set(nexus_attr_t attr,
|
||
|
const nexus_attr_type_t type, const uint64_t value);
|
||
|
extern errno_t kern_nexus_attr_get(const nexus_attr_t attr,
|
||
|
const nexus_attr_type_t type, uint64_t *value);
|
||
|
extern void kern_nexus_attr_destroy(nexus_attr_t attr);
|
||
|
|
||
|
/*
|
||
|
* Domain provider.
|
||
|
*
|
||
|
* At present we allow only NEXUS_TYPE_{KERNEL_PIPE,NET_IF} external
|
||
|
* providers to be registered.
|
||
|
*/
|
||
|
extern errno_t kern_nexus_register_domain_provider(const nexus_type_t type,
|
||
|
const nexus_domain_provider_name_t name,
|
||
|
const struct kern_nexus_domain_provider_init *init,
|
||
|
const uint32_t init_len, uuid_t *dom_prov_uuid);
|
||
|
extern errno_t kern_nexus_deregister_domain_provider(
|
||
|
const uuid_t dom_prov_uuid);
|
||
|
extern errno_t kern_nexus_get_default_domain_provider(const nexus_type_t type,
|
||
|
uuid_t *dom_prov_uuid);
|
||
|
|
||
|
/*
|
||
|
* Nexus provider.
|
||
|
*/
|
||
|
typedef void (*nexus_ctx_release_fn_t)(void *const ctx);
|
||
|
|
||
|
extern errno_t kern_nexus_controller_create(nexus_controller_t *ctl);
|
||
|
extern errno_t kern_nexus_controller_register_provider(
|
||
|
const nexus_controller_t ctl, const uuid_t dom_prov_uuid,
|
||
|
const nexus_name_t, const struct kern_nexus_provider_init *init,
|
||
|
const uint32_t init_len, const nexus_attr_t nxa, uuid_t *nx_prov_uuid);
|
||
|
extern errno_t kern_nexus_controller_deregister_provider(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_prov_uuid);
|
||
|
extern errno_t kern_nexus_controller_alloc_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_prov_uuid,
|
||
|
const void *nexus_context, nexus_ctx_release_fn_t nexus_context_release,
|
||
|
uuid_t *nx_uuid, const struct kern_nexus_init *init);
|
||
|
extern errno_t kern_nexus_controller_alloc_net_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_prov_uuid,
|
||
|
const void *nexus_context, nexus_ctx_release_fn_t nexus_context_release,
|
||
|
uuid_t *nx_uuid, const struct kern_nexus_net_init *init, ifnet_t *);
|
||
|
extern errno_t kern_nexus_controller_free_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid);
|
||
|
extern errno_t kern_nexus_controller_bind_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid, nexus_port_t *port,
|
||
|
const pid_t pid, const uuid_t exec_uuid, const void *key,
|
||
|
const uint32_t key_len, const uint32_t bind_flags);
|
||
|
extern errno_t kern_nexus_controller_unbind_provider_instance(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid,
|
||
|
const nexus_port_t port);
|
||
|
extern errno_t kern_nexus_controller_read_provider_attr(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_prov_uuid,
|
||
|
nexus_attr_t attr);
|
||
|
extern void kern_nexus_controller_destroy(nexus_controller_t ctl);
|
||
|
extern void kern_nexus_stop(const kern_nexus_t nx);
|
||
|
|
||
|
/*
|
||
|
* Netif specific.
|
||
|
*/
|
||
|
extern errno_t kern_netif_queue_tx_dequeue(kern_netif_queue_t, uint32_t,
|
||
|
uint32_t, boolean_t *, uint64_t *);
|
||
|
|
||
|
#define KERN_NETIF_QUEUE_RX_ENQUEUE_FLAG_FLUSH 0x0001
|
||
|
extern void kern_netif_queue_rx_enqueue(kern_netif_queue_t, uint64_t,
|
||
|
uint32_t, uint32_t);
|
||
|
|
||
|
extern errno_t kern_nexus_netif_llink_add(struct kern_nexus *,
|
||
|
struct kern_nexus_netif_llink_init *);
|
||
|
|
||
|
extern errno_t kern_nexus_netif_llink_remove(struct kern_nexus *,
|
||
|
kern_nexus_netif_llink_id_t);
|
||
|
|
||
|
extern errno_t kern_netif_qset_tx_queue_len(kern_netif_qset_t,
|
||
|
uint32_t, uint32_t *, uint32_t *);
|
||
|
|
||
|
extern void kern_netif_set_qset_combined(kern_netif_qset_t qset);
|
||
|
|
||
|
extern void kern_netif_set_qset_separate(kern_netif_qset_t qset);
|
||
|
|
||
|
/*
|
||
|
* Misc.
|
||
|
*/
|
||
|
extern void *kern_nexus_get_context(const kern_nexus_t nexus);
|
||
|
extern errno_t kern_nexus_get_pbufpool(const kern_nexus_t nexus,
|
||
|
kern_pbufpool_t *tx_pbufpool, kern_pbufpool_t *rx_pbufpool);
|
||
|
|
||
|
/*
|
||
|
* Non-exported KPIs.
|
||
|
*/
|
||
|
extern int kern_nexus_ifattach(nexus_controller_t, const uuid_t nx_uuid,
|
||
|
struct ifnet *ifp, const uuid_t nx_attachee, boolean_t host,
|
||
|
uuid_t *nx_if_uuid);
|
||
|
extern int kern_nexus_ifdetach(const nexus_controller_t ctl,
|
||
|
const uuid_t nx_uuid, const uuid_t nx_if_uuid);
|
||
|
extern int kern_nexus_get_netif_instance(struct ifnet *ifp, uuid_t nx_uuid);
|
||
|
extern int kern_nexus_get_flowswitch_instance(struct ifnet *ifp,
|
||
|
uuid_t nx_uuid);
|
||
|
extern nexus_controller_t kern_nexus_shared_controller(void);
|
||
|
extern void kern_nexus_register_netagents(void);
|
||
|
extern void kern_nexus_deregister_netagents(void);
|
||
|
extern void kern_nexus_update_netagents(void);
|
||
|
extern int kern_nexus_interface_add_netagent(struct ifnet *);
|
||
|
extern int kern_nexus_interface_remove_netagent(struct ifnet *);
|
||
|
extern int kern_nexus_set_netif_input_tbr_rate(struct ifnet *ifp,
|
||
|
uint64_t rate);
|
||
|
extern int kern_nexus_set_if_netem_params(
|
||
|
const nexus_controller_t ctl, const uuid_t nx_uuid,
|
||
|
void *data, size_t data_len);
|
||
|
extern int kern_nexus_flow_add(const nexus_controller_t ncd,
|
||
|
const uuid_t nx_uuid, void *data, size_t data_len);
|
||
|
extern int kern_nexus_flow_del(const nexus_controller_t ncd,
|
||
|
const uuid_t nx_uuid, void *data, size_t data_len);
|
||
|
|
||
|
__END_DECLS
|
||
|
#endif /* KERNEL */
|
||
|
#endif /* PRIVATE */
|
||
|
#endif /* !_SKYWALK_OS_NEXUS_H_ */
|