xref: /xnu-8020.121.3/bsd/skywalk/nexus/nexus_var.h (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
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 /*
30  * Copyright (C) 2012-2014 Matteo Landi, Luigi Rizzo, Giuseppe Lettieri.
31  * All rights reserved.
32  * Copyright (C) 2013-2014 Universita` di Pisa. All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  *   1. Redistributions of source code must retain the above copyright
38  *      notice, this list of conditions and the following disclaimer.
39  *   2. Redistributions in binary form must reproduce the above copyright
40  *      notice, this list of conditions and the following disclaimer in the
41  *    documentation and/or other materials provided with the distribution.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
44  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53  * SUCH DAMAGE.
54  */
55 
56 #ifndef _SKYWALK_NEXUS_NEXUSVAR_H_
57 #define _SKYWALK_NEXUS_NEXUSVAR_H_
58 
59 #ifdef BSD_KERNEL_PRIVATE
60 #include <skywalk/core/skywalk_var.h>
61 #include <skywalk/os_nexus_private.h>
62 
63 struct chreq;
64 struct nxdom;
65 struct kern_channel;
66 struct kern_nexus_domain_provider;
67 
68 /*
69  * Nexus controller instance.
70  */
71 struct nxctl {
72 	decl_lck_mtx_data(, nxctl_lock);
73 	uint32_t                nxctl_refcnt;
74 	uint32_t                nxctl_flags;
75 	uuid_t                  nxctl_uuid;
76 	uuid_t                  nxctl_proc_uuid;
77 	uint64_t                nxctl_proc_uniqueid;
78 	STAILQ_ENTRY(nxctl)     nxctl_link;
79 	struct fileproc         *nxctl_fp;
80 	kauth_cred_t            nxctl_cred;
81 };
82 
83 #define NEXUSCTLF_ATTACHED      0x1
84 #define NEXUSCTLF_NOFDREF       0x2
85 #define NEXUSCTLF_KERNEL        0x4
86 
87 #define NEXUSCTLF_BITS  \
88 	"\020\01ATTACHED\02NOFDREF\03KERNEL"
89 
90 /*
91  * Nexus port binding structure.
92  */
93 struct nxbind {
94 	uint32_t                nxb_flags;
95 	pid_t                   nxb_pid;
96 	uint64_t                nxb_uniqueid;
97 	uuid_t                  nxb_exec_uuid;
98 	uint32_t                nxb_key_len;
99 	void                    *nxb_key;
100 };
101 
102 #define NXBF_MATCH_UNIQUEID     0x1     /* match against process's unique ID */
103 #define NXBF_MATCH_EXEC_UUID    0x2     /* match against executable's UUID */
104 #define NXBF_MATCH_KEY          0x4     /* match against key blob */
105 
106 #define NXBF_BITS       \
107 	"\020\01UNIQUEID\02EXEC_UUID\03KEY"
108 
109 /*
110  * Nexus port info structure.
111  */
112 struct nx_port_info {
113 	/*
114 	 * We need to store some states on the nexus port info,
115 	 * e.g. defunct.  The states are encoded in the tagged
116 	 * pointer handle npi_nah.
117 	 */
118 	uintptr_t               npi_nah;
119 	struct nxbind           *npi_nxb;
120 	void                    *npi_info;
121 };
122 
123 /*
124  * Used for indicating what type is attached to npi_info
125  * The type enum is defined here. One namespace for all nexus types.
126  * The actual structure is defined in nexus specific headers.
127  */
128 typedef enum {
129 	NX_PORT_INFO_TYPE_NETIF = 0x10000001
130 } nx_port_info_type_t;
131 
132 /*
133  * Header of nexus specific structure npi_info
134  */
135 struct nx_port_info_header {
136 	nx_port_info_type_t     ih_type;
137 	size_t                  ih_size;
138 };
139 
140 #define NX_PORT_CHUNK      64
141 #define NX_PORT_CHUNK_FREE 0xffffffffffffffff /* entire chunk is free */
142 
143 /*
144  * Nexus port state type.
145  *
146  * Be mindful that due to the use of tagger pointer for nexus adapter in the
147  * nexus port info structure, this type gets encoded with the requirement
148  * that the object addresses are aligned on 4-bytes boundary at the minimum.
149  * That leaves 2 bits for the states, therefore limiting the maximum enum
150  * value to 3.
151  */
152 typedef enum {
153 	NEXUS_PORT_STATE_WORKING = 0,           /* fully operational */
154 	NEXUS_PORT_STATE_DEFUNCT,               /* no longer in service */
155 	NEXUS_PORT_STATE_RESERVED_1,            /* for future use */
156 	NEXUS_PORT_STATE_RESERVED_2,            /* for future use */
157 	NEXUS_PORT_STATE_MAX = NEXUS_PORT_STATE_RESERVED_2
158 } nexus_port_state_t;
159 
160 #define NPI_NA_STATE_MASK       ((uintptr_t)0x3)        /* 11 */
161 #define NPI_NA_TAG_MASK         ((uintptr_t)0x3)        /* 11 */
162 
163 #define NPI_NA_TAG(_p)          ((uintptr_t)(_p) & NPI_NA_TAG_MASK)
164 #define NPI_NA_ADDR_MASK        (~NPI_NA_TAG_MASK)
165 
166 #define NPI_NA_STATE(_p)        ((uintptr_t)(_p) & NPI_NA_STATE_MASK)
167 #define NPI_NA_STATE_ENC(_s)    ((uintptr_t)(_s) & NPI_NA_STATE_MASK)
168 
169 #define NPI_NA_ADDR(_p)         ((uintptr_t)(_p) & NPI_NA_ADDR_MASK)
170 #define NPI_NA_ADDR_ENC(_p)     ((uintptr_t)(_p) & NPI_NA_ADDR_MASK)
171 
172 #define NPI_NA_ENCODE(_p, _s)   (NPI_NA_ADDR_ENC(_p) | NPI_NA_STATE_ENC(_s))
173 
174 #define NPI_NA(_npi)            \
175 	((struct nexus_adapter *)NPI_NA_ADDR((_npi)->npi_nah))
176 #define NPI_IS_DEFUNCT(_npi)    \
177 	(NPI_NA_STATE((_npi)->npi_nah) == NEXUS_PORT_STATE_DEFUNCT)
178 
179 /*
180  * Nexus-wide advisory region and object.
181  */
182 struct kern_nexus_advisory {
183 	struct skmem_region     *nxv_reg;
184 	void                    *nxv_adv;
185 	nexus_advisory_type_t   nxv_adv_type;
186 	union {
187 		struct sk_nexusadv             *flowswitch_nxv_adv;
188 		struct netif_nexus_advisory    *netif_nxv_adv;
189 	};
190 };
191 
192 /*
193  * Nexus instance.
194  *
195  * At present most fields are protected by sk_lock.  The exception is
196  * the nx_ch_if_adv_head list which uses nx_ch_if_adv_lock instead.
197  *
198  * In cases where sk_lock, nx_ch_if_adv_lock and ch_lock must be held,
199  * the following ordering needs to be followed:
200  *
201  *   sk_lock -> nx_ch_if_adv_lock -> ch_lock
202  */
203 struct kern_nexus {
204 	uint32_t                nx_refcnt;
205 	volatile uint32_t       nx_flags;
206 	void                    *nx_ctx;
207 	nexus_ctx_release_fn_t  nx_ctx_release;
208 	struct kern_nexus_provider *nx_prov;
209 	uint64_t                nx_id;
210 	uuid_t                  nx_uuid;
211 	STAILQ_ENTRY(kern_nexus) nx_prov_link;
212 	RB_ENTRY(kern_nexus)    nx_link;
213 	STAILQ_HEAD(, kern_channel) nx_ch_head;
214 	uint32_t                nx_ch_count;
215 	STAILQ_HEAD(, kern_channel) nx_ch_nonxref_head;
216 	decl_lck_rw_data(, nx_ch_if_adv_lock);
217 	STAILQ_HEAD(, kern_channel) nx_ch_if_adv_head;
218 	void                    *nx_arg;
219 	struct kern_pbufpool    *nx_rx_pp;
220 	struct kern_pbufpool    *nx_tx_pp;
221 	struct kern_nexus_advisory nx_adv;
222 
223 	/* nexus port */
224 	struct nx_port_info     *nx_ports;
225 	bitmap_t                *nx_ports_bmap;
226 	uint32_t                nx_active_ports;
227 	uint32_t                nx_num_ports;
228 };
229 
230 #define NXF_ATTACHED    0x1
231 #define NXF_CLOSED      0x2             /* attached but closed */
232 #define NXF_REJECT      (1U << 31)      /* not accepting channel activities */
233 
234 #define NXF_BITS        \
235 	"\020\01ATTACHED\02CLOSED\040REJECT"
236 
237 #define NX_PROV(_nx)            ((_nx)->nx_prov)
238 #define NX_DOM_PROV(_nx)        (NX_PROV(_nx)->nxprov_dom_prov)
239 #define NX_DOM(_nx)             (NX_DOM_PROV(_nx)->nxdom_prov_dom)
240 
241 #define NX_REJECT_ACT(_nx)      (((_nx)->nx_flags & NXF_REJECT) != 0)
242 
243 /*
244  * Nexus provider.
245  */
246 struct kern_nexus_provider {
247 	uint32_t                        nxprov_refcnt;
248 	uint32_t                        nxprov_flags;
249 	STAILQ_ENTRY(kern_nexus_provider) nxprov_link;
250 	STAILQ_HEAD(, kern_nexus)       nxprov_nx_head;
251 	uint32_t                        nxprov_nx_count;
252 	struct nxctl                    *nxprov_ctl;
253 	uuid_t                          nxprov_uuid;
254 	struct kern_nexus_domain_provider *nxprov_dom_prov;
255 	union {
256 		struct kern_nexus_provider_init nxprov_ext;
257 		struct kern_nexus_netif_provider_init nxprov_netif_ext;
258 	};
259 	struct nxprov_params            *nxprov_params;
260 	struct skmem_region_params      nxprov_region_params[SKMEM_REGIONS];
261 };
262 
263 /* valid flags for nxprov_flags */
264 #define NXPROVF_ATTACHED        0x1     /* attached to global list */
265 #define NXPROVF_CLOSED          0x2     /* attached but closed */
266 #define NXPROVF_EXTERNAL        0x4     /* external nexus provider */
267 #define NXPROVF_VIRTUAL_DEVICE  0x8     /* device is virtual (no DMA) */
268 
269 #define NXPROV_LLINK(_nxp) \
270 	((_nxp)->nxprov_params->nxp_flags & NXPF_NETIF_LLINK)
271 
272 #define NXPROVF_BITS    \
273 	"\020\01ATTACHED\02CLOSED\03EXTERNAL\04VIRTUALDEV"
274 
275 #define NX_ANONYMOUS_PROV(_nx)  \
276 	(NX_PROV(_nx)->nxprov_params->nxp_flags & NXPF_ANONYMOUS)
277 #define NX_USER_CHANNEL_PROV(_nx) \
278 	(NX_PROV(_nx)->nxprov_params->nxp_flags & NXPF_USER_CHANNEL)
279 #define NX_LLINK_PROV(_nx)    NXPROV_LLINK(NX_PROV(_nx))
280 
281 /*
282  * Nexus domain provider.
283  */
284 struct kern_nexus_domain_provider {
285 	STAILQ_ENTRY(kern_nexus_domain_provider) nxdom_prov_link;
286 	STAILQ_ENTRY(kern_nexus_domain_provider) nxdom_prov_detaching_link;
287 	char                    nxdom_prov_name[64];
288 	uuid_t                  nxdom_prov_uuid;
289 	uint64_t                nxdom_prov_gencnt;
290 	uint32_t                nxdom_prov_refcnt;
291 	uint32_t                nxdom_prov_flags;
292 	struct nxdom            *nxdom_prov_dom;
293 	struct kern_nexus_domain_provider_init nxdom_prov_ext;
294 	/*
295 	 * The callbacks are grouped together to simplify the
296 	 * initialization of external domain providers; see
297 	 * kern_nexus_register_domain_provider() for details.
298 	 */
299 	struct nxdom_prov_cb {
300 		int (*dp_cb_init)(struct kern_nexus_domain_provider *);
301 		void (*dp_cb_fini)(struct kern_nexus_domain_provider *);
302 		int (*dp_cb_params)(struct kern_nexus_domain_provider *,
303 		    const uint32_t, const struct nxprov_params *,
304 		    struct nxprov_params *,
305 		    struct skmem_region_params[SKMEM_REGIONS]);
306 		int (*dp_cb_mem_new)(struct kern_nexus_domain_provider *,
307 		    struct kern_nexus *, struct nexus_adapter *);
308 		int (*dp_cb_config)(struct kern_nexus_domain_provider *,
309 		    struct kern_nexus *, struct nx_cfg_req *, int,
310 		    struct proc *, kauth_cred_t);
311 		int (*dp_cb_nx_ctor)(struct kern_nexus *);
312 		void (*dp_cb_nx_dtor)(struct kern_nexus *);
313 		int (*dp_cb_nx_mem_info)(struct kern_nexus *,
314 		    struct kern_pbufpool **, struct kern_pbufpool **);
315 		size_t (*dp_cb_nx_mib_get)(struct kern_nexus *,
316 		    struct nexus_mib_filter *, void *, size_t, struct proc *);
317 		int (*dp_cb_nx_stop)(struct kern_nexus *);
318 	} nxdom_prov_cb;
319 #define nxdom_prov_init         nxdom_prov_cb.dp_cb_init
320 #define nxdom_prov_fini         nxdom_prov_cb.dp_cb_fini
321 #define nxdom_prov_params       nxdom_prov_cb.dp_cb_params
322 #define nxdom_prov_mem_new      nxdom_prov_cb.dp_cb_mem_new
323 #define nxdom_prov_config       nxdom_prov_cb.dp_cb_config
324 #define nxdom_prov_nx_ctor      nxdom_prov_cb.dp_cb_nx_ctor
325 #define nxdom_prov_nx_dtor      nxdom_prov_cb.dp_cb_nx_dtor
326 #define nxdom_prov_nx_mem_info  nxdom_prov_cb.dp_cb_nx_mem_info
327 #define nxdom_prov_nx_mib_get   nxdom_prov_cb.dp_cb_nx_mib_get
328 #define nxdom_prov_nx_stop      nxdom_prov_cb.dp_cb_nx_stop
329 };
330 
331 #define NXDOMPROVF_INITIALIZED  0x1     /* provider has been initialized */
332 #define NXDOMPROVF_ATTACHED     0x2     /* provider is attached to a domain */
333 #define NXDOMPROVF_DETACHING    0x4     /* provider is being detached */
334 #define NXDOMPROVF_EXT          0x8     /* external provider */
335 #define NXDOMPROVF_EXT_INITED   0x10    /* nxpi_init() succeeded */
336 #define NXDOMPROVF_DEFAULT      0x20    /* default provider for domain */
337 
338 struct nxp_bounds {
339 	uint32_t        nb_def;
340 	uint32_t        nb_min;
341 	uint32_t        nb_max;
342 };
343 
344 /*
345  * Nexus domain.
346  *
347  * Each Nexus type is represented by a Nexus domain; there can
348  * be more than one providers for a given domain.
349  */
350 struct nxdom {
351 	STAILQ_ENTRY(nxdom) nxdom_link;
352 	STAILQ_HEAD(, kern_nexus_domain_provider) nxdom_prov_head;
353 	nexus_type_t    nxdom_type;
354 	nexus_meta_type_t nxdom_md_type;
355 	nexus_meta_subtype_t nxdom_md_subtype;
356 	uint32_t        nxdom_flags;
357 	struct nxp_bounds nxdom_ports;
358 	struct nxp_bounds nxdom_tx_rings;
359 	struct nxp_bounds nxdom_rx_rings;
360 	struct nxp_bounds nxdom_tx_slots;
361 	struct nxp_bounds nxdom_rx_slots;
362 	struct nxp_bounds nxdom_buf_size;
363 	struct nxp_bounds nxdom_meta_size;
364 	struct nxp_bounds nxdom_stats_size;
365 	struct nxp_bounds nxdom_pipes;
366 	struct nxp_bounds nxdom_extensions;
367 	struct nxp_bounds nxdom_mhints;
368 	struct nxp_bounds nxdom_flowadv_max;
369 	struct nxp_bounds nxdom_nexusadv_size;
370 	struct nxp_bounds nxdom_capabilities;
371 	struct nxp_bounds nxdom_qmap;
372 	struct nxp_bounds nxdom_max_frags;
373 	struct skmem_region_params nxdom_region_params[SKMEM_REGIONS];
374 	const char      *nxdom_name;
375 
376 	/*
377 	 * Nexus domain callbacks.
378 	 */
379 	void (*nxdom_init)(struct nxdom *);             /* optional */
380 	void (*nxdom_terminate)(struct nxdom *);        /* optional */
381 	void (*nxdom_fini)(struct nxdom *);             /* optional */
382 	int (*nxdom_find_port)                          /* optional */
383 	(struct kern_nexus *, boolean_t, nexus_port_t *);
384 	boolean_t (*nxdom_port_is_reserved)             /* optional */
385 	(struct kern_nexus *, nexus_port_t);
386 	int (*nxdom_bind_port)                          /* required */
387 	(struct kern_nexus *, nexus_port_t *, struct nxbind *, void *);
388 	int (*nxdom_unbind_port)                        /* required */
389 	(struct kern_nexus *, nexus_port_t);
390 	int (*nxdom_connect)                            /* required */
391 	(struct kern_nexus_domain_provider *, struct kern_nexus *,
392 	struct kern_channel *, struct chreq *, struct kern_channel *,
393 	struct nxbind *, struct proc *);
394 	void (*nxdom_disconnect)                        /* required */
395 	(struct kern_nexus_domain_provider *, struct kern_nexus *,
396 	struct kern_channel *);
397 	void (*nxdom_defunct)                           /* required */
398 	(struct kern_nexus_domain_provider *, struct kern_nexus *,
399 	struct kern_channel *, struct proc *);
400 	void (*nxdom_defunct_finalize)                  /* required */
401 	(struct kern_nexus_domain_provider *, struct kern_nexus *,
402 	struct kern_channel *, boolean_t);
403 };
404 
405 #define NEXUSDOMF_INITIALIZED   0x1     /* domain has been initialized */
406 #define NEXUSDOMF_ATTACHED      0x2     /* domain is globally attached */
407 #define NEXUSDOMF_TERMINATED    0x4     /* domain has been terminated */
408 
409 #define NXDOM_DEF(_dom, var)    ((_dom)->nxdom_##var.nb_def)
410 #define NXDOM_MIN(_dom, var)    ((_dom)->nxdom_##var.nb_min)
411 #define NXDOM_MAX(_dom, var)    ((_dom)->nxdom_##var.nb_max)
412 
413 extern struct nexus_controller kernnxctl;
414 extern lck_grp_t nexus_lock_group;
415 extern lck_grp_t nexus_mbq_lock_group;
416 extern lck_grp_t nexus_pktq_lock_group;
417 extern lck_attr_t nexus_lock_attr;
418 extern kern_allocation_name_t skmem_tag_nx_key;
419 extern kern_allocation_name_t skmem_tag_nx_port_info;
420 
421 extern struct kern_nexus_domain_provider *nxdom_prov_default[NEXUS_TYPE_MAX];
422 
423 #define NX_SHARED_NXCTL_INSTANCE(_nxctl)        \
424     ((_nxctl) == kernnxctl.ncd_nxctl)
425 
426 #define NXCTL_LOCK(_nxctl)      do {                    \
427 	if (!NX_SHARED_NXCTL_INSTANCE((_nxctl))) {      \
428 	        lck_mtx_lock(&((_nxctl)->nxctl_lock));  \
429 	} else {                                        \
430 	        LCK_MTX_ASSERT(&((_nxctl)->nxctl_lock), \
431 	            LCK_MTX_ASSERT_NOTOWNED);           \
432 	}                                               \
433 } while (0)
434 
435 #define NXCTL_UNLOCK(_nxctl)    do {                    \
436 	if (!NX_SHARED_NXCTL_INSTANCE((_nxctl))) {      \
437 	        lck_mtx_unlock(&((_nxctl)->nxctl_lock));\
438 	}                                               \
439 	LCK_MTX_ASSERT(&((_nxctl)->nxctl_lock),         \
440 	    LCK_MTX_ASSERT_NOTOWNED);                   \
441 } while (0)
442 
443 #define NXCTL_LOCK_ASSERT_HELD(_nxctl)  do {            \
444 	if (!NX_SHARED_NXCTL_INSTANCE((_nxctl))) {      \
445 	        LCK_MTX_ASSERT(&((_nxctl)->nxctl_lock), \
446 	            LCK_MTX_ASSERT_OWNED);              \
447 	} else {                                        \
448 	        LCK_MTX_ASSERT(&((_nxctl)->nxctl_lock), \
449 	            LCK_MTX_ASSERT_NOTOWNED);           \
450 	}                                               \
451 } while (0)
452 
453 __BEGIN_DECLS
454 extern int nexus_init(void);
455 extern void nexus_fini(void);
456 
457 extern struct kern_nexus *nx_create(struct nxctl *, const uuid_t,
458     const nexus_type_t, const void *, nexus_ctx_release_fn_t,
459     struct kern_pbufpool *, struct kern_pbufpool *, int *);
460 extern void nx_retain(struct kern_nexus *);
461 extern void nx_retain_locked(struct kern_nexus *);
462 extern int nx_release(struct kern_nexus *);
463 extern int nx_release_locked(struct kern_nexus *);
464 extern void nx_detach(struct kern_nexus *);
465 extern void nx_stop(struct kern_nexus *nx);
466 extern int nx_close(struct kern_nexus *, boolean_t);
467 extern int nx_destroy(struct nxctl *, const uuid_t);
468 extern struct kern_nexus *nx_find(const uuid_t, boolean_t);
469 extern int nx_advisory_alloc(struct kern_nexus *, const char *,
470     struct skmem_region_params *, nexus_advisory_type_t);
471 extern void nx_advisory_free(struct kern_nexus *);
472 extern int nx_port_find(struct kern_nexus *, nexus_port_t,
473     nexus_port_t, nexus_port_t *);
474 extern int nx_port_alloc(struct kern_nexus *, nexus_port_t,
475     struct nxbind *, struct nexus_adapter **, struct proc *);
476 extern int nx_port_bind(struct kern_nexus *, nexus_port_t,
477     struct nxbind *);
478 extern int nx_port_bind_info(struct kern_nexus *, nexus_port_t,
479     struct nxbind *, void *);
480 extern int nx_port_unbind(struct kern_nexus *, nexus_port_t);
481 extern struct nexus_adapter *nx_port_get_na(struct kern_nexus *,
482     nexus_port_t);
483 extern int nx_port_get_info(struct kern_nexus *, nexus_port_t,
484     nx_port_info_type_t, void *, uint32_t);
485 extern void nx_port_defunct(struct kern_nexus *, nexus_port_t);
486 extern void nx_port_free(struct kern_nexus *, nexus_port_t);
487 extern void nx_port_free_all(struct kern_nexus *);
488 extern bool nx_port_is_valid(struct kern_nexus *, nexus_port_t);
489 extern bool nx_port_is_defunct(struct kern_nexus *, nexus_port_t);
490 extern void nx_port_foreach(struct kern_nexus *, void (^)(nexus_port_t));
491 extern void nx_interface_advisory_notify(struct kern_nexus *);
492 
493 extern struct nxctl *nxctl_create(struct proc *, struct fileproc *,
494     const uuid_t, int *);
495 extern void nxctl_close(struct nxctl *nxctl);
496 extern int nxctl_get_opt(struct nxctl *, struct sockopt *);
497 extern int nxctl_set_opt(struct nxctl *, struct sockopt *);
498 extern void nxctl_retain(struct nxctl *);
499 extern int nxctl_release(struct nxctl *);
500 extern void nxctl_dtor(void *);
501 
502 extern int nxprov_advise_connect(struct kern_nexus *, struct kern_channel *,
503     struct proc *p);
504 extern void nxprov_advise_disconnect(struct kern_nexus *,
505     struct kern_channel *);
506 extern struct kern_nexus_provider *nxprov_create(struct proc *,
507     struct nxctl *, struct nxprov_reg *, int *);
508 extern struct kern_nexus_provider *nxprov_create_kern(struct nxctl *,
509     struct kern_nexus_domain_provider *, struct nxprov_reg *,
510     const struct kern_nexus_provider_init *init, int *err);
511 extern int nxprov_close(struct kern_nexus_provider *, boolean_t);
512 extern int nxprov_destroy(struct nxctl *, const uuid_t);
513 extern void nxprov_retain(struct kern_nexus_provider *);
514 extern int nxprov_release(struct kern_nexus_provider *);
515 extern struct nxprov_params *nxprov_params_alloc(zalloc_flags_t);
516 extern void nxprov_params_free(struct nxprov_params *);
517 
518 struct nxprov_adjusted_params {
519 	nexus_meta_subtype_t *adj_md_subtype;
520 	boolean_t *adj_md_magazines;
521 	uint32_t *adj_stats_size;
522 	uint32_t *adj_flowadv_max;
523 	uint32_t *adj_nexusadv_size;
524 	uint32_t *adj_caps;
525 	uint32_t *adj_tx_rings;
526 	uint32_t *adj_rx_rings;
527 	uint32_t *adj_tx_slots;
528 	uint32_t *adj_rx_slots;
529 	uint32_t *adj_alloc_rings;
530 	uint32_t *adj_free_rings;
531 	uint32_t *adj_alloc_slots;
532 	uint32_t *adj_free_slots;
533 	uint32_t *adj_buf_size;
534 	struct skmem_region_params *adj_buf_srp;
535 	uint32_t *adj_max_frags;
536 	uint32_t *adj_event_rings;
537 	uint32_t *adj_event_slots;
538 	uint32_t *adj_max_buffers;
539 };
540 
541 extern int nxprov_params_adjust(struct kern_nexus_domain_provider *,
542     const uint32_t, const struct nxprov_params *, struct nxprov_params *,
543     struct skmem_region_params[SKMEM_REGIONS], const struct nxdom *,
544     const struct nxdom *, const struct nxdom *,
545     int (*adjust_fn)(const struct kern_nexus_domain_provider *,
546     const struct nxprov_params *, struct nxprov_adjusted_params *));
547 
548 extern void nxdom_attach_all(void);
549 extern void nxdom_detach_all(void);
550 extern struct nxdom *nxdom_find(nexus_type_t);
551 
552 extern struct kern_nexus_domain_provider *nxdom_prov_find(
553 	const struct nxdom *, const char *);
554 extern struct kern_nexus_domain_provider *nxdom_prov_find_uuid(const uuid_t);
555 extern int nxdom_prov_add(struct nxdom *, struct kern_nexus_domain_provider *);
556 extern void nxdom_prov_del(struct kern_nexus_domain_provider *);
557 extern void nxdom_prov_retain_locked(struct kern_nexus_domain_provider *);
558 extern void nxdom_prov_retain(struct kern_nexus_domain_provider *);
559 extern boolean_t nxdom_prov_release_locked(struct kern_nexus_domain_provider *);
560 extern boolean_t nxdom_prov_release(struct kern_nexus_domain_provider *);
561 extern int nxdom_prov_validate_params(struct kern_nexus_domain_provider *,
562     const struct nxprov_reg *, struct nxprov_params *,
563     struct skmem_region_params[SKMEM_REGIONS], const uint32_t);
564 
565 extern struct nxbind *nxb_alloc(zalloc_flags_t);
566 extern void nxb_free(struct nxbind *);
567 extern boolean_t nxb_is_equal(struct nxbind *, struct nxbind *);
568 extern void nxb_move(struct nxbind *, struct nxbind *);
569 
570 typedef void kern_nexus_walktree_f_t(struct kern_nexus *, void *);
571 extern void kern_nexus_walktree(kern_nexus_walktree_f_t *, void *, boolean_t);
572 
573 extern int kern_nexus_get_pbufpool_info(const uuid_t nx_uuid,
574     struct kern_pbufpool_memory_info *rx_pool,
575     struct kern_pbufpool_memory_info *tx_pool);
576 __END_DECLS
577 
578 #include <skywalk/nexus/nexus_adapter.h>
579 
580 __attribute__((always_inline))
581 static inline int
nx_sync_tx(struct __kern_channel_ring * kring,boolean_t commit)582 nx_sync_tx(struct __kern_channel_ring *kring, boolean_t commit)
583 {
584 	struct kern_nexus_provider *nxprov = NX_PROV(KRNA(kring)->na_nx);
585 
586 	ASSERT(kring->ckr_tx == NR_TX);
587 	if (nxprov->nxprov_ext.nxpi_sync_tx != NULL) {
588 		return nxprov->nxprov_ext.nxpi_sync_tx(nxprov,
589 		           KRNA(kring)->na_nx, kring,
590 		           (commit ? KERN_NEXUS_SYNCF_COMMIT : 0));
591 	} else {
592 		return 0;
593 	}
594 }
595 
596 __attribute__((always_inline))
597 static inline int
nx_sync_rx(struct __kern_channel_ring * kring,boolean_t commit)598 nx_sync_rx(struct __kern_channel_ring *kring, boolean_t commit)
599 {
600 	struct kern_nexus_provider *nxprov = NX_PROV(KRNA(kring)->na_nx);
601 
602 	ASSERT(kring->ckr_tx == NR_RX);
603 	if (nxprov->nxprov_ext.nxpi_sync_rx != NULL) {
604 		return nxprov->nxprov_ext.nxpi_sync_rx(nxprov,
605 		           KRNA(kring)->na_nx, kring,
606 		           (commit ? KERN_NEXUS_SYNCF_COMMIT : 0));
607 	} else {
608 		return 0;
609 	}
610 }
611 
612 __attribute__((always_inline))
613 static __inline__ void
nx_tx_doorbell(struct __kern_channel_ring * kring,boolean_t async)614 nx_tx_doorbell(struct __kern_channel_ring *kring, boolean_t async)
615 {
616 	struct kern_nexus_provider *nxprov = NX_PROV(KRNA(kring)->na_nx);
617 
618 	ASSERT(kring->ckr_tx == NR_TX);
619 	ASSERT(nxprov->nxprov_ext.nxpi_tx_doorbell != NULL);
620 	nxprov->nxprov_ext.nxpi_tx_doorbell(nxprov, KRNA(kring)->na_nx,
621 	    kring, (async ? KERN_NEXUS_TXDOORBELLF_ASYNC_REFILL: 0));
622 }
623 
624 __attribute__((always_inline))
625 static inline int
nx_rx_sync_packets(struct __kern_channel_ring * kring,uint64_t packets[],uint32_t * count)626 nx_rx_sync_packets(struct __kern_channel_ring *kring, uint64_t packets[],
627     uint32_t *count)
628 {
629 	struct kern_nexus_provider *nxprov = NX_PROV(KRNA(kring)->na_nx);
630 
631 	ASSERT(kring->ckr_tx == NR_RX);
632 	if (nxprov->nxprov_ext.nxpi_rx_sync_packets != NULL) {
633 		return nxprov->nxprov_ext.nxpi_rx_sync_packets(nxprov,
634 		           KRNA(kring)->na_nx, kring, packets, count, 0);
635 	} else {
636 		return 0;
637 	}
638 }
639 
640 __attribute__((always_inline))
641 static inline boolean_t
nx_has_rx_sync_packets(struct __kern_channel_ring * kring)642 nx_has_rx_sync_packets(struct __kern_channel_ring *kring)
643 {
644 	struct kern_nexus_provider *nxprov = NX_PROV(KRNA(kring)->na_nx);
645 
646 	ASSERT(kring->ckr_tx == NR_RX);
647 	return nxprov->nxprov_ext.nxpi_rx_sync_packets != NULL;
648 }
649 
650 __attribute__((always_inline))
651 static __inline__ errno_t
nx_tx_qset_notify(struct kern_nexus * nx,struct netif_qset * qset)652 nx_tx_qset_notify(struct kern_nexus *nx, struct netif_qset *qset)
653 {
654 	struct kern_nexus_provider *nxprov = NX_PROV(nx);
655 	sk_protect_t protect;
656 	errno_t err;
657 
658 	ASSERT(nxprov->nxprov_netif_ext.nxnpi_tx_qset_notify != NULL);
659 	protect = sk_tx_notify_protect();
660 	err = nxprov->nxprov_netif_ext.nxnpi_tx_qset_notify(nxprov, nx, qset, 0);
661 	sk_tx_notify_unprotect(protect);
662 	return err;
663 }
664 #endif /* BSD_KERNEL_PRIVATE */
665 #endif /* _SKYWALK_NEXUS_NEXUSVAR_H_ */
666