/* * Copyright (c) 2015-2023 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_NEXUS_NETIF_H_ #define _SKYWALK_NEXUS_NETIF_H_ #include #include #if CONFIG_NEXUS_NETIF #define NEXUS_PROVIDER_NET_IF "com.apple.nexus.netif" #define NX_NETIF_MAXPORTS 128 #define NX_NETIF_EVENT_RING_NUM 1 /* number of event rings */ #define NX_NETIF_EVENT_RING_SIZE 32 /* default event ring size */ struct netif_filter { STAILQ_ENTRY(netif_filter) nf_link; nexus_port_t nf_port; uint32_t nf_refcnt; void *nf_cb_arg; errno_t (*nf_cb_func)(void *, struct __kern_packet *, uint32_t); }; STAILQ_HEAD(netif_filter_head, netif_filter); struct netif_flow_desc { uint16_t fd_ethertype; struct in6_addr fd_laddr; struct in6_addr fd_raddr; }; struct netif_port_info { struct nx_port_info_header npi_hdr; struct netif_flow_desc npi_fd; }; struct netif_flow { SLIST_ENTRY(netif_flow) nf_link; SLIST_ENTRY(netif_flow) nf_table_link; nexus_port_t nf_port; uint32_t nf_refcnt; struct netif_flow_desc nf_desc; void *nf_cb_arg; errno_t (*nf_cb_func)(void *, void *, uint32_t); }; typedef enum { FT_TYPE_ETHERTYPE, FT_TYPE_IPV6_ULA } netif_flowtable_type_t; struct netif_flowtable { struct netif_flowtable_ops *ft_ops; void *ft_internal; }; typedef int netif_flow_lookup_t(struct netif_flowtable *, struct __kern_packet *, uint32_t, struct netif_flow **); typedef boolean_t netif_flow_match_t(struct netif_flow_desc *, struct netif_flow_desc *); typedef int netif_flow_info_t(struct __kern_packet *, struct netif_flow_desc *, uint32_t); typedef int netif_flow_insert_t(struct netif_flowtable *, struct netif_flow *); typedef void netif_flow_remove_t(struct netif_flowtable *, struct netif_flow *); typedef struct netif_flowtable *netif_flow_table_alloc_t( struct netif_flowtable_ops *); typedef void netif_flow_table_free_t(struct netif_flowtable *); struct netif_flowtable_ops { netif_flow_lookup_t *nfo_lookup; netif_flow_match_t *nfo_match; netif_flow_info_t *nfo_info; netif_flow_insert_t *nfo_insert; netif_flow_remove_t *nfo_remove; netif_flow_table_alloc_t *nfo_table_alloc; netif_flow_table_free_t *nfo_table_free; }; SLIST_HEAD(netif_flow_head, netif_flow); struct nexus_netif_adapter { /* * This is an overlay structure on nexus_adapter; * make sure it contains 'up' as the first member. */ struct nexus_adapter nifna_up; struct nx_netif *nifna_netif; struct nx_netif_mit *nifna_tx_mit; struct nx_netif_mit *nifna_rx_mit; /* * XXX For filter or vpna only */ union { struct netif_filter *nifna_filter; struct netif_flow *nifna_flow; }; uint16_t nifna_gencnt; }; struct netif_queue { decl_lck_mtx_data(, nq_lock); struct netif_qset *nq_qset; /* backpointer to parent netif qset */ struct pktq nq_pktq; struct netif_qstats nq_stats; uint64_t nq_accumulated_bytes; uint64_t nq_accumulated_pkts; uint64_t nq_accumulate_start; /* in seconds */ void *nq_ctx; kern_packet_svc_class_t nq_svc; /* service class of TX queue */ uint16_t nq_flags; }__attribute__((aligned(sizeof(uint64_t)))); /* values for nq_flags */ #define NETIF_QUEUE_EXT_INITED 0x0001 /* nxnpi_queue_init() succeeded */ #define NETIF_QUEUE_IS_RX 0x0002 /* RX queue, else TX */ #define _NETIF_QSET_QUEUE(_p, _n) \ (struct netif_queue *)(void *)((uint8_t *)((_p)->nqs_driver_queues) + \ ((_n) * sizeof(struct netif_queue))) #define NETIF_QSET_RX_QUEUE(_p, _n) _NETIF_QSET_QUEUE(_p, _n) #define NETIF_QSET_TX_QUEUE(_p, _n) \ _NETIF_QSET_QUEUE(_p, (_p)->nqs_num_rx_queues + (_n)) /* the top 32 bits are unused for now */ #define NETIF_QSET_ID_ENCODE(llink_id_internal, qset_idx) \ ((((llink_id_internal) << 16) | (qset_idx)) & 0xffffffff) struct netif_qset { struct netif_llink *nqs_llink; /* backpointer to parent logical link */ struct ifclassq *nqs_ifcq; SLIST_ENTRY(netif_qset) nqs_list; void *nqs_ctx; /* context provided by driver */ uint64_t nqs_id; /* queue set identifier */ uint8_t nqs_idx; /* queue set index */ uint16_t nqs_flags; uint8_t nqs_num_rx_queues; uint8_t nqs_num_tx_queues; /* * nq_queues will be organized as: * nq_queues[0..nq_num_rx_queues-1] will hold RX queues. * nq_queues[nq_num_rx_queues..nq_num_tx_queues-1] will hold TX queues. */ struct netif_queue nqs_driver_queues[0] __attribute__((aligned(sizeof(uint64_t)))); }; /* values for nqs_flags */ #define NETIF_QSET_FLAG_DEFAULT 0x0001 /* default queue set of the logical link */ #define NETIF_QSET_FLAG_AQM 0x0002 /* provides AQM */ #define NETIF_QSET_FLAG_LOW_LATENCY 0x0004 /* provides low latency service */ #define NETIF_QSET_FLAG_EXT_INITED 0x0008 /* nxnpi_qset_init() succeeded */ #define NETIF_DEFAULT_QSET(_qs) ((_qs)->nqs_flags & NETIF_QSET_FLAG_DEFAULT) struct netif_llink { struct nx_netif *nll_nif; /* backpointer to parent netif instance */ STAILQ_ENTRY(netif_llink) nll_link; SLIST_HEAD(, netif_qset) nll_qset_list; struct netif_qset *nll_default_qset; struct ifclassq *nll_ifcq; struct os_refcnt nll_refcnt; #define NETIF_LLINK_ID_DEFAULT 0 kern_nexus_netif_llink_id_t nll_link_id; uint16_t nll_link_id_internal; uint16_t nll_qset_cnt; uint8_t nll_state; uint8_t nll_flags; void *nll_ctx; /* context provided by driver */ }; STAILQ_HEAD(netif_llink_head, netif_llink); /* values for nll_flags */ #define NETIF_LLINK_FLAG_DEFAULT 0x1 /* default logical link */ /* values for nll_state */ #define NETIF_LLINK_STATE_INIT 0x1 /* Intialized and ready for use */ #define NETIF_LLINK_STATE_DESTROYED 0x2 /* not available for use */ #define NETIF_DEFAULT_LLINK(_ll) ((_ll)->nll_flags & NETIF_LLINK_FLAG_DEFAULT) SLIST_HEAD(netif_agent_flow_head, netif_agent_flow); struct netif_agent_flow { SLIST_ENTRY(netif_agent_flow) naf_link; uuid_t naf_flow_uuid; uuid_t naf_bind_key; nexus_port_t naf_nx_port; uint16_t naf_flags; pid_t naf_pid; union sockaddr_in_4_6 naf_daddr; union sockaddr_in_4_6 naf_saddr; }; #define NIFNA(_na) ((struct nexus_netif_adapter *)(_na)) /* nif_flags */ /* * This is named differently from the flow classification rule * (IPV6 ULA) because this gives us the flexibility of using * different types of classification in the future. */ #define NETIF_FLAG_LOW_LATENCY 0x00000001 #define NETIF_FLAG_COMPAT 0x00000002 #define NETIF_FLAG_LLINK_INITIALIZED 0x00000004 #define NETIF_IS_LOW_LATENCY(n) \ (((n)->nif_flags & NETIF_FLAG_LOW_LATENCY) != 0) #define NETIF_IS_COMPAT(n) \ (((n)->nif_flags & NETIF_FLAG_COMPAT) != 0) #define NETIF_LLINK_ENABLED(n) \ (((n)->nif_flags & NETIF_FLAG_LLINK_INITIALIZED) != 0) #define NETIF_DEFAULT_DROP_ENABLED(n) \ (nx_netif_filter_default_drop != 0 && \ (((n)->nif_filter_flags & NETIF_FILTER_FLAG_INITIALIZED) != 0)) /* nif_agent_flags */ #define NETIF_AGENT_FLAG_REGISTERED 0x00000001 #define NETIF_AGENT_FLAG_ADDED 0x00000002 /* nif_filter_flags */ #define NETIF_FILTER_FLAG_INITIALIZED 0x00000001 #define NETIF_FILTER_FLAG_ENABLED 0x00000002 /* nif_flow_flags */ #define NETIF_FLOW_FLAG_INITIALIZED 0x00000001 #define NETIF_FLOW_FLAG_ENABLED 0x00000002 /* nif_llink_flags */ #define NETIF_LLINK_FLAG_INITIALIZED 0x00000001 /* Used by netif_hwna_set_mode() */ typedef enum { NETIF_MODE_NONE, NETIF_MODE_FSW, NETIF_MODE_LLW } netif_mode_t; /* nif capabilities */ #define NETIF_CAPAB_INTERFACE_ADVISORY 0x00000001 #define NETIF_CAPAB_QSET_EXTENSIONS 0x00000002 struct netif_qset_extensions { kern_nexus_capab_qsext_notify_steering_info_fn_t qe_notify_steering_info; void *qe_prov_ctx; }; /* * nx_netif is a descriptor for a netif nexus instance. */ struct nx_netif { decl_lck_rw_data(, nif_lock); struct kern_nexus *nif_nx; struct nxbind *nif_dev_nxb; struct nxbind *nif_host_nxb; uuid_t nif_uuid; /* attachment UUID */ struct netif_stats nif_stats; uint32_t nif_flags; struct os_refcnt nif_refcnt; decl_lck_mtx_data(, nif_agent_lock); struct netif_agent_flow_head nif_agent_flow_list; uint32_t nif_agent_flow_cnt; uint32_t nif_agent_flags; netagent_session_t nif_agent_session; uuid_t nif_agent_uuid; uint32_t nif_hwassist; uint32_t nif_capabilities; uint32_t nif_capenable; uint64_t nif_input_rate; /* device input rate limit */ struct ifnet *nif_ifp; struct nx_flowswitch *nif_fsw; /* attached flowswitch nexus */ struct sk_nexusadv *nif_fsw_nxadv; /* flowswitch nexus advisory */ struct netif_nexus_advisory *nif_netif_nxadv; /* netif nexus advisory */ /* packet-mbuf copy routines */ pkt_copy_from_mbuf_t *nif_pkt_copy_from_mbuf; pkt_copy_to_mbuf_t *nif_pkt_copy_to_mbuf; pkt_copy_from_pkt_t *nif_pkt_copy_from_pkt; /* packet filtering */ decl_lck_mtx_data(, nif_filter_lock); uint32_t nif_filter_flags; uint32_t nif_filter_vp_cnt; uint32_t nif_filter_cnt; struct kern_pbufpool *nif_filter_pp; struct netif_filter_head nif_filter_list; union { struct nx_mbq nif_tx_processed_mbq[MBUF_TC_MAX]; struct nx_pktq nif_tx_processed_pktq[KPKT_TC_MAX]; }; /* virtual port */ decl_lck_mtx_data(, nif_flow_lock); uint32_t nif_vp_cnt; uint32_t nif_flow_flags; uint32_t nif_flow_cnt; struct netif_flow_head nif_flow_list; struct netif_flowtable *nif_flow_table; struct kern_channel *nif_hw_ch; uint32_t nif_hw_ch_refcnt; /* logical link */ decl_lck_rw_data(, nif_llink_lock); struct kern_nexus_netif_llink_init *nif_default_llink_params; struct netif_llink *nif_default_llink; STAILQ_HEAD(, netif_llink) nif_llink_list; uint16_t nif_llink_cnt; /* capability configuration callback function and context */ uint32_t nif_extended_capabilities; kern_nexus_capab_interface_advisory_config_fn_t nif_intf_adv_config; void *nif_intf_adv_prov_ctx; struct netif_qset_extensions nif_qset_extensions; #if (DEVELOPMENT || DEBUG) struct skoid nif_skoid; #endif /* !DEVELOPMENT && !DEBUG */ }; #define NX_NETIF_PRIVATE(_nx) ((struct nx_netif *)(_nx)->nx_arg) #define NETIF_RWINIT(_nif) \ lck_rw_init(&(_nif)->nif_lock, &nexus_lock_group, &nexus_lock_attr) #define NETIF_WLOCK(_nif) \ lck_rw_lock_exclusive(&(_nif)->nif_lock) #define NETIF_WUNLOCK(_nif) \ lck_rw_unlock_exclusive(&(_nif)->nif_lock) #define NETIF_WLOCKTORLOCK(_nif) \ lck_rw_lock_exclusive_to_shared(&(_nif)->nif_lock) #define NETIF_RLOCK(_nif) \ lck_rw_lock_shared(&(_nif)->nif_lock) #define NETIF_RLOCKTOWLOCK(_nif) \ lck_rw_lock_shared_to_exclusive(&(_nif)->nif_lock) #define NETIF_RTRYLOCK(_nif) \ lck_rw_try_lock(&(_nif)->nif_lock, LCK_RW_TYPE_SHARED) #define NETIF_RUNLOCK(_nif) \ lck_rw_unlock_shared(&(_nif)->nif_lock) #define NETIF_UNLOCK(_nif) \ lck_rw_done(&(_nif)->nif_lock) #define NETIF_RWDESTROY(_nif) \ lck_rw_destroy(&(_nif)->nif_lock, &nexus_lock_group) #define NETIF_WLOCK_ASSERT_HELD(_nif) \ LCK_RW_ASSERT(&(_nif)->nif_lock, LCK_RW_ASSERT_EXCLUSIVE) #define NETIF_RLOCK_ASSERT_HELD(_nif) \ LCK_RW_ASSERT(&(_nif)->nif_lock, LCK_RW_ASSERT_SHARED) #define NETIF_LOCK_ASSERT_HELD(_nif) \ LCK_RW_ASSERT(&(_nif)->nif_lock, LCK_RW_ASSERT_HELD) SYSCTL_DECL(_kern_skywalk_netif); /* * Macros to determine if an interface is skywalk capable or skywalk enabled. * See the magic field in struct nexus_adapter. */ #define SKYWALK_CAPABLE(ifp) \ (NA(ifp) != NULL && (ifnet_capabilities_supported(ifp) & IFCAP_SKYWALK)) #define SKYWALK_SET_CAPABLE(ifp) do { \ ifnet_lock_exclusive(ifp); \ (ifp)->if_capabilities |= IFCAP_SKYWALK; \ (ifp)->if_capenable |= IFCAP_SKYWALK; \ ifnet_lock_done(ifp); \ } while (0) #define SKYWALK_CLEAR_CAPABLE(ifp) do { \ ifnet_lock_exclusive(ifp); \ (ifp)->if_capabilities &= ~IFCAP_SKYWALK; \ (ifp)->if_capenable &= ~IFCAP_SKYWALK; \ ifnet_lock_done(ifp); \ } while (0) #define SKYWALK_NATIVE(ifp) \ ((ifp)->if_eflags & IFEF_SKYWALK_NATIVE) typedef enum { MIT_MODE_SIMPLE, MIT_MODE_ADVANCED_STATIC, MIT_MODE_ADVANCED_DYNAMIC, } mit_mode_t; /* * Mitigation support. */ struct mit_cfg_tbl { uint32_t cfg_plowat; /* packets low watermark */ uint32_t cfg_phiwat; /* packets high watermark */ uint32_t cfg_blowat; /* bytes low watermark */ uint32_t cfg_bhiwat; /* bytes high watermark */ uint32_t cfg_ival; /* delay interval (in microsecond) */ }; #define NETIF_MIT_CFG_TBL_MAX_CFG 5 struct nx_netif_mit { decl_lck_spin_data(, mit_lock); volatile struct __kern_channel_ring *mit_ckr; /* kring backpointer */ uint32_t mit_flags; uint32_t mit_requests; uint32_t mit_interval; /* * Adaptive mitigation. */ uint32_t mit_cfg_idx_max; /* highest config selector */ uint32_t mit_cfg_idx; /* current config selector */ const struct mit_cfg_tbl *mit_cfg; /* current config mapping */ mit_mode_t mit_mode; /* current mode */ uint32_t mit_packets_avg; /* average # of packets */ uint32_t mit_packets_min; /* smallest # of packets */ uint32_t mit_packets_max; /* largest # of packets */ uint32_t mit_bytes_avg; /* average # of bytes */ uint32_t mit_bytes_min; /* smallest # of bytes */ uint32_t mit_bytes_max; /* largest # of bytes */ struct pktcntr mit_sstats; /* pkts & bytes per sampling */ struct timespec mit_mode_holdtime; /* mode holdtime in nsec */ struct timespec mit_mode_lasttime; /* last mode change time nsec */ struct timespec mit_sample_time; /* sampling holdtime in nsec */ struct timespec mit_sample_lasttime; /* last sampling time in nsec */ struct timespec mit_start_time; /* time of start work in nsec */ struct thread *mit_thread; char mit_name[MAXTHREADNAMESIZE]; const struct ifnet *mit_netif_ifp; /* interface-specific mitigation table */ struct mit_cfg_tbl mit_tbl[NETIF_MIT_CFG_TBL_MAX_CFG]; #if (DEVELOPMENT || DEBUG) struct skoid mit_skoid; #endif /* !DEVELOPMENT && !DEBUG */ }; #define NETIF_MITF_INITIALIZED 0x00000001 /* has been initialized */ #define NETIF_MITF_SAMPLING 0x00000002 /* busy sampling stats */ #define NETIF_MITF_SIMPLE 0x00000004 /* no stats, no delay */ #define NETIF_MITF_READY 0x10000000 /* thread is ready */ #define NETIF_MITF_RUNNING 0x20000000 /* thread is running */ #define NETIF_MITF_TERMINATING 0x40000000 /* thread is terminating */ #define NETIF_MITF_TERMINATED 0x80000000 /* thread is terminated */ #define MIT_SPIN_LOCK(_mit) \ lck_spin_lock(&(_mit)->mit_lock) #define MIT_SPIN_LOCK_ASSERT_HELD(_mit) \ LCK_SPIN_ASSERT(&(_mit)->mit_lock, LCK_ASSERT_OWNED) #define MIT_SPIN_LOCK_ASSERT_NOTHELD(_mit) \ LCK_SPIN_ASSERT(&(_mit)->mit_lock, LCK_ASSERT_NOTOWNED) #define MIT_SPIN_UNLOCK(_mit) \ lck_spin_unlock(&(_mit)->mit_lock) extern kern_allocation_name_t skmem_tag_netif_filter; extern kern_allocation_name_t skmem_tag_netif_flow; extern kern_allocation_name_t skmem_tag_netif_agent_flow; extern kern_allocation_name_t skmem_tag_netif_llink; extern kern_allocation_name_t skmem_tag_netif_qset; __BEGIN_DECLS extern struct nxdom nx_netif_dom_s; extern struct kern_nexus_domain_provider nx_netif_prov_s; extern struct nx_netif *nx_netif_alloc(zalloc_flags_t); extern void nx_netif_free(struct nx_netif *); extern void nx_netif_retain(struct nx_netif *); extern void nx_netif_release(struct nx_netif *); extern int nx_netif_dev_krings_create(struct nexus_adapter *, struct kern_channel *); extern void nx_netif_dev_krings_delete(struct nexus_adapter *, struct kern_channel *, boolean_t); extern int nx_netif_na_find(struct kern_nexus *, struct kern_channel *, struct chreq *, struct nxbind *, struct proc *, struct nexus_adapter **, boolean_t create); extern int nx_netif_na_special(struct nexus_adapter *, struct kern_channel *, struct chreq *, nxspec_cmd_t); extern int nx_netif_na_special_common(struct nexus_adapter *, struct kern_channel *, struct chreq *, nxspec_cmd_t); extern int nx_netif_common_intr(struct __kern_channel_ring *, struct proc *, uint32_t, uint32_t *); extern int nx_netif_prov_init(struct kern_nexus_domain_provider *); extern int nx_netif_prov_params(struct kern_nexus_domain_provider *, const uint32_t, const struct nxprov_params *, struct nxprov_params *, struct skmem_region_params[SKMEM_REGIONS], uint32_t); extern int nx_netif_prov_mem_new(struct kern_nexus_domain_provider *, struct kern_nexus *, struct nexus_adapter *); extern void nx_netif_prov_fini(struct kern_nexus_domain_provider *); extern int nx_netif_prov_config(struct kern_nexus_domain_provider *, struct kern_nexus *, struct nx_cfg_req *, int, struct proc *, kauth_cred_t); extern int nx_netif_prov_nx_ctor(struct kern_nexus *); extern void nx_netif_prov_nx_dtor(struct kern_nexus *); extern int nx_netif_prov_nx_mem_info(struct kern_nexus *, struct kern_pbufpool **, struct kern_pbufpool **); extern size_t nx_netif_prov_nx_mib_get(struct kern_nexus *nx, struct nexus_mib_filter *, void *, size_t, struct proc *); extern int nx_netif_prov_nx_stop(struct kern_nexus *); extern void nx_netif_reap(struct nexus_netif_adapter *, struct ifnet *, uint32_t, boolean_t); extern void nx_netif_copy_stats(struct nexus_netif_adapter *, struct if_netif_stats *); extern struct nexus_netif_adapter * na_netif_alloc(zalloc_flags_t); extern void na_netif_free(struct nexus_adapter *); extern void na_netif_finalize(struct nexus_netif_adapter *, struct ifnet *); extern void nx_netif_llw_detach_notify(void *); extern void nx_netif_config_interface_advisory(struct kern_nexus *, bool); /* * netif netagent API */ extern void nx_netif_agent_init(struct nx_netif *); extern void nx_netif_agent_fini(struct nx_netif *); extern int nx_netif_netagent_flow_add(struct nx_netif *, struct nx_flow_req *); extern int nx_netif_netagent_flow_del(struct nx_netif *, struct nx_flow_req *); /* * "Interrupt" mitigation API. This is used by the netif adapter to reduce * the number of "interrupt" requests/wakeup to clients on incoming packets. */ extern void nx_netif_mit_init(struct nx_netif *, const struct ifnet *, struct nx_netif_mit *, struct __kern_channel_ring *, boolean_t); extern void nx_netif_mit_cleanup(struct nx_netif_mit *); extern int nx_netif_mit_tx_intr(struct __kern_channel_ring *, struct proc *, uint32_t, uint32_t *); extern int nx_netif_mit_rx_intr(struct __kern_channel_ring *, struct proc *, uint32_t, uint32_t *); /* * Interface filter API */ #define NETIF_FILTER_RX 0x0001 #define NETIF_FILTER_TX 0x0002 #define NETIF_FILTER_SOURCE 0x0004 #define NETIF_FILTER_INJECT 0x0008 extern errno_t nx_netif_filter_inject(struct nexus_netif_adapter *, struct netif_filter *, struct __kern_packet *, uint32_t); extern errno_t nx_netif_filter_add(struct nx_netif *, nexus_port_t, void *, errno_t (*)(void *, struct __kern_packet *, uint32_t), struct netif_filter **); extern errno_t nx_netif_filter_remove(struct nx_netif *, struct netif_filter *); extern void nx_netif_filter_init(struct nx_netif *); extern void nx_netif_filter_fini(struct nx_netif *); extern void nx_netif_filter_enable(struct nx_netif *); extern void nx_netif_filter_disable(struct nx_netif *); /* * These callbacks are invoked when a packet chain has traversed the full * filter chain. */ extern errno_t nx_netif_filter_rx_cb(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern errno_t nx_netif_filter_tx_cb(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); /* * These are called by nx_netif_filter_tx_cb() to feed filtered packets * back to driver. */ extern errno_t nx_netif_filter_tx_processed_mbuf_enqueue(struct nexus_netif_adapter *, mbuf_svc_class_t, struct mbuf *); extern errno_t nx_netif_filter_tx_processed_pkt_enqueue(struct nexus_netif_adapter *, kern_packet_svc_class_t, struct __kern_packet *); /* * Called by nx_netif_na_find() to create a filter nexus adapter. */ extern int netif_filter_na_create(struct kern_nexus *, struct chreq *, struct nexus_adapter **); /* * Callbacks from ifnet */ extern errno_t nx_netif_native_tx_dequeue(struct nexus_netif_adapter *, uint32_t, uint32_t, uint32_t, classq_pkt_t *, classq_pkt_t *, uint32_t *, uint32_t *, boolean_t, errno_t); extern errno_t nx_netif_native_tx_get_len(struct nexus_netif_adapter *, uint32_t, uint32_t *, uint32_t *, errno_t); extern errno_t nx_netif_compat_tx_dequeue(struct nexus_netif_adapter *, uint32_t, uint32_t, uint32_t, classq_pkt_t *, classq_pkt_t *, uint32_t *, uint32_t *, boolean_t, errno_t); extern errno_t nx_netif_compat_tx_get_len(struct nexus_netif_adapter *, uint32_t, uint32_t *, uint32_t *, errno_t); /* * doorbell dequeue tunable */ extern uint32_t nx_netif_doorbell_max_dequeue; /* * Default drop tunable */ extern uint32_t nx_netif_filter_default_drop; /* * Flow API */ #define NETIF_FLOW_SOURCE 0x0001 #define NETIF_FLOW_INJECT 0x0002 #define NETIF_FLOW_OUTBOUND 0x0004 /* Assumes inbound if flag is missing */ extern errno_t nx_netif_demux(struct nexus_netif_adapter *, struct __kern_packet *, struct __kern_packet **, uint32_t); extern errno_t nx_netif_flow_add(struct nx_netif *, nexus_port_t, struct netif_flow_desc *, void *, errno_t (*)(void *, void *, uint32_t), struct netif_flow **); extern errno_t nx_netif_flow_remove(struct nx_netif *, struct netif_flow *); extern void nx_netif_flow_init(struct nx_netif *); extern void nx_netif_flow_fini(struct nx_netif *); extern void nx_netif_flow_enable(struct nx_netif *); extern void nx_netif_flow_disable(struct nx_netif *); extern void nx_netif_snoop(struct nx_netif *, struct __kern_packet *, boolean_t); extern boolean_t nx_netif_validate_macaddr(struct nx_netif *, struct __kern_packet *, uint32_t); extern boolean_t nx_netif_flow_match(struct nx_netif *, struct __kern_packet *, struct netif_flow *, uint32_t); extern struct netif_flow * nx_netif_flow_classify(struct nx_netif *, struct __kern_packet *, uint32_t); extern void nx_netif_flow_release(struct nx_netif *, struct netif_flow *); extern int netif_vp_na_create(struct kern_nexus *, struct chreq *, struct nexus_adapter **); extern errno_t netif_vp_na_channel_event(struct nx_netif *, uint32_t, struct __kern_channel_event *, uint16_t); /* * Disable all checks on inbound/outbound packets on VP adapters */ extern uint32_t nx_netif_vp_accept_all; /* * Utility functions */ extern struct __kern_packet *nx_netif_alloc_packet(struct kern_pbufpool *, uint32_t, kern_packet_t *); extern void nx_netif_free_packet(struct __kern_packet *); extern void nx_netif_free_packet_chain(struct __kern_packet *, int *); extern void netif_ifp_inc_traffic_class_out_pkt(struct ifnet *, uint32_t, uint32_t, uint32_t); #define NETIF_CONVERT_RX 0x0001 #define NETIF_CONVERT_TX 0x0002 extern struct __kern_packet * nx_netif_mbuf_to_filter_pkt_chain(struct nexus_netif_adapter *, struct mbuf *, uint32_t); extern struct mbuf * nx_netif_filter_pkt_to_mbuf_chain(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern struct __kern_packet * nx_netif_pkt_to_filter_pkt(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern struct __kern_packet * nx_netif_pkt_to_filter_pkt_chain(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern struct __kern_packet * nx_netif_filter_pkt_to_pkt_chain(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern struct mbuf * nx_netif_pkt_to_mbuf(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern struct __kern_packet * nx_netif_pkt_to_pkt(struct nexus_netif_adapter *, struct __kern_packet *, uint32_t); extern void nx_netif_mbuf_chain_info(struct mbuf *, struct mbuf **, uint32_t *, uint32_t *); extern void nx_netif_pkt_chain_info(struct __kern_packet *, struct __kern_packet **, uint32_t *, uint32_t *); extern int nx_netif_get_max_mtu(ifnet_t, uint32_t *); extern void nx_netif_mit_config(struct nexus_netif_adapter *, boolean_t *, boolean_t *, boolean_t *, boolean_t *); extern void nx_netif_vp_region_params_adjust(struct nexus_adapter *, struct skmem_region_params *); extern void nx_netif_pktap_output(ifnet_t, int, struct __kern_packet *); extern int netif_rx_notify_default(struct __kern_channel_ring *, struct proc *p, uint32_t); extern int netif_rx_notify_fast(struct __kern_channel_ring *, struct proc *p, uint32_t); extern int netif_llw_rx_notify_default(struct __kern_channel_ring *, struct proc *p, uint32_t); extern int netif_llw_rx_notify_fast(struct __kern_channel_ring *, struct proc *p, uint32_t); extern void netif_receive(struct nexus_netif_adapter *, struct __kern_packet *, struct nexus_pkt_stats *); #define NETIF_XMIT_FLAG_CHANNEL 0x0001 #define NETIF_XMIT_FLAG_HOST 0x0002 #define NETIF_XMIT_FLAG_REDIRECT 0x0004 #define NETIF_XMIT_FLAG_PACING 0x0008 extern void netif_transmit(struct ifnet *, uint32_t); extern int netif_ring_tx_refill(const kern_channel_ring_t, uint32_t, uint32_t, boolean_t, boolean_t *, boolean_t); extern void netif_hwna_set_mode(struct nexus_adapter *, netif_mode_t, void (*)(struct nexus_adapter *, struct __kern_packet *, struct nexus_pkt_stats *)); extern void netif_hwna_clear_mode(struct nexus_adapter *); /* * rxpoll functions */ extern errno_t netif_rxpoll_set_params(struct ifnet *, struct ifnet_poll_params *, boolean_t locked); extern void netif_rxpoll_compat_thread_func(void *, wait_result_t); /* * GSO functions */ extern int netif_gso_dispatch(struct ifnet *ifp, struct mbuf *m); extern void netif_gso_init(void); extern void netif_gso_fini(void); /* * Logical link functions */ extern void nx_netif_llink_retain(struct netif_llink *); extern void nx_netif_llink_release(struct netif_llink **); extern void nx_netif_qset_retain(struct netif_qset *); extern void nx_netif_qset_release(struct netif_qset **); extern void nx_netif_llink_init(struct nx_netif *); extern void nx_netif_llink_fini(struct nx_netif *); extern struct netif_qset * nx_netif_find_qset(struct nx_netif *, uint64_t); extern struct netif_qset * nx_netif_get_default_qset_noref(struct nx_netif *); extern int netif_qset_enqueue(struct netif_qset *, struct __kern_packet *, struct __kern_packet *, uint32_t, uint32_t, uint32_t *, uint32_t *); extern int nx_netif_default_llink_config(struct nx_netif *, struct kern_nexus_netif_llink_init *); extern void nx_netif_llink_config_free(struct nx_netif *); extern int nx_netif_llink_ext_init_default_queues(struct kern_nexus *); extern void nx_netif_llink_ext_fini_default_queues(struct kern_nexus *); extern int nx_netif_validate_llink_config(struct kern_nexus_netif_llink_init *, bool); extern int nx_netif_llink_add(struct nx_netif *, struct kern_nexus_netif_llink_init *, struct netif_llink **); extern int nx_netif_llink_remove(struct nx_netif *, kern_nexus_netif_llink_id_t); extern int nx_netif_notify_steering_info(struct nx_netif *, struct netif_qset *, struct ifnet_traffic_descriptor_common *, bool); __END_DECLS #endif /* CONFIG_NEXUS_NETIF */ #include #include #endif /* _SKYWALK_NEXUS_NETIF_H_ */