2 * Copyright (c) 2008-2020 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
31 /* ----------------------------------------------------------------------------------
32 * Application of kernel control for interface creation
34 * Theory of operation:
35 * utun (user tunnel) acts as glue between kernel control sockets and network interfaces.
36 * This kernel control will register an interface for every client that connects.
37 * ---------------------------------------------------------------------------------- */
39 #include <sys/systm.h>
40 #include <sys/kern_control.h>
41 #include <net/kpi_protocol.h>
42 #include <net/kpi_interface.h>
43 #include <sys/socket.h>
45 #include <net/if_types.h>
47 #include <net/if_utun.h>
49 #include <sys/sockio.h>
50 #include <netinet/in.h>
51 #include <netinet/ip.h>
52 #include <netinet6/in6_var.h>
53 #include <netinet6/in6_var.h>
54 #include <sys/kauth.h>
56 #include <kern/zalloc.h>
62 static nexus_controller_t utun_ncd
;
63 static int utun_ncd_refcount
;
64 static uuid_t utun_kpipe_uuid
;
65 static uuid_t utun_nx_dom_prov
;
67 typedef struct utun_nx
{
79 /* Control block allocated for each kernel control connection */
81 TAILQ_ENTRY(utun_pcb
) utun_chain
;
82 kern_ctl_ref utun_ctlref
;
85 u_int32_t utun_unique_id
;
87 int utun_ext_ifdata_stats
;
88 u_int32_t utun_max_pending_packets
;
89 char utun_if_xname
[IFXNAMSIZ
];
90 char utun_unique_name
[IFXNAMSIZ
];
91 // PCB lock protects state fields and rings
92 decl_lck_rw_data(, utun_pcb_lock
);
93 struct mbuf
* utun_input_chain
;
94 struct mbuf
* utun_input_chain_last
;
95 u_int32_t utun_input_chain_count
;
96 // Input chain lock protects the list of input mbufs
97 // The input chain lock must be taken AFTER the PCB lock if both are held
98 lck_mtx_t utun_input_chain_lock
;
101 struct utun_nx utun_nx
;
102 int utun_kpipe_enabled
;
103 uuid_t utun_kpipe_uuid
;
104 void * utun_kpipe_rxring
;
105 void * utun_kpipe_txring
;
106 kern_pbufpool_t utun_kpipe_pp
;
107 u_int32_t utun_kpipe_tx_ring_size
;
108 u_int32_t utun_kpipe_rx_ring_size
;
110 kern_nexus_t utun_netif_nexus
;
111 kern_pbufpool_t utun_netif_pp
;
112 void * utun_netif_rxring
;
113 void * utun_netif_txring
;
114 uint64_t utun_netif_txring_size
;
116 u_int32_t utun_slot_size
;
117 u_int32_t utun_netif_ring_size
;
118 u_int32_t utun_tx_fsw_ring_size
;
119 u_int32_t utun_rx_fsw_ring_size
;
120 // Auto attach flowswitch when netif is enabled. When set to false,
121 // it allows userspace nexus controller to attach and own flowswitch.
122 bool utun_attach_fsw
;
123 bool utun_netif_connected
;
125 bool utun_needs_netagent
;
129 /* Kernel Control functions */
130 static errno_t
utun_ctl_setup(u_int32_t
*unit
, void **unitinfo
);
131 static errno_t
utun_ctl_bind(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
133 static errno_t
utun_ctl_connect(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
135 static errno_t
utun_ctl_disconnect(kern_ctl_ref kctlref
, u_int32_t unit
,
137 static errno_t
utun_ctl_send(kern_ctl_ref kctlref
, u_int32_t unit
,
138 void *unitinfo
, mbuf_t m
, int flags
);
139 static errno_t
utun_ctl_getopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
140 int opt
, void *data
, size_t *len
);
141 static errno_t
utun_ctl_setopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
142 int opt
, void *data
, size_t len
);
143 static void utun_ctl_rcvd(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
146 /* Network Interface functions */
147 static void utun_start(ifnet_t interface
);
148 static errno_t
utun_framer(ifnet_t interface
, mbuf_t
*packet
,
149 const struct sockaddr
*dest
, const char *desk_linkaddr
,
150 const char *frame_type
, u_int32_t
*prepend_len
, u_int32_t
*postpend_len
);
151 static errno_t
utun_output(ifnet_t interface
, mbuf_t data
);
152 static errno_t
utun_demux(ifnet_t interface
, mbuf_t data
, char *frame_header
,
153 protocol_family_t
*protocol
);
154 static errno_t
utun_add_proto(ifnet_t interface
, protocol_family_t protocol
,
155 const struct ifnet_demux_desc
*demux_array
,
156 u_int32_t demux_count
);
157 static errno_t
utun_del_proto(ifnet_t interface
, protocol_family_t protocol
);
158 static errno_t
utun_ioctl(ifnet_t interface
, u_long cmd
, void *data
);
159 static void utun_detached(ifnet_t interface
);
161 /* Protocol handlers */
162 static errno_t
utun_attach_proto(ifnet_t interface
, protocol_family_t proto
);
163 static errno_t
utun_proto_input(ifnet_t interface
, protocol_family_t protocol
,
164 mbuf_t m
, char *frame_header
);
165 static errno_t
utun_proto_pre_output(ifnet_t interface
, protocol_family_t protocol
,
166 mbuf_t
*packet
, const struct sockaddr
*dest
, void *route
,
167 char *frame_type
, char *link_layer_dest
);
168 static errno_t
utun_pkt_input(struct utun_pcb
*pcb
, mbuf_t m
);
172 #define UTUN_IF_DEFAULT_SLOT_SIZE 2048
173 #define UTUN_IF_DEFAULT_RING_SIZE 64
174 #define UTUN_IF_DEFAULT_TX_FSW_RING_SIZE 64
175 #define UTUN_IF_DEFAULT_RX_FSW_RING_SIZE 128
176 #define UTUN_IF_DEFAULT_BUF_SEG_SIZE skmem_usr_buf_seg_size
177 #define UTUN_IF_HEADROOM_SIZE 32
179 #define UTUN_IF_MIN_RING_SIZE 8
180 #define UTUN_IF_MAX_RING_SIZE 1024
182 #define UTUN_IF_MIN_SLOT_SIZE 1024
183 #define UTUN_IF_MAX_SLOT_SIZE 4096
185 #define UTUN_DEFAULT_MAX_PENDING_INPUT_COUNT 512
187 static int if_utun_max_pending_input
= UTUN_DEFAULT_MAX_PENDING_INPUT_COUNT
;
189 static int sysctl_if_utun_ring_size SYSCTL_HANDLER_ARGS
;
190 static int sysctl_if_utun_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
191 static int sysctl_if_utun_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
193 static int if_utun_ring_size
= UTUN_IF_DEFAULT_RING_SIZE
;
194 static int if_utun_tx_fsw_ring_size
= UTUN_IF_DEFAULT_TX_FSW_RING_SIZE
;
195 static int if_utun_rx_fsw_ring_size
= UTUN_IF_DEFAULT_RX_FSW_RING_SIZE
;
197 SYSCTL_DECL(_net_utun
);
198 SYSCTL_NODE(_net
, OID_AUTO
, utun
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "UTun");
200 SYSCTL_INT(_net_utun
, OID_AUTO
, max_pending_input
, CTLFLAG_LOCKED
| CTLFLAG_RW
, &if_utun_max_pending_input
, 0, "");
201 SYSCTL_PROC(_net_utun
, OID_AUTO
, ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
202 &if_utun_ring_size
, UTUN_IF_DEFAULT_RING_SIZE
, &sysctl_if_utun_ring_size
, "I", "");
203 SYSCTL_PROC(_net_utun
, OID_AUTO
, tx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
204 &if_utun_tx_fsw_ring_size
, UTUN_IF_DEFAULT_TX_FSW_RING_SIZE
, &sysctl_if_utun_tx_fsw_ring_size
, "I", "");
205 SYSCTL_PROC(_net_utun
, OID_AUTO
, rx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
206 &if_utun_rx_fsw_ring_size
, UTUN_IF_DEFAULT_RX_FSW_RING_SIZE
, &sysctl_if_utun_rx_fsw_ring_size
, "I", "");
209 utun_register_nexus(void);
212 utun_netif_prepare(__unused kern_nexus_t nexus
, ifnet_t ifp
);
214 utun_nexus_pre_connect(kern_nexus_provider_t nxprov
,
215 proc_t p
, kern_nexus_t nexus
,
216 nexus_port_t nexus_port
, kern_channel_t channel
, void **ch_ctx
);
218 utun_nexus_connected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
219 kern_channel_t channel
);
221 utun_netif_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
222 kern_channel_t channel
);
224 utun_nexus_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
225 kern_channel_t channel
);
227 utun_nexus_disconnected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
228 kern_channel_t channel
);
230 utun_kpipe_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
231 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
234 utun_kpipe_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
235 kern_channel_ring_t ring
);
237 utun_kpipe_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
238 kern_channel_ring_t ring
, uint32_t flags
);
240 utun_kpipe_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
241 kern_channel_ring_t ring
, uint32_t flags
);
244 #define UTUN_DEFAULT_MTU 1500
245 #define UTUN_HEADER_SIZE(_pcb) (sizeof(u_int32_t) + (((_pcb)->utun_flags & UTUN_FLAGS_ENABLE_PROC_UUID) ? sizeof(uuid_t) : 0))
247 static kern_ctl_ref utun_kctlref
;
248 static lck_attr_t
*utun_lck_attr
;
249 static lck_grp_attr_t
*utun_lck_grp_attr
;
250 static lck_grp_t
*utun_lck_grp
;
251 static lck_mtx_t utun_lock
;
253 TAILQ_HEAD(utun_list
, utun_pcb
) utun_head
;
255 static ZONE_DECLARE(utun_pcb_zone
, "net.if_utun",
256 sizeof(struct utun_pcb
), ZC_ZFREE_CLEARMEM
);
261 sysctl_if_utun_ring_size SYSCTL_HANDLER_ARGS
263 #pragma unused(arg1, arg2)
264 int value
= if_utun_ring_size
;
266 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
267 if (error
|| !req
->newptr
) {
271 if (value
< UTUN_IF_MIN_RING_SIZE
||
272 value
> UTUN_IF_MAX_RING_SIZE
) {
276 if_utun_ring_size
= value
;
282 sysctl_if_utun_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
284 #pragma unused(arg1, arg2)
285 int value
= if_utun_tx_fsw_ring_size
;
287 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
288 if (error
|| !req
->newptr
) {
292 if (value
< UTUN_IF_MIN_RING_SIZE
||
293 value
> UTUN_IF_MAX_RING_SIZE
) {
297 if_utun_tx_fsw_ring_size
= value
;
303 sysctl_if_utun_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
305 #pragma unused(arg1, arg2)
306 int value
= if_utun_rx_fsw_ring_size
;
308 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
309 if (error
|| !req
->newptr
) {
313 if (value
< UTUN_IF_MIN_RING_SIZE
||
314 value
> UTUN_IF_MAX_RING_SIZE
) {
318 if_utun_rx_fsw_ring_size
= value
;
324 utun_netif_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
325 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
328 #pragma unused(nxprov)
329 #pragma unused(channel)
330 #pragma unused(ring_ctx)
331 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
333 VERIFY(pcb
->utun_netif_rxring
== NULL
);
334 pcb
->utun_netif_rxring
= ring
;
336 VERIFY(pcb
->utun_netif_txring
== NULL
);
337 pcb
->utun_netif_txring
= ring
;
343 utun_netif_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
344 kern_channel_ring_t ring
)
346 #pragma unused(nxprov)
347 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
348 if (pcb
->utun_netif_rxring
== ring
) {
349 pcb
->utun_netif_rxring
= NULL
;
350 } else if (pcb
->utun_netif_txring
== ring
) {
351 pcb
->utun_netif_txring
= NULL
;
356 utun_netif_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
357 kern_channel_ring_t tx_ring
, uint32_t flags
)
359 #pragma unused(nxprov)
360 #pragma unused(flags)
361 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
363 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
365 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
367 struct kern_channel_ring_stat_increment tx_ring_stats
;
368 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
369 kern_channel_slot_t tx_pslot
= NULL
;
370 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
372 STATS_INC(nifs
, NETIF_STATS_TX_SYNC
);
374 if (tx_slot
== NULL
) {
375 // Nothing to write, don't bother signalling
376 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
380 if (pcb
->utun_kpipe_enabled
) {
381 kern_channel_ring_t rx_ring
= pcb
->utun_kpipe_rxring
;
382 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
384 // Signal the kernel pipe ring to read
385 if (rx_ring
!= NULL
) {
386 kern_channel_notify(rx_ring
, 0);
391 // If we're here, we're injecting into the utun kernel control socket
392 while (tx_slot
!= NULL
) {
396 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
401 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
404 (void) kern_channel_slot_detach_packet(tx_ring
, tx_slot
, tx_ph
);
408 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
410 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
411 VERIFY(tx_buf
!= NULL
);
413 /* tx_baddr is the absolute buffer address */
414 uint8_t *tx_baddr
= kern_buflet_get_data_address(tx_buf
);
415 VERIFY(tx_baddr
!= 0);
417 bpf_tap_packet_out(pcb
->utun_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
419 uint16_t tx_offset
= kern_buflet_get_data_offset(tx_buf
);
420 uint32_t tx_length
= kern_buflet_get_data_length(tx_buf
);
422 // The offset must be large enough for the headers
423 VERIFY(tx_offset
>= UTUN_HEADER_SIZE(pcb
));
427 uint8_t vhl
= *(uint8_t *)(tx_baddr
+ tx_offset
);
428 u_int ip_version
= (vhl
>> 4);
429 switch (ip_version
) {
439 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_tx %s: unknown ip version %u vhl %u tx_offset %u len %u header_size %zu\n",
440 pcb
->utun_ifp
->if_xname
, ip_version
, vhl
, tx_offset
, tx_length
,
441 UTUN_HEADER_SIZE(pcb
));
446 tx_offset
-= UTUN_HEADER_SIZE(pcb
);
447 tx_length
+= UTUN_HEADER_SIZE(pcb
);
448 tx_baddr
+= tx_offset
;
450 length
= MIN(tx_length
, pcb
->utun_slot_size
);
453 memcpy(tx_baddr
, &af
, sizeof(af
));
454 if (pcb
->utun_flags
& UTUN_FLAGS_ENABLE_PROC_UUID
) {
455 kern_packet_get_euuid(tx_ph
, (void *)(tx_baddr
+ sizeof(af
)));
459 errno_t error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
461 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
463 error
= utun_output(pcb
->utun_ifp
, data
);
465 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_tx %s - utun_output error %d\n", pcb
->utun_ifp
->if_xname
, error
);
468 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_tx %s - mbuf_copyback(%zu) error %d\n", pcb
->utun_ifp
->if_xname
, length
, error
);
469 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
470 STATS_INC(nifs
, NETIF_STATS_DROP
);
475 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_tx %s - mbuf_gethdr error %d\n", pcb
->utun_ifp
->if_xname
, error
);
476 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
477 STATS_INC(nifs
, NETIF_STATS_DROP
);
480 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_tx %s - 0 length packet\n", pcb
->utun_ifp
->if_xname
);
481 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
482 STATS_INC(nifs
, NETIF_STATS_DROP
);
485 kern_pbufpool_free(tx_ring
->ckr_pp
, tx_ph
);
491 STATS_INC(nifs
, NETIF_STATS_TX_PACKETS
);
492 STATS_INC(nifs
, NETIF_STATS_TX_COPY_MBUF
);
494 tx_ring_stats
.kcrsi_slots_transferred
++;
495 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
499 kern_channel_advance_slot(tx_ring
, tx_pslot
);
500 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
501 (void)kern_channel_reclaim(tx_ring
);
504 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
510 utun_netif_tx_doorbell(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
511 kern_channel_ring_t ring
, __unused
uint32_t flags
)
513 #pragma unused(nxprov)
514 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
515 boolean_t more
= false;
519 * Refill and sync the ring; we may be racing against another thread doing
520 * an RX sync that also wants to do kr_enter(), and so use the blocking
523 rc
= kern_channel_tx_refill_canblock(ring
, UINT32_MAX
, UINT32_MAX
, true, &more
);
524 if (rc
!= 0 && rc
!= EAGAIN
&& rc
!= EBUSY
) {
525 os_log_error(OS_LOG_DEFAULT
, "%s, tx refill failed %d\n", __func__
, rc
);
528 (void) kr_enter(ring
, TRUE
);
529 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
531 if (pcb
->utun_kpipe_enabled
) {
532 uint32_t tx_available
= kern_channel_available_slot_count(ring
);
533 if (pcb
->utun_netif_txring_size
> 0 &&
534 tx_available
>= pcb
->utun_netif_txring_size
- 1) {
535 // No room left in tx ring, disable output for now
536 errno_t error
= ifnet_disable_output(pcb
->utun_ifp
);
538 os_log_error(OS_LOG_DEFAULT
, "utun_netif_tx_doorbell: ifnet_disable_output returned error %d\n", error
);
543 if (pcb
->utun_kpipe_enabled
) {
544 kern_channel_ring_t rx_ring
= pcb
->utun_kpipe_rxring
;
546 // Unlock while calling notify
547 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
548 // Signal the kernel pipe ring to read
549 if (rx_ring
!= NULL
) {
550 kern_channel_notify(rx_ring
, 0);
553 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
562 utun_netif_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
563 kern_channel_ring_t rx_ring
, uint32_t flags
)
565 #pragma unused(nxprov)
566 #pragma unused(flags)
567 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
568 struct kern_channel_ring_stat_increment rx_ring_stats
;
570 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
572 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
574 // Reclaim user-released slots
575 (void) kern_channel_reclaim(rx_ring
);
577 STATS_INC(nifs
, NETIF_STATS_RX_SYNC
);
579 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
581 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
585 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
586 VERIFY(rx_pp
!= NULL
);
587 bzero(&rx_ring_stats
, sizeof(rx_ring_stats
));
588 kern_channel_slot_t rx_pslot
= NULL
;
589 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
591 while (rx_slot
!= NULL
) {
592 // Check for a waiting packet
593 lck_mtx_lock(&pcb
->utun_input_chain_lock
);
594 mbuf_t data
= pcb
->utun_input_chain
;
596 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
600 // Allocate rx packet
601 kern_packet_t rx_ph
= 0;
602 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
603 if (__improbable(error
!= 0)) {
604 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_PKT
);
605 STATS_INC(nifs
, NETIF_STATS_DROP
);
606 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
610 // Advance waiting packets
611 if (pcb
->utun_input_chain_count
> 0) {
612 pcb
->utun_input_chain_count
--;
614 pcb
->utun_input_chain
= data
->m_nextpkt
;
615 data
->m_nextpkt
= NULL
;
616 if (pcb
->utun_input_chain
== NULL
) {
617 pcb
->utun_input_chain_last
= NULL
;
619 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
621 size_t header_offset
= UTUN_HEADER_SIZE(pcb
);
622 size_t length
= mbuf_pkthdr_len(data
);
624 if (length
< header_offset
) {
627 kern_pbufpool_free(rx_pp
, rx_ph
);
628 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
629 STATS_INC(nifs
, NETIF_STATS_DROP
);
630 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_rx %s: legacy packet length too short for header %zu < %zu\n",
631 pcb
->utun_ifp
->if_xname
, length
, header_offset
);
635 length
-= header_offset
;
636 if (length
> rx_pp
->pp_buflet_size
) {
639 kern_pbufpool_free(rx_pp
, rx_ph
);
640 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
641 STATS_INC(nifs
, NETIF_STATS_DROP
);
642 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_rx %s: legacy packet length %zu > %u\n",
643 pcb
->utun_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
647 mbuf_pkthdr_setrcvif(data
, pcb
->utun_ifp
);
650 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
651 VERIFY(rx_buf
!= NULL
);
652 void *rx_baddr
= kern_buflet_get_data_address(rx_buf
);
653 VERIFY(rx_baddr
!= NULL
);
655 // Copy-in data from mbuf to buflet
656 mbuf_copydata(data
, header_offset
, length
, (void *)rx_baddr
);
657 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
659 // Finalize and attach the packet
660 error
= kern_buflet_set_data_offset(rx_buf
, 0);
662 error
= kern_buflet_set_data_length(rx_buf
, length
);
664 error
= kern_packet_set_headroom(rx_ph
, 0);
666 error
= kern_packet_finalize(rx_ph
);
668 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
671 STATS_INC(nifs
, NETIF_STATS_RX_PACKETS
);
672 STATS_INC(nifs
, NETIF_STATS_RX_COPY_MBUF
);
673 bpf_tap_packet_in(pcb
->utun_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
675 rx_ring_stats
.kcrsi_slots_transferred
++;
676 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
682 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
685 struct kern_channel_ring_stat_increment tx_ring_stats
;
686 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
687 kern_channel_ring_t tx_ring
= pcb
->utun_kpipe_txring
;
688 kern_channel_slot_t tx_pslot
= NULL
;
689 kern_channel_slot_t tx_slot
= NULL
;
690 if (tx_ring
== NULL
) {
691 // Net-If TX ring not set up yet, nothing to read
695 // Unlock utun before entering ring
696 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
698 (void)kr_enter(tx_ring
, TRUE
);
700 // Lock again after entering and validate
701 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
702 if (tx_ring
!= pcb
->utun_kpipe_txring
) {
706 tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
707 if (tx_slot
== NULL
) {
708 // Nothing to read, don't bother signalling
712 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
713 // Allocate rx packet
714 kern_packet_t rx_ph
= 0;
715 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
719 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
721 /* Skip slot if packet is zero-length or marked as dropped (QUMF_DROPPED) */
726 /* XXX We could try this alloc before advancing the slot to avoid
727 * dropping the packet on failure to allocate.
729 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
730 if (__improbable(error
!= 0)) {
731 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_PKT
);
732 STATS_INC(nifs
, NETIF_STATS_DROP
);
736 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
737 VERIFY(tx_buf
!= NULL
);
738 uint8_t *tx_baddr
= kern_buflet_get_data_address(tx_buf
);
739 VERIFY(tx_baddr
!= 0);
740 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
742 // Check packet length
743 size_t header_offset
= UTUN_HEADER_SIZE(pcb
);
744 uint32_t tx_length
= kern_packet_get_data_length(tx_ph
);
745 if (tx_length
< header_offset
) {
746 // Packet is too small
747 kern_pbufpool_free(rx_pp
, rx_ph
);
748 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
749 STATS_INC(nifs
, NETIF_STATS_DROP
);
750 os_log_error(OS_LOG_DEFAULT
, "utun_netif_sync_rx %s: packet length too short for header %u < %zu\n",
751 pcb
->utun_ifp
->if_xname
, tx_length
, header_offset
);
755 size_t length
= MIN(tx_length
- header_offset
,
756 pcb
->utun_slot_size
);
758 tx_ring_stats
.kcrsi_slots_transferred
++;
759 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
762 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
763 VERIFY(rx_buf
!= NULL
);
764 void *rx_baddr
= kern_buflet_get_data_address(rx_buf
);
765 VERIFY(rx_baddr
!= NULL
);
767 // Copy-in data from tx to rx
768 memcpy((void *)rx_baddr
, (void *)(tx_baddr
+ header_offset
), length
);
769 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
771 // Finalize and attach the packet
772 error
= kern_buflet_set_data_offset(rx_buf
, 0);
774 error
= kern_buflet_set_data_length(rx_buf
, length
);
776 error
= kern_packet_set_headroom(rx_ph
, 0);
778 error
= kern_packet_finalize(rx_ph
);
780 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
783 STATS_INC(nifs
, NETIF_STATS_RX_PACKETS
);
784 STATS_INC(nifs
, NETIF_STATS_RX_COPY_DIRECT
);
785 bpf_tap_packet_in(pcb
->utun_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
787 rx_ring_stats
.kcrsi_slots_transferred
++;
788 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
791 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
796 kern_channel_advance_slot(rx_ring
, rx_pslot
);
797 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->utun_ifp
, &rx_ring_stats
);
801 kern_channel_advance_slot(tx_ring
, tx_pslot
);
802 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
803 (void)kern_channel_reclaim(tx_ring
);
806 // Unlock first, then exit ring
807 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
808 if (tx_ring
!= NULL
) {
809 if (tx_pslot
!= NULL
) {
810 kern_channel_notify(tx_ring
, 0);
819 utun_nexus_ifattach(struct utun_pcb
*pcb
,
820 struct ifnet_init_eparams
*init_params
,
824 nexus_controller_t controller
= kern_nexus_shared_controller();
825 struct kern_nexus_net_init net_init
;
826 struct kern_pbufpool_init pp_init
;
828 nexus_name_t provider_name
;
829 snprintf((char *)provider_name
, sizeof(provider_name
),
830 "com.apple.netif.%s", pcb
->utun_if_xname
);
832 struct kern_nexus_provider_init prov_init
= {
833 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
834 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
835 .nxpi_pre_connect
= utun_nexus_pre_connect
,
836 .nxpi_connected
= utun_nexus_connected
,
837 .nxpi_pre_disconnect
= utun_netif_pre_disconnect
,
838 .nxpi_disconnected
= utun_nexus_disconnected
,
839 .nxpi_ring_init
= utun_netif_ring_init
,
840 .nxpi_ring_fini
= utun_netif_ring_fini
,
841 .nxpi_slot_init
= NULL
,
842 .nxpi_slot_fini
= NULL
,
843 .nxpi_sync_tx
= utun_netif_sync_tx
,
844 .nxpi_sync_rx
= utun_netif_sync_rx
,
845 .nxpi_tx_doorbell
= utun_netif_tx_doorbell
,
848 nexus_attr_t nxa
= NULL
;
849 err
= kern_nexus_attr_create(&nxa
);
851 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_attr_create failed: %d\n",
856 uint64_t slot_buffer_size
= pcb
->utun_slot_size
;
857 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
860 // Reset ring size for netif nexus to limit memory usage
861 uint64_t ring_size
= pcb
->utun_netif_ring_size
;
862 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
864 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
867 pcb
->utun_netif_txring_size
= ring_size
;
869 bzero(&pp_init
, sizeof(pp_init
));
870 pp_init
.kbi_version
= KERN_PBUFPOOL_CURRENT_VERSION
;
871 pp_init
.kbi_flags
|= KBIF_VIRTUAL_DEVICE
;
872 pp_init
.kbi_packets
= pcb
->utun_netif_ring_size
* 2;
873 pp_init
.kbi_bufsize
= pcb
->utun_slot_size
;
874 pp_init
.kbi_buf_seg_size
= UTUN_IF_DEFAULT_BUF_SEG_SIZE
;
875 pp_init
.kbi_max_frags
= 1;
876 (void) snprintf((char *)pp_init
.kbi_name
, sizeof(pp_init
.kbi_name
),
877 "%s", provider_name
);
878 pp_init
.kbi_ctx
= NULL
;
879 pp_init
.kbi_ctx_retain
= NULL
;
880 pp_init
.kbi_ctx_release
= NULL
;
882 err
= kern_pbufpool_create(&pp_init
, &pcb
->utun_netif_pp
, NULL
);
884 os_log_error(OS_LOG_DEFAULT
, "%s pbufbool create failed, error %d\n", __func__
, err
);
888 err
= kern_nexus_controller_register_provider(controller
,
894 &pcb
->utun_nx
.if_provider
);
896 os_log_error(OS_LOG_DEFAULT
, "%s register provider failed, error %d\n",
901 bzero(&net_init
, sizeof(net_init
));
902 net_init
.nxneti_version
= KERN_NEXUS_NET_CURRENT_VERSION
;
903 net_init
.nxneti_flags
= 0;
904 net_init
.nxneti_eparams
= init_params
;
905 net_init
.nxneti_lladdr
= NULL
;
906 net_init
.nxneti_prepare
= utun_netif_prepare
;
907 net_init
.nxneti_rx_pbufpool
= pcb
->utun_netif_pp
;
908 net_init
.nxneti_tx_pbufpool
= pcb
->utun_netif_pp
;
909 err
= kern_nexus_controller_alloc_net_provider_instance(controller
,
910 pcb
->utun_nx
.if_provider
,
912 &pcb
->utun_nx
.if_instance
,
916 os_log_error(OS_LOG_DEFAULT
, "%s alloc_net_provider_instance failed, %d\n",
918 kern_nexus_controller_deregister_provider(controller
,
919 pcb
->utun_nx
.if_provider
);
920 uuid_clear(pcb
->utun_nx
.if_provider
);
926 kern_nexus_attr_destroy(nxa
);
928 if (err
&& pcb
->utun_netif_pp
!= NULL
) {
929 kern_pbufpool_destroy(pcb
->utun_netif_pp
);
930 pcb
->utun_netif_pp
= NULL
;
936 utun_detach_provider_and_instance(uuid_t provider
, uuid_t instance
)
938 nexus_controller_t controller
= kern_nexus_shared_controller();
941 if (!uuid_is_null(instance
)) {
942 err
= kern_nexus_controller_free_provider_instance(controller
,
945 os_log_error(OS_LOG_DEFAULT
, "%s free_provider_instance failed %d\n",
948 uuid_clear(instance
);
950 if (!uuid_is_null(provider
)) {
951 err
= kern_nexus_controller_deregister_provider(controller
,
954 os_log_error(OS_LOG_DEFAULT
, "%s deregister_provider %d\n", __func__
, err
);
956 uuid_clear(provider
);
962 utun_nexus_detach(struct utun_pcb
*pcb
)
964 utun_nx_t nx
= &pcb
->utun_nx
;
965 nexus_controller_t controller
= kern_nexus_shared_controller();
968 if (!uuid_is_null(nx
->fsw_host
)) {
969 err
= kern_nexus_ifdetach(controller
,
973 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_ifdetach ms host failed %d\n",
978 if (!uuid_is_null(nx
->fsw_device
)) {
979 err
= kern_nexus_ifdetach(controller
,
983 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_ifdetach ms device failed %d\n",
988 utun_detach_provider_and_instance(nx
->if_provider
,
990 utun_detach_provider_and_instance(nx
->fsw_provider
,
993 if (pcb
->utun_netif_pp
!= NULL
) {
994 kern_pbufpool_destroy(pcb
->utun_netif_pp
);
995 pcb
->utun_netif_pp
= NULL
;
997 memset(nx
, 0, sizeof(*nx
));
1001 utun_create_fs_provider_and_instance(struct utun_pcb
*pcb
,
1002 const char *type_name
,
1004 uuid_t
*provider
, uuid_t
*instance
)
1006 nexus_attr_t attr
= NULL
;
1007 nexus_controller_t controller
= kern_nexus_shared_controller();
1010 struct kern_nexus_init init
;
1011 nexus_name_t provider_name
;
1013 err
= kern_nexus_get_default_domain_provider(NEXUS_TYPE_FLOW_SWITCH
,
1016 os_log_error(OS_LOG_DEFAULT
, "%s can't get %s provider, error %d\n",
1017 __func__
, type_name
, err
);
1021 err
= kern_nexus_attr_create(&attr
);
1023 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_attr_create failed: %d\n",
1028 uint64_t slot_buffer_size
= pcb
->utun_slot_size
;
1029 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1032 // Reset ring size for flowswitch nexus to limit memory usage. Larger RX than netif.
1033 uint64_t tx_ring_size
= pcb
->utun_tx_fsw_ring_size
;
1034 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_TX_SLOTS
, tx_ring_size
);
1036 uint64_t rx_ring_size
= pcb
->utun_rx_fsw_ring_size
;
1037 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_RX_SLOTS
, rx_ring_size
);
1040 * Configure flowswitch to use super-packet (multi-buflet).
1041 * This allows flowswitch to perform intra-stack packet aggregation.
1043 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_MAX_FRAGS
,
1044 sk_fsw_rx_agg_tcp
? NX_PBUF_FRAGS_MAX
: 1);
1047 snprintf((char *)provider_name
, sizeof(provider_name
),
1048 "com.apple.%s.%s", type_name
, ifname
);
1049 err
= kern_nexus_controller_register_provider(controller
,
1056 kern_nexus_attr_destroy(attr
);
1059 os_log_error(OS_LOG_DEFAULT
, "%s register %s provider failed, error %d\n",
1060 __func__
, type_name
, err
);
1063 bzero(&init
, sizeof(init
));
1064 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
1065 err
= kern_nexus_controller_alloc_provider_instance(controller
,
1070 os_log_error(OS_LOG_DEFAULT
, "%s alloc_provider_instance %s failed, %d\n",
1071 __func__
, type_name
, err
);
1072 kern_nexus_controller_deregister_provider(controller
,
1074 uuid_clear(*provider
);
1081 utun_flowswitch_attach(struct utun_pcb
*pcb
)
1083 nexus_controller_t controller
= kern_nexus_shared_controller();
1085 utun_nx_t nx
= &pcb
->utun_nx
;
1087 // Allocate flowswitch
1088 err
= utun_create_fs_provider_and_instance(pcb
,
1090 pcb
->utun_ifp
->if_xname
,
1094 os_log_error(OS_LOG_DEFAULT
, "%s: failed to create bridge provider and instance\n",
1099 // Attach flowswitch to device port
1100 err
= kern_nexus_ifattach(controller
, nx
->fsw_instance
,
1101 NULL
, nx
->if_instance
,
1102 FALSE
, &nx
->fsw_device
);
1104 os_log_error(OS_LOG_DEFAULT
, "%s kern_nexus_ifattach ms device %d\n", __func__
, err
);
1108 // Attach flowswitch to host port
1109 err
= kern_nexus_ifattach(controller
, nx
->fsw_instance
,
1110 NULL
, nx
->if_instance
,
1111 TRUE
, &nx
->fsw_host
);
1113 os_log_error(OS_LOG_DEFAULT
, "%s kern_nexus_ifattach ms host %d\n", __func__
, err
);
1117 // Extract the agent UUID and save for later
1118 struct kern_nexus
*flowswitch_nx
= nx_find(nx
->fsw_instance
, false);
1119 if (flowswitch_nx
!= NULL
) {
1120 struct nx_flowswitch
*flowswitch
= NX_FSW_PRIVATE(flowswitch_nx
);
1121 if (flowswitch
!= NULL
) {
1122 FSW_RLOCK(flowswitch
);
1123 uuid_copy(nx
->fsw_agent
, flowswitch
->fsw_agent_uuid
);
1124 FSW_UNLOCK(flowswitch
);
1126 os_log_error(OS_LOG_DEFAULT
, "utun_flowswitch_attach - flowswitch is NULL\n");
1128 nx_release(flowswitch_nx
);
1130 os_log_error(OS_LOG_DEFAULT
, "utun_flowswitch_attach - unable to find flowswitch nexus\n");
1136 utun_nexus_detach(pcb
);
1138 errno_t detach_error
= 0;
1139 if ((detach_error
= ifnet_detach(pcb
->utun_ifp
)) != 0) {
1140 panic("utun_flowswitch_attach - ifnet_detach failed: %d\n", detach_error
);
1148 utun_register_kernel_pipe_nexus(struct utun_pcb
*pcb
)
1150 nexus_attr_t nxa
= NULL
;
1153 lck_mtx_lock(&utun_lock
);
1154 if (utun_ncd_refcount
++) {
1155 lck_mtx_unlock(&utun_lock
);
1159 result
= kern_nexus_controller_create(&utun_ncd
);
1161 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_controller_create failed: %d\n",
1162 __FUNCTION__
, result
);
1167 result
= kern_nexus_get_default_domain_provider(
1168 NEXUS_TYPE_KERNEL_PIPE
, &dom_prov
);
1170 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_get_default_domain_provider failed: %d\n",
1171 __FUNCTION__
, result
);
1175 struct kern_nexus_provider_init prov_init
= {
1176 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
1177 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
1178 .nxpi_pre_connect
= utun_nexus_pre_connect
,
1179 .nxpi_connected
= utun_nexus_connected
,
1180 .nxpi_pre_disconnect
= utun_nexus_pre_disconnect
,
1181 .nxpi_disconnected
= utun_nexus_disconnected
,
1182 .nxpi_ring_init
= utun_kpipe_ring_init
,
1183 .nxpi_ring_fini
= utun_kpipe_ring_fini
,
1184 .nxpi_slot_init
= NULL
,
1185 .nxpi_slot_fini
= NULL
,
1186 .nxpi_sync_tx
= utun_kpipe_sync_tx
,
1187 .nxpi_sync_rx
= utun_kpipe_sync_rx
,
1188 .nxpi_tx_doorbell
= NULL
,
1191 result
= kern_nexus_attr_create(&nxa
);
1193 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_attr_create failed: %d\n",
1194 __FUNCTION__
, result
);
1198 uint64_t slot_buffer_size
= UTUN_IF_DEFAULT_SLOT_SIZE
;
1199 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1200 VERIFY(result
== 0);
1202 // Reset ring size for kernel pipe nexus to limit memory usage
1203 uint64_t ring_size
=
1204 pcb
->utun_kpipe_tx_ring_size
!= 0 ? pcb
->utun_kpipe_tx_ring_size
:
1206 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
1207 VERIFY(result
== 0);
1210 pcb
->utun_kpipe_rx_ring_size
!= 0 ? pcb
->utun_kpipe_rx_ring_size
:
1212 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
1213 VERIFY(result
== 0);
1215 result
= kern_nexus_controller_register_provider(utun_ncd
,
1217 (const uint8_t *)"com.apple.nexus.utun.kpipe",
1223 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_controller_register_provider failed: %d\n",
1224 __FUNCTION__
, result
);
1230 kern_nexus_attr_destroy(nxa
);
1235 kern_nexus_controller_destroy(utun_ncd
);
1238 utun_ncd_refcount
= 0;
1241 lck_mtx_unlock(&utun_lock
);
1247 utun_unregister_kernel_pipe_nexus(void)
1249 lck_mtx_lock(&utun_lock
);
1251 VERIFY(utun_ncd_refcount
> 0);
1253 if (--utun_ncd_refcount
== 0) {
1254 kern_nexus_controller_destroy(utun_ncd
);
1258 lck_mtx_unlock(&utun_lock
);
1261 // For use by socket option, not internally
1263 utun_disable_channel(struct utun_pcb
*pcb
)
1269 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
1271 enabled
= pcb
->utun_kpipe_enabled
;
1272 uuid_copy(uuid
, pcb
->utun_kpipe_uuid
);
1274 VERIFY(uuid_is_null(pcb
->utun_kpipe_uuid
) == !enabled
);
1276 pcb
->utun_kpipe_enabled
= 0;
1277 uuid_clear(pcb
->utun_kpipe_uuid
);
1279 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1282 result
= kern_nexus_controller_free_provider_instance(utun_ncd
, uuid
);
1288 if (pcb
->utun_kpipe_pp
!= NULL
) {
1289 kern_pbufpool_destroy(pcb
->utun_kpipe_pp
);
1290 pcb
->utun_kpipe_pp
= NULL
;
1292 utun_unregister_kernel_pipe_nexus();
1299 utun_enable_channel(struct utun_pcb
*pcb
, struct proc
*proc
)
1301 struct kern_nexus_init init
;
1302 struct kern_pbufpool_init pp_init
;
1305 kauth_cred_t cred
= kauth_cred_get();
1306 result
= priv_check_cred(cred
, PRIV_SKYWALK_REGISTER_KERNEL_PIPE
, 0);
1311 result
= utun_register_kernel_pipe_nexus(pcb
);
1318 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
1320 if (pcb
->utun_kpipe_enabled
) {
1321 result
= EEXIST
; // return success instead?
1326 * Make sure we can fit packets in the channel buffers and
1327 * Allow an extra 4 bytes for the protocol number header in the channel
1329 if (pcb
->utun_ifp
->if_mtu
+ UTUN_HEADER_SIZE(pcb
) > pcb
->utun_slot_size
) {
1330 result
= EOPNOTSUPP
;
1334 bzero(&pp_init
, sizeof(pp_init
));
1335 pp_init
.kbi_version
= KERN_PBUFPOOL_CURRENT_VERSION
;
1336 pp_init
.kbi_flags
|= KBIF_VIRTUAL_DEVICE
;
1337 pp_init
.kbi_packets
= pcb
->utun_netif_ring_size
* 2;
1338 pp_init
.kbi_bufsize
= pcb
->utun_slot_size
;
1339 pp_init
.kbi_buf_seg_size
= UTUN_IF_DEFAULT_BUF_SEG_SIZE
;
1340 pp_init
.kbi_max_frags
= 1;
1341 pp_init
.kbi_flags
|= KBIF_QUANTUM
;
1342 (void) snprintf((char *)pp_init
.kbi_name
, sizeof(pp_init
.kbi_name
),
1343 "com.apple.kpipe.%s", pcb
->utun_if_xname
);
1344 pp_init
.kbi_ctx
= NULL
;
1345 pp_init
.kbi_ctx_retain
= NULL
;
1346 pp_init
.kbi_ctx_release
= NULL
;
1348 result
= kern_pbufpool_create(&pp_init
, &pcb
->utun_kpipe_pp
,
1351 os_log_error(OS_LOG_DEFAULT
, "%s pbufbool create failed, error %d\n", __func__
, result
);
1355 VERIFY(uuid_is_null(pcb
->utun_kpipe_uuid
));
1356 bzero(&init
, sizeof(init
));
1357 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
1358 init
.nxi_tx_pbufpool
= pcb
->utun_kpipe_pp
;
1359 result
= kern_nexus_controller_alloc_provider_instance(utun_ncd
,
1360 utun_kpipe_uuid
, pcb
, &pcb
->utun_kpipe_uuid
, &init
);
1365 nexus_port_t port
= NEXUS_PORT_KERNEL_PIPE_CLIENT
;
1366 result
= kern_nexus_controller_bind_provider_instance(utun_ncd
,
1367 pcb
->utun_kpipe_uuid
, &port
,
1368 proc_pid(proc
), NULL
, NULL
, 0, NEXUS_BIND_PID
);
1370 kern_nexus_controller_free_provider_instance(utun_ncd
,
1371 pcb
->utun_kpipe_uuid
);
1372 uuid_clear(pcb
->utun_kpipe_uuid
);
1376 pcb
->utun_kpipe_enabled
= 1;
1379 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1382 if (pcb
->utun_kpipe_pp
!= NULL
) {
1383 kern_pbufpool_destroy(pcb
->utun_kpipe_pp
);
1384 pcb
->utun_kpipe_pp
= NULL
;
1386 utun_unregister_kernel_pipe_nexus();
1392 #endif // UTUN_NEXUS
1395 utun_register_control(void)
1397 struct kern_ctl_reg kern_ctl
;
1401 utun_register_nexus();
1402 #endif // UTUN_NEXUS
1404 TAILQ_INIT(&utun_head
);
1406 bzero(&kern_ctl
, sizeof(kern_ctl
));
1407 strlcpy(kern_ctl
.ctl_name
, UTUN_CONTROL_NAME
, sizeof(kern_ctl
.ctl_name
));
1408 kern_ctl
.ctl_name
[sizeof(kern_ctl
.ctl_name
) - 1] = 0;
1409 kern_ctl
.ctl_flags
= CTL_FLAG_PRIVILEGED
| CTL_FLAG_REG_SETUP
| CTL_FLAG_REG_EXTENDED
; /* Require root */
1410 kern_ctl
.ctl_sendsize
= 512 * 1024;
1411 kern_ctl
.ctl_recvsize
= 512 * 1024;
1412 kern_ctl
.ctl_setup
= utun_ctl_setup
;
1413 kern_ctl
.ctl_bind
= utun_ctl_bind
;
1414 kern_ctl
.ctl_connect
= utun_ctl_connect
;
1415 kern_ctl
.ctl_disconnect
= utun_ctl_disconnect
;
1416 kern_ctl
.ctl_send
= utun_ctl_send
;
1417 kern_ctl
.ctl_setopt
= utun_ctl_setopt
;
1418 kern_ctl
.ctl_getopt
= utun_ctl_getopt
;
1419 kern_ctl
.ctl_rcvd
= utun_ctl_rcvd
;
1421 result
= ctl_register(&kern_ctl
, &utun_kctlref
);
1423 os_log_error(OS_LOG_DEFAULT
, "utun_register_control - ctl_register failed: %d\n", result
);
1427 /* Register the protocol plumbers */
1428 if ((result
= proto_register_plumber(PF_INET
, IFNET_FAMILY_UTUN
,
1429 utun_attach_proto
, NULL
)) != 0) {
1430 os_log_error(OS_LOG_DEFAULT
, "utun_register_control - proto_register_plumber(PF_INET, IFNET_FAMILY_UTUN) failed: %d\n",
1432 ctl_deregister(utun_kctlref
);
1436 /* Register the protocol plumbers */
1437 if ((result
= proto_register_plumber(PF_INET6
, IFNET_FAMILY_UTUN
,
1438 utun_attach_proto
, NULL
)) != 0) {
1439 proto_unregister_plumber(PF_INET
, IFNET_FAMILY_UTUN
);
1440 ctl_deregister(utun_kctlref
);
1441 os_log_error(OS_LOG_DEFAULT
, "utun_register_control - proto_register_plumber(PF_INET6, IFNET_FAMILY_UTUN) failed: %d\n",
1446 utun_lck_attr
= lck_attr_alloc_init();
1447 utun_lck_grp_attr
= lck_grp_attr_alloc_init();
1448 utun_lck_grp
= lck_grp_alloc_init("utun", utun_lck_grp_attr
);
1450 lck_mtx_init(&utun_lock
, utun_lck_grp
, utun_lck_attr
);
1455 /* Kernel control functions */
1458 utun_find_by_unit(u_int32_t unit
)
1460 struct utun_pcb
*next_pcb
= NULL
;
1463 TAILQ_FOREACH(next_pcb
, &utun_head
, utun_chain
) {
1464 if (next_pcb
->utun_unit
== unit
) {
1474 utun_free_pcb(struct utun_pcb
*pcb
, bool locked
)
1477 mbuf_freem_list(pcb
->utun_input_chain
);
1478 pcb
->utun_input_chain_count
= 0;
1479 lck_mtx_destroy(&pcb
->utun_input_chain_lock
, utun_lck_grp
);
1480 #endif // UTUN_NEXUS
1481 lck_rw_destroy(&pcb
->utun_pcb_lock
, utun_lck_grp
);
1483 lck_mtx_lock(&utun_lock
);
1485 TAILQ_REMOVE(&utun_head
, pcb
, utun_chain
);
1487 lck_mtx_unlock(&utun_lock
);
1489 zfree(utun_pcb_zone
, pcb
);
1493 utun_ctl_setup(u_int32_t
*unit
, void **unitinfo
)
1495 if (unit
== NULL
|| unitinfo
== NULL
) {
1499 lck_mtx_lock(&utun_lock
);
1501 /* Find next available unit */
1504 while (*unit
!= ctl_maxunit
) {
1505 if (utun_find_by_unit(*unit
)) {
1511 if (*unit
== ctl_maxunit
) {
1512 lck_mtx_unlock(&utun_lock
);
1515 } else if (utun_find_by_unit(*unit
)) {
1516 lck_mtx_unlock(&utun_lock
);
1520 /* Find some open interface id */
1521 u_int32_t chosen_unique_id
= 1;
1522 struct utun_pcb
*next_pcb
= TAILQ_LAST(&utun_head
, utun_list
);
1523 if (next_pcb
!= NULL
) {
1524 /* List was not empty, add one to the last item */
1525 chosen_unique_id
= next_pcb
->utun_unique_id
+ 1;
1529 * If this wrapped the id number, start looking at
1530 * the front of the list for an unused id.
1532 if (chosen_unique_id
== 0) {
1533 /* Find the next unused ID */
1534 chosen_unique_id
= 1;
1535 TAILQ_FOREACH(next_pcb
, &utun_head
, utun_chain
) {
1536 if (next_pcb
->utun_unique_id
> chosen_unique_id
) {
1537 /* We found a gap */
1541 chosen_unique_id
= next_pcb
->utun_unique_id
+ 1;
1546 struct utun_pcb
*pcb
= zalloc_flags(utun_pcb_zone
, Z_WAITOK
| Z_ZERO
);
1549 pcb
->utun_unit
= *unit
;
1550 pcb
->utun_unique_id
= chosen_unique_id
;
1552 if (next_pcb
!= NULL
) {
1553 TAILQ_INSERT_BEFORE(next_pcb
, pcb
, utun_chain
);
1555 TAILQ_INSERT_TAIL(&utun_head
, pcb
, utun_chain
);
1558 lck_mtx_unlock(&utun_lock
);
1564 utun_ctl_bind(kern_ctl_ref kctlref
,
1565 struct sockaddr_ctl
*sac
,
1568 if (*unitinfo
== NULL
) {
1570 (void)utun_ctl_setup(&unit
, unitinfo
);
1573 struct utun_pcb
*pcb
= (struct utun_pcb
*)*unitinfo
;
1578 pcb
->utun_ctlref
= kctlref
;
1579 pcb
->utun_unit
= sac
->sc_unit
;
1580 pcb
->utun_max_pending_packets
= 1;
1583 pcb
->utun_use_netif
= false;
1584 pcb
->utun_attach_fsw
= true;
1585 pcb
->utun_netif_connected
= false;
1586 pcb
->utun_slot_size
= UTUN_IF_DEFAULT_SLOT_SIZE
;
1587 pcb
->utun_netif_ring_size
= if_utun_ring_size
;
1588 pcb
->utun_tx_fsw_ring_size
= if_utun_tx_fsw_ring_size
;
1589 pcb
->utun_rx_fsw_ring_size
= if_utun_rx_fsw_ring_size
;
1590 pcb
->utun_input_chain_count
= 0;
1591 lck_mtx_init(&pcb
->utun_input_chain_lock
, utun_lck_grp
, utun_lck_attr
);
1592 #endif // UTUN_NEXUS
1594 lck_rw_init(&pcb
->utun_pcb_lock
, utun_lck_grp
, utun_lck_attr
);
1600 utun_ctl_connect(kern_ctl_ref kctlref
,
1601 struct sockaddr_ctl
*sac
,
1604 struct ifnet_init_eparams utun_init
= {};
1607 if (*unitinfo
== NULL
) {
1608 (void)utun_ctl_bind(kctlref
, sac
, unitinfo
);
1611 struct utun_pcb
*pcb
= *unitinfo
;
1616 /* Handle case where utun_ctl_setup() was called, but ipsec_ctl_bind() was not */
1617 if (pcb
->utun_ctlref
== NULL
) {
1618 (void)utun_ctl_bind(kctlref
, sac
, unitinfo
);
1621 snprintf(pcb
->utun_if_xname
, sizeof(pcb
->utun_if_xname
), "utun%d", pcb
->utun_unit
- 1);
1622 snprintf(pcb
->utun_unique_name
, sizeof(pcb
->utun_unique_name
), "utunid%d", pcb
->utun_unique_id
- 1);
1624 /* Create the interface */
1625 bzero(&utun_init
, sizeof(utun_init
));
1626 utun_init
.ver
= IFNET_INIT_CURRENT_VERSION
;
1627 utun_init
.len
= sizeof(utun_init
);
1630 if (pcb
->utun_use_netif
) {
1631 utun_init
.flags
= (IFNET_INIT_SKYWALK_NATIVE
| IFNET_INIT_NX_NOAUTO
);
1632 utun_init
.tx_headroom
= UTUN_IF_HEADROOM_SIZE
;
1634 #endif // UTUN_NEXUS
1636 utun_init
.flags
= IFNET_INIT_NX_NOAUTO
;
1637 utun_init
.start
= utun_start
;
1638 utun_init
.framer_extended
= utun_framer
;
1640 utun_init
.name
= "utun";
1641 utun_init
.unit
= pcb
->utun_unit
- 1;
1642 utun_init
.uniqueid
= pcb
->utun_unique_name
;
1643 utun_init
.uniqueid_len
= strlen(pcb
->utun_unique_name
);
1644 utun_init
.family
= IFNET_FAMILY_UTUN
;
1645 utun_init
.type
= IFT_OTHER
;
1646 utun_init
.demux
= utun_demux
;
1647 utun_init
.add_proto
= utun_add_proto
;
1648 utun_init
.del_proto
= utun_del_proto
;
1649 utun_init
.softc
= pcb
;
1650 utun_init
.ioctl
= utun_ioctl
;
1651 utun_init
.free
= utun_detached
;
1654 if (pcb
->utun_use_netif
) {
1655 result
= utun_nexus_ifattach(pcb
, &utun_init
, &pcb
->utun_ifp
);
1657 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_connect - utun_nexus_ifattach failed: %d\n", result
);
1658 utun_free_pcb(pcb
, false);
1663 if (pcb
->utun_attach_fsw
) {
1664 result
= utun_flowswitch_attach(pcb
);
1666 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_connect - utun_flowswitch_attach failed: %d\n", result
);
1667 // Do not call utun_free_pcb(). We will be attached already, and will be freed later
1668 // in utun_detached().
1675 bpfattach(pcb
->utun_ifp
, DLT_RAW
, 0);
1677 #endif // UTUN_NEXUS
1680 * Upon success, this holds an ifnet reference which we will
1681 * release via ifnet_release() at final detach time.
1683 result
= ifnet_allocate_extended(&utun_init
, &pcb
->utun_ifp
);
1685 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_connect - ifnet_allocate failed: %d\n", result
);
1686 utun_free_pcb(pcb
, false);
1691 /* Set flags and additional information. */
1692 ifnet_set_mtu(pcb
->utun_ifp
, UTUN_DEFAULT_MTU
);
1693 ifnet_set_flags(pcb
->utun_ifp
, IFF_UP
| IFF_MULTICAST
| IFF_POINTOPOINT
, 0xffff);
1695 /* The interface must generate its own IPv6 LinkLocal address,
1696 * if possible following the recommendation of RFC2472 to the 64bit interface ID
1698 ifnet_set_eflags(pcb
->utun_ifp
, IFEF_NOAUTOIPV6LL
, IFEF_NOAUTOIPV6LL
);
1700 /* Reset the stats in case as the interface may have been recycled */
1701 struct ifnet_stats_param stats
;
1702 bzero(&stats
, sizeof(struct ifnet_stats_param
));
1703 ifnet_set_stat(pcb
->utun_ifp
, &stats
);
1705 /* Attach the interface */
1706 result
= ifnet_attach(pcb
->utun_ifp
, NULL
);
1708 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_connect - ifnet_attach failed: %d\n", result
);
1709 /* Release reference now since attach failed */
1710 ifnet_release(pcb
->utun_ifp
);
1711 utun_free_pcb(pcb
, false);
1717 bpfattach(pcb
->utun_ifp
, DLT_NULL
, UTUN_HEADER_SIZE(pcb
));
1720 /* The interfaces resoures allocated, mark it as running */
1721 ifnet_set_flags(pcb
->utun_ifp
, IFF_RUNNING
, IFF_RUNNING
);
1727 utun_detach_ip(ifnet_t interface
,
1728 protocol_family_t protocol
,
1731 errno_t result
= EPROTONOSUPPORT
;
1733 /* Attempt a detach */
1734 if (protocol
== PF_INET
) {
1737 bzero(&ifr
, sizeof(ifr
));
1738 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
1739 ifnet_name(interface
), ifnet_unit(interface
));
1741 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH
, &ifr
);
1742 } else if (protocol
== PF_INET6
) {
1743 struct in6_ifreq ifr6
;
1745 bzero(&ifr6
, sizeof(ifr6
));
1746 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
1747 ifnet_name(interface
), ifnet_unit(interface
));
1749 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH_IN6
, &ifr6
);
1756 utun_remove_address(ifnet_t interface
,
1757 protocol_family_t protocol
,
1763 /* Attempt a detach */
1764 if (protocol
== PF_INET
) {
1767 bzero(&ifr
, sizeof(ifr
));
1768 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
1769 ifnet_name(interface
), ifnet_unit(interface
));
1770 result
= ifaddr_address(address
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
1772 os_log_error(OS_LOG_DEFAULT
, "utun_remove_address - ifaddr_address failed: %d", result
);
1774 result
= sock_ioctl(pf_socket
, SIOCDIFADDR
, &ifr
);
1776 os_log_error(OS_LOG_DEFAULT
, "utun_remove_address - SIOCDIFADDR failed: %d", result
);
1779 } else if (protocol
== PF_INET6
) {
1780 struct in6_ifreq ifr6
;
1782 bzero(&ifr6
, sizeof(ifr6
));
1783 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
1784 ifnet_name(interface
), ifnet_unit(interface
));
1785 result
= ifaddr_address(address
, (struct sockaddr
*)&ifr6
.ifr_addr
,
1786 sizeof(ifr6
.ifr_addr
));
1788 os_log_error(OS_LOG_DEFAULT
, "utun_remove_address - ifaddr_address failed (v6): %d",
1791 result
= sock_ioctl(pf_socket
, SIOCDIFADDR_IN6
, &ifr6
);
1793 os_log_error(OS_LOG_DEFAULT
, "utun_remove_address - SIOCDIFADDR_IN6 failed: %d",
1801 utun_cleanup_family(ifnet_t interface
,
1802 protocol_family_t protocol
)
1805 socket_t pf_socket
= NULL
;
1806 ifaddr_t
*addresses
= NULL
;
1809 if (protocol
!= PF_INET
&& protocol
!= PF_INET6
) {
1810 os_log_error(OS_LOG_DEFAULT
, "utun_cleanup_family - invalid protocol family %d\n", protocol
);
1814 /* Create a socket for removing addresses and detaching the protocol */
1815 result
= sock_socket(protocol
, SOCK_DGRAM
, 0, NULL
, NULL
, &pf_socket
);
1817 if (result
!= EAFNOSUPPORT
) {
1818 os_log_error(OS_LOG_DEFAULT
, "utun_cleanup_family - failed to create %s socket: %d\n",
1819 protocol
== PF_INET
? "IP" : "IPv6", result
);
1824 /* always set SS_PRIV, we want to close and detach regardless */
1825 sock_setpriv(pf_socket
, 1);
1827 result
= utun_detach_ip(interface
, protocol
, pf_socket
);
1828 if (result
== 0 || result
== ENXIO
) {
1829 /* We are done! We either detached or weren't attached. */
1831 } else if (result
!= EBUSY
) {
1832 /* Uh, not really sure what happened here... */
1833 os_log_error(OS_LOG_DEFAULT
, "utun_cleanup_family - utun_detach_ip failed: %d\n", result
);
1838 * At this point, we received an EBUSY error. This means there are
1839 * addresses attached. We should detach them and then try again.
1841 result
= ifnet_get_address_list_family(interface
, &addresses
, protocol
);
1843 os_log_error(OS_LOG_DEFAULT
, "fnet_get_address_list_family(%s%d, 0xblah, %s) - failed: %d\n",
1844 ifnet_name(interface
), ifnet_unit(interface
),
1845 protocol
== PF_INET
? "PF_INET" : "PF_INET6", result
);
1849 for (i
= 0; addresses
[i
] != 0; i
++) {
1850 utun_remove_address(interface
, protocol
, addresses
[i
], pf_socket
);
1852 ifnet_free_address_list(addresses
);
1856 * The addresses should be gone, we should try the remove again.
1858 result
= utun_detach_ip(interface
, protocol
, pf_socket
);
1859 if (result
!= 0 && result
!= ENXIO
) {
1860 os_log_error(OS_LOG_DEFAULT
, "utun_cleanup_family - utun_detach_ip failed: %d\n", result
);
1864 if (pf_socket
!= NULL
) {
1865 sock_close(pf_socket
);
1868 if (addresses
!= NULL
) {
1869 ifnet_free_address_list(addresses
);
1874 utun_ctl_disconnect(__unused kern_ctl_ref kctlref
,
1875 __unused u_int32_t unit
,
1878 struct utun_pcb
*pcb
= unitinfo
;
1887 // Tell the nexus to stop all rings
1888 if (pcb
->utun_netif_nexus
!= NULL
&& pcb
->utun_netif_connected
) {
1889 kern_nexus_stop(pcb
->utun_netif_nexus
);
1891 #endif // UTUN_NEXUS
1893 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
1897 uuid_copy(kpipe_uuid
, pcb
->utun_kpipe_uuid
);
1898 uuid_clear(pcb
->utun_kpipe_uuid
);
1899 pcb
->utun_kpipe_enabled
= FALSE
;
1900 #endif // UTUN_NEXUS
1902 pcb
->utun_ctlref
= NULL
;
1904 ifp
= pcb
->utun_ifp
;
1907 // Tell the nexus to stop all rings
1908 if (pcb
->utun_netif_nexus
!= NULL
) {
1910 * Quiesce the interface and flush any pending outbound packets.
1914 /* Increment refcnt, but detach interface */
1915 ifnet_incr_iorefcnt(ifp
);
1916 if ((result
= ifnet_detach(ifp
)) != 0) {
1917 panic("utun_ctl_disconnect - ifnet_detach failed: %d\n", result
);
1921 * We want to do everything in our power to ensure that the interface
1922 * really goes away when the socket is closed. We must remove IP/IPv6
1923 * addresses and detach the protocols. Finally, we can remove and
1924 * release the interface.
1926 utun_cleanup_family(ifp
, AF_INET
);
1927 utun_cleanup_family(ifp
, AF_INET6
);
1929 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1931 if (!uuid_is_null(kpipe_uuid
)) {
1932 if (kern_nexus_controller_free_provider_instance(utun_ncd
, kpipe_uuid
) == 0) {
1933 if (pcb
->utun_kpipe_pp
!= NULL
) {
1934 kern_pbufpool_destroy(pcb
->utun_kpipe_pp
);
1935 pcb
->utun_kpipe_pp
= NULL
;
1937 utun_unregister_kernel_pipe_nexus();
1940 utun_nexus_detach(pcb
);
1942 /* Decrement refcnt to finish detaching and freeing */
1943 ifnet_decr_iorefcnt(ifp
);
1945 #endif // UTUN_NEXUS
1947 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1950 if (!uuid_is_null(kpipe_uuid
)) {
1951 if (kern_nexus_controller_free_provider_instance(utun_ncd
, kpipe_uuid
) == 0) {
1952 if (pcb
->utun_kpipe_pp
!= NULL
) {
1953 kern_pbufpool_destroy(pcb
->utun_kpipe_pp
);
1954 pcb
->utun_kpipe_pp
= NULL
;
1956 utun_unregister_kernel_pipe_nexus();
1959 #endif // UTUN_NEXUS
1962 * We want to do everything in our power to ensure that the interface
1963 * really goes away when the socket is closed. We must remove IP/IPv6
1964 * addresses and detach the protocols. Finally, we can remove and
1965 * release the interface.
1967 utun_cleanup_family(ifp
, AF_INET
);
1968 utun_cleanup_family(ifp
, AF_INET6
);
1971 * Detach now; utun_detach() will be called asynchronously once
1972 * the I/O reference count drops to 0. There we will invoke
1975 if ((result
= ifnet_detach(ifp
)) != 0) {
1976 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_disconnect - ifnet_detach failed: %d\n", result
);
1980 // Bound, but not connected
1981 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1982 utun_free_pcb(pcb
, false);
1989 utun_ctl_send(__unused kern_ctl_ref kctlref
,
1990 __unused u_int32_t unit
,
1996 * The userland ABI requires the first four bytes have the protocol family
1997 * in network byte order: swap them
1999 if (m_pktlen(m
) >= (int32_t)UTUN_HEADER_SIZE((struct utun_pcb
*)unitinfo
)) {
2000 *(protocol_family_t
*)mbuf_data(m
) = ntohl(*(protocol_family_t
*)mbuf_data(m
));
2002 os_log_error(OS_LOG_DEFAULT
, "%s - unexpected short mbuf pkt len %d\n", __func__
, m_pktlen(m
));
2005 return utun_pkt_input((struct utun_pcb
*)unitinfo
, m
);
2009 utun_ctl_setopt(__unused kern_ctl_ref kctlref
,
2010 __unused u_int32_t unit
,
2016 struct utun_pcb
*pcb
= unitinfo
;
2018 /* check for privileges for privileged options */
2020 case UTUN_OPT_FLAGS
:
2021 case UTUN_OPT_EXT_IFDATA_STATS
:
2022 case UTUN_OPT_SET_DELEGATE_INTERFACE
:
2023 if (kauth_cred_issuser(kauth_cred_get()) == 0) {
2030 case UTUN_OPT_FLAGS
:
2031 if (len
!= sizeof(u_int32_t
)) {
2035 if (pcb
->utun_ifp
!= NULL
) {
2036 // Only can set before connecting
2040 pcb
->utun_flags
= *(u_int32_t
*)data
;
2043 case UTUN_OPT_EXT_IFDATA_STATS
:
2044 if (len
!= sizeof(int)) {
2048 if (pcb
->utun_ifp
== NULL
) {
2049 // Only can set after connecting
2053 pcb
->utun_ext_ifdata_stats
= (*(int *)data
) ? 1 : 0;
2056 case UTUN_OPT_INC_IFDATA_STATS_IN
:
2057 case UTUN_OPT_INC_IFDATA_STATS_OUT
: {
2058 struct utun_stats_param
*utsp
= (struct utun_stats_param
*)data
;
2060 if (utsp
== NULL
|| len
< sizeof(struct utun_stats_param
)) {
2064 if (pcb
->utun_ifp
== NULL
) {
2065 // Only can set after connecting
2069 if (!pcb
->utun_ext_ifdata_stats
) {
2073 if (opt
== UTUN_OPT_INC_IFDATA_STATS_IN
) {
2074 ifnet_stat_increment_in(pcb
->utun_ifp
, utsp
->utsp_packets
,
2075 utsp
->utsp_bytes
, utsp
->utsp_errors
);
2077 ifnet_stat_increment_out(pcb
->utun_ifp
, utsp
->utsp_packets
,
2078 utsp
->utsp_bytes
, utsp
->utsp_errors
);
2082 case UTUN_OPT_SET_DELEGATE_INTERFACE
: {
2083 ifnet_t del_ifp
= NULL
;
2084 char name
[IFNAMSIZ
];
2086 if (len
> IFNAMSIZ
- 1) {
2090 if (pcb
->utun_ifp
== NULL
) {
2091 // Only can set after connecting
2095 if (len
!= 0) { /* if len==0, del_ifp will be NULL causing the delegate to be removed */
2096 bcopy(data
, name
, len
);
2098 result
= ifnet_find_by_name(name
, &del_ifp
);
2101 result
= ifnet_set_delegate(pcb
->utun_ifp
, del_ifp
);
2103 ifnet_release(del_ifp
);
2108 case UTUN_OPT_MAX_PENDING_PACKETS
: {
2109 u_int32_t max_pending_packets
= 0;
2110 if (len
!= sizeof(u_int32_t
)) {
2114 max_pending_packets
= *(u_int32_t
*)data
;
2115 if (max_pending_packets
== 0) {
2119 pcb
->utun_max_pending_packets
= max_pending_packets
;
2123 case UTUN_OPT_ENABLE_CHANNEL
: {
2124 if (len
!= sizeof(int)) {
2128 if (pcb
->utun_ifp
== NULL
) {
2129 // Only can set after connecting
2134 result
= utun_enable_channel(pcb
, current_proc());
2136 result
= utun_disable_channel(pcb
);
2140 case UTUN_OPT_ENABLE_FLOWSWITCH
: {
2141 if (len
!= sizeof(int)) {
2145 if (pcb
->utun_ifp
== NULL
) {
2146 // Only can set after connecting
2150 if (!if_is_fsw_transport_netagent_enabled()) {
2154 if (uuid_is_null(pcb
->utun_nx
.fsw_agent
)) {
2159 uint32_t flags
= netagent_get_flags(pcb
->utun_nx
.fsw_agent
);
2162 pcb
->utun_needs_netagent
= true;
2163 flags
|= (NETAGENT_FLAG_NEXUS_PROVIDER
|
2164 NETAGENT_FLAG_NEXUS_LISTENER
);
2165 result
= netagent_set_flags(pcb
->utun_nx
.fsw_agent
, flags
);
2167 flags
&= ~(NETAGENT_FLAG_NEXUS_PROVIDER
|
2168 NETAGENT_FLAG_NEXUS_LISTENER
);
2169 result
= netagent_set_flags(pcb
->utun_nx
.fsw_agent
, flags
);
2170 pcb
->utun_needs_netagent
= false;
2174 case UTUN_OPT_ATTACH_FLOWSWITCH
: {
2175 if (len
!= sizeof(int)) {
2179 if (pcb
->utun_ifp
!= NULL
) {
2180 // Only can set before connecting
2184 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
2185 pcb
->utun_attach_fsw
= !!(*(int *)data
);
2186 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
2189 case UTUN_OPT_ENABLE_NETIF
: {
2190 if (len
!= sizeof(int)) {
2194 if (pcb
->utun_ifp
!= NULL
) {
2195 // Only can set before connecting
2199 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
2200 pcb
->utun_use_netif
= !!(*(int *)data
);
2201 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
2204 case UTUN_OPT_SLOT_SIZE
: {
2205 if (len
!= sizeof(u_int32_t
)) {
2209 if (pcb
->utun_ifp
!= NULL
) {
2210 // Only can set before connecting
2214 u_int32_t slot_size
= *(u_int32_t
*)data
;
2215 if (slot_size
< UTUN_IF_MIN_SLOT_SIZE
||
2216 slot_size
> UTUN_IF_MAX_SLOT_SIZE
) {
2219 pcb
->utun_slot_size
= slot_size
;
2222 case UTUN_OPT_NETIF_RING_SIZE
: {
2223 if (len
!= sizeof(u_int32_t
)) {
2227 if (pcb
->utun_ifp
!= NULL
) {
2228 // Only can set before connecting
2232 u_int32_t ring_size
= *(u_int32_t
*)data
;
2233 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2234 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2237 pcb
->utun_netif_ring_size
= ring_size
;
2240 case UTUN_OPT_TX_FSW_RING_SIZE
: {
2241 if (len
!= sizeof(u_int32_t
)) {
2245 if (pcb
->utun_ifp
!= NULL
) {
2246 // Only can set before connecting
2250 u_int32_t ring_size
= *(u_int32_t
*)data
;
2251 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2252 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2255 pcb
->utun_tx_fsw_ring_size
= ring_size
;
2258 case UTUN_OPT_RX_FSW_RING_SIZE
: {
2259 if (len
!= sizeof(u_int32_t
)) {
2263 if (pcb
->utun_ifp
!= NULL
) {
2264 // Only can set before connecting
2268 u_int32_t ring_size
= *(u_int32_t
*)data
;
2269 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2270 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2273 pcb
->utun_rx_fsw_ring_size
= ring_size
;
2276 case UTUN_OPT_KPIPE_TX_RING_SIZE
: {
2277 if (len
!= sizeof(u_int32_t
)) {
2281 if (pcb
->utun_ifp
!= NULL
) {
2282 // Only can set before connecting
2286 u_int32_t ring_size
= *(u_int32_t
*)data
;
2287 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2288 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2291 pcb
->utun_kpipe_tx_ring_size
= ring_size
;
2294 case UTUN_OPT_KPIPE_RX_RING_SIZE
: {
2295 if (len
!= sizeof(u_int32_t
)) {
2299 if (pcb
->utun_ifp
!= NULL
) {
2300 // Only can set before connecting
2304 u_int32_t ring_size
= *(u_int32_t
*)data
;
2305 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2306 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2309 pcb
->utun_kpipe_rx_ring_size
= ring_size
;
2312 #endif // UTUN_NEXUS
2314 result
= ENOPROTOOPT
;
2323 utun_ctl_getopt(__unused kern_ctl_ref kctlref
,
2324 __unused u_int32_t unit
,
2330 struct utun_pcb
*pcb
= unitinfo
;
2334 case UTUN_OPT_FLAGS
:
2335 if (*len
!= sizeof(u_int32_t
)) {
2338 *(u_int32_t
*)data
= pcb
->utun_flags
;
2342 case UTUN_OPT_EXT_IFDATA_STATS
:
2343 if (*len
!= sizeof(int)) {
2346 *(int *)data
= (pcb
->utun_ext_ifdata_stats
) ? 1 : 0;
2350 case UTUN_OPT_IFNAME
:
2351 if (*len
< MIN(strlen(pcb
->utun_if_xname
) + 1, sizeof(pcb
->utun_if_xname
))) {
2354 if (pcb
->utun_ifp
== NULL
) {
2355 // Only can get after connecting
2359 *len
= scnprintf(data
, *len
, "%s", pcb
->utun_if_xname
) + 1;
2363 case UTUN_OPT_MAX_PENDING_PACKETS
: {
2364 if (*len
!= sizeof(u_int32_t
)) {
2367 *((u_int32_t
*)data
) = pcb
->utun_max_pending_packets
;
2373 case UTUN_OPT_ENABLE_CHANNEL
: {
2374 if (*len
!= sizeof(int)) {
2377 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2378 *(int *)data
= pcb
->utun_kpipe_enabled
;
2379 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2384 case UTUN_OPT_ENABLE_FLOWSWITCH
: {
2385 if (*len
!= sizeof(int)) {
2388 *(int *)data
= if_check_netagent(pcb
->utun_ifp
, pcb
->utun_nx
.fsw_agent
);
2393 case UTUN_OPT_ENABLE_NETIF
: {
2394 if (*len
!= sizeof(int)) {
2397 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2398 *(int *)data
= !!pcb
->utun_use_netif
;
2399 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2404 case UTUN_OPT_GET_CHANNEL_UUID
: {
2405 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2406 if (uuid_is_null(pcb
->utun_kpipe_uuid
)) {
2408 } else if (*len
!= sizeof(uuid_t
)) {
2411 uuid_copy(data
, pcb
->utun_kpipe_uuid
);
2413 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2416 case UTUN_OPT_SLOT_SIZE
: {
2417 if (*len
!= sizeof(u_int32_t
)) {
2420 *(u_int32_t
*)data
= pcb
->utun_slot_size
;
2424 case UTUN_OPT_NETIF_RING_SIZE
: {
2425 if (*len
!= sizeof(u_int32_t
)) {
2428 *(u_int32_t
*)data
= pcb
->utun_netif_ring_size
;
2432 case UTUN_OPT_TX_FSW_RING_SIZE
: {
2433 if (*len
!= sizeof(u_int32_t
)) {
2436 *(u_int32_t
*)data
= pcb
->utun_tx_fsw_ring_size
;
2440 case UTUN_OPT_RX_FSW_RING_SIZE
: {
2441 if (*len
!= sizeof(u_int32_t
)) {
2444 *(u_int32_t
*)data
= pcb
->utun_rx_fsw_ring_size
;
2448 case UTUN_OPT_KPIPE_TX_RING_SIZE
: {
2449 if (*len
!= sizeof(u_int32_t
)) {
2452 *(u_int32_t
*)data
= pcb
->utun_kpipe_tx_ring_size
;
2456 case UTUN_OPT_KPIPE_RX_RING_SIZE
: {
2457 if (*len
!= sizeof(u_int32_t
)) {
2460 *(u_int32_t
*)data
= pcb
->utun_kpipe_rx_ring_size
;
2464 #endif // UTUN_NEXUS
2467 result
= ENOPROTOOPT
;
2475 utun_ctl_rcvd(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
, int flags
)
2477 #pragma unused(flags)
2478 bool reenable_output
= false;
2479 struct utun_pcb
*pcb
= unitinfo
;
2483 ifnet_lock_exclusive(pcb
->utun_ifp
);
2485 u_int32_t utun_packet_cnt
;
2486 errno_t error_pc
= ctl_getenqueuepacketcount(kctlref
, unit
, &utun_packet_cnt
);
2487 if (error_pc
!= 0) {
2488 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_rcvd: ctl_getenqueuepacketcount returned error %d\n", error_pc
);
2489 utun_packet_cnt
= 0;
2492 if (utun_packet_cnt
< pcb
->utun_max_pending_packets
) {
2493 reenable_output
= true;
2496 if (reenable_output
) {
2497 errno_t error
= ifnet_enable_output(pcb
->utun_ifp
);
2499 os_log_error(OS_LOG_DEFAULT
, "utun_ctl_rcvd: ifnet_enable_output returned error %d\n", error
);
2502 ifnet_lock_done(pcb
->utun_ifp
);
2505 /* Network Interface functions */
2507 utun_start(ifnet_t interface
)
2510 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2512 VERIFY(pcb
!= NULL
);
2515 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2516 if (pcb
->utun_kpipe_enabled
) {
2517 /* It's possible to have channels enabled, but not yet have the channel opened,
2518 * in which case the rxring will not be set
2520 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2521 if (pcb
->utun_kpipe_rxring
!= NULL
) {
2522 kern_channel_notify(pcb
->utun_kpipe_rxring
, 0);
2526 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2527 #endif // UTUN_NEXUS
2530 bool can_accept_packets
= true;
2531 ifnet_lock_shared(pcb
->utun_ifp
);
2533 u_int32_t utun_packet_cnt
;
2534 errno_t error_pc
= ctl_getenqueuepacketcount(pcb
->utun_ctlref
, pcb
->utun_unit
, &utun_packet_cnt
);
2535 if (error_pc
!= 0) {
2536 os_log_error(OS_LOG_DEFAULT
, "utun_start: ctl_getenqueuepacketcount returned error %d\n", error_pc
);
2537 utun_packet_cnt
= 0;
2540 can_accept_packets
= (utun_packet_cnt
< pcb
->utun_max_pending_packets
);
2541 if (!can_accept_packets
&& pcb
->utun_ctlref
) {
2542 u_int32_t difference
= 0;
2543 if (ctl_getenqueuereadable(pcb
->utun_ctlref
, pcb
->utun_unit
, &difference
) == 0) {
2544 if (difference
> 0) {
2545 // If the low-water mark has not yet been reached, we still need to enqueue data
2547 can_accept_packets
= true;
2551 if (!can_accept_packets
) {
2552 errno_t error
= ifnet_disable_output(interface
);
2554 os_log_error(OS_LOG_DEFAULT
, "utun_start: ifnet_disable_output returned error %d\n", error
);
2556 ifnet_lock_done(pcb
->utun_ifp
);
2559 ifnet_lock_done(pcb
->utun_ifp
);
2560 if (ifnet_dequeue(interface
, &data
) != 0) {
2563 if (utun_output(interface
, data
) != 0) {
2570 utun_output(ifnet_t interface
,
2573 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2576 VERIFY(interface
== pcb
->utun_ifp
);
2579 if (!pcb
->utun_use_netif
)
2580 #endif // UTUN_NEXUS
2582 if (m_pktlen(data
) >= (int32_t)UTUN_HEADER_SIZE(pcb
)) {
2583 bpf_tap_out(pcb
->utun_ifp
, DLT_NULL
, data
, 0, 0);
2587 if (pcb
->utun_flags
& UTUN_FLAGS_NO_OUTPUT
) {
2593 // otherwise, fall thru to ctl_enqueumbuf
2594 if (pcb
->utun_ctlref
) {
2598 * The ABI requires the protocol in network byte order
2600 if (m_pktlen(data
) >= (int32_t)UTUN_HEADER_SIZE(pcb
)) {
2601 *(u_int32_t
*)mbuf_data(data
) = htonl(*(u_int32_t
*)mbuf_data(data
));
2604 length
= mbuf_pkthdr_len(data
);
2605 result
= ctl_enqueuembuf(pcb
->utun_ctlref
, pcb
->utun_unit
, data
, CTL_DATA_EOR
);
2608 os_log_error(OS_LOG_DEFAULT
, "utun_output - ctl_enqueuembuf failed: %d\n", result
);
2610 if (!pcb
->utun_use_netif
)
2611 #endif // UTUN_NEXUS
2613 ifnet_stat_increment_out(interface
, 0, 0, 1);
2617 if (!pcb
->utun_use_netif
)
2618 #endif // UTUN_NEXUS
2620 if (!pcb
->utun_ext_ifdata_stats
) {
2621 ifnet_stat_increment_out(interface
, 1, length
, 0);
2633 utun_demux(__unused ifnet_t interface
,
2635 __unused
char *frame_header
,
2636 protocol_family_t
*protocol
)
2639 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2644 while (data
!= NULL
&& mbuf_len(data
) < 1) {
2645 data
= mbuf_next(data
);
2653 if (pcb
->utun_use_netif
) {
2654 ip
= mtod(data
, struct ip
*);
2655 ip_version
= ip
->ip_v
;
2657 switch (ip_version
) {
2659 *protocol
= PF_INET
;
2662 *protocol
= PF_INET6
;
2669 #endif // UTUN_NEXUS
2671 *protocol
= *(u_int32_t
*)mbuf_data(data
);
2678 utun_framer(ifnet_t interface
,
2680 __unused
const struct sockaddr
*dest
,
2681 __unused
const char *desk_linkaddr
,
2682 const char *frame_type
,
2683 u_int32_t
*prepend_len
,
2684 u_int32_t
*postpend_len
)
2686 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2687 VERIFY(interface
== pcb
->utun_ifp
);
2689 u_int32_t header_length
= UTUN_HEADER_SIZE(pcb
);
2690 if (mbuf_prepend(packet
, header_length
, MBUF_DONTWAIT
) != 0) {
2691 os_log_error(OS_LOG_DEFAULT
, "utun_framer - ifnet_output prepend failed\n");
2693 ifnet_stat_increment_out(interface
, 0, 0, 1);
2695 // just return, because the buffer was freed in mbuf_prepend
2698 if (prepend_len
!= NULL
) {
2699 *prepend_len
= header_length
;
2701 if (postpend_len
!= NULL
) {
2705 // place protocol number at the beginning of the mbuf
2706 *(protocol_family_t
*)mbuf_data(*packet
) = *(protocol_family_t
*)(uintptr_t)(size_t)frame_type
;
2713 utun_add_proto(__unused ifnet_t interface
,
2714 protocol_family_t protocol
,
2715 __unused
const struct ifnet_demux_desc
*demux_array
,
2716 __unused u_int32_t demux_count
)
2731 utun_del_proto(__unused ifnet_t interface
,
2732 __unused protocol_family_t protocol
)
2738 utun_ioctl(ifnet_t interface
,
2743 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2750 if (pcb
->utun_use_netif
) {
2751 // Make sure we can fit packets in the channel buffers
2752 // Allow for the headroom in the slot
2753 if (((uint64_t)((struct ifreq
*)data
)->ifr_mtu
) + UTUN_IF_HEADROOM_SIZE
> pcb
->utun_slot_size
) {
2756 ifnet_set_mtu(interface
, (uint32_t)((struct ifreq
*)data
)->ifr_mtu
);
2759 #endif // UTUN_NEXUS
2761 ifnet_set_mtu(interface
, ((struct ifreq
*)data
)->ifr_mtu
);
2767 /* ifioctl() takes care of it */
2771 result
= EOPNOTSUPP
;
2778 utun_detached(ifnet_t interface
)
2780 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2781 (void)ifnet_release(interface
);
2782 lck_mtx_lock(&utun_lock
);
2783 utun_free_pcb(pcb
, true);
2784 (void)ifnet_dispose(interface
);
2785 lck_mtx_unlock(&utun_lock
);
2788 /* Protocol Handlers */
2791 utun_proto_input(__unused ifnet_t interface
,
2792 protocol_family_t protocol
,
2794 __unused
char *frame_header
)
2796 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2798 if (!pcb
->utun_use_netif
)
2799 #endif // UTUN_NEXUS
2801 mbuf_adj(m
, UTUN_HEADER_SIZE(pcb
));
2803 int32_t pktlen
= m
->m_pkthdr
.len
;
2804 if (proto_input(protocol
, m
) != 0) {
2807 if (!pcb
->utun_use_netif
)
2808 #endif // UTUN_NEXUS
2810 ifnet_stat_increment_in(interface
, 0, 0, 1);
2814 if (!pcb
->utun_use_netif
)
2815 #endif // UTUN_NEXUS
2817 ifnet_stat_increment_in(interface
, 1, pktlen
, 0);
2825 utun_proto_pre_output(__unused ifnet_t interface
,
2826 protocol_family_t protocol
,
2827 __unused mbuf_t
*packet
,
2828 __unused
const struct sockaddr
*dest
,
2829 __unused
void *route
,
2831 __unused
char *link_layer_dest
)
2833 *(protocol_family_t
*)(void *)frame_type
= protocol
;
2838 utun_attach_proto(ifnet_t interface
,
2839 protocol_family_t protocol
)
2841 struct ifnet_attach_proto_param proto
;
2843 bzero(&proto
, sizeof(proto
));
2844 proto
.input
= utun_proto_input
;
2845 proto
.pre_output
= utun_proto_pre_output
;
2847 errno_t result
= ifnet_attach_protocol(interface
, protocol
, &proto
);
2848 if (result
!= 0 && result
!= EEXIST
) {
2849 os_log_error(OS_LOG_DEFAULT
, "utun_attach_inet - ifnet_attach_protocol %d failed: %d\n",
2857 utun_pkt_input(struct utun_pcb
*pcb
, mbuf_t packet
)
2860 if (pcb
->utun_use_netif
) {
2861 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2863 lck_mtx_lock(&pcb
->utun_input_chain_lock
);
2865 if (pcb
->utun_input_chain_count
> (u_int32_t
)if_utun_max_pending_input
) {
2866 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
2867 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2871 if (pcb
->utun_input_chain
!= NULL
) {
2872 pcb
->utun_input_chain_last
->m_nextpkt
= packet
;
2874 pcb
->utun_input_chain
= packet
;
2876 pcb
->utun_input_chain_count
++;
2877 while (packet
->m_nextpkt
) {
2878 VERIFY(packet
!= packet
->m_nextpkt
);
2879 packet
= packet
->m_nextpkt
;
2880 pcb
->utun_input_chain_count
++;
2882 pcb
->utun_input_chain_last
= packet
;
2883 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
2885 kern_channel_ring_t rx_ring
= pcb
->utun_netif_rxring
;
2886 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2888 if (rx_ring
!= NULL
) {
2889 kern_channel_notify(rx_ring
, 0);
2894 #endif // UTUN_NEXUS
2896 mbuf_pkthdr_setrcvif(packet
, pcb
->utun_ifp
);
2898 if (m_pktlen(packet
) >= (int32_t)UTUN_HEADER_SIZE(pcb
)) {
2899 bpf_tap_in(pcb
->utun_ifp
, DLT_NULL
, packet
, 0, 0);
2901 if (pcb
->utun_flags
& UTUN_FLAGS_NO_INPUT
) {
2908 if (!pcb
->utun_ext_ifdata_stats
) {
2909 struct ifnet_stat_increment_param incs
= {};
2910 incs
.packets_in
= 1;
2911 incs
.bytes_in
= mbuf_pkthdr_len(packet
);
2912 result
= ifnet_input(pcb
->utun_ifp
, packet
, &incs
);
2914 result
= ifnet_input(pcb
->utun_ifp
, packet
, NULL
);
2917 ifnet_stat_increment_in(pcb
->utun_ifp
, 0, 0, 1);
2919 os_log_error(OS_LOG_DEFAULT
, "%s - ifnet_input failed: %d\n", __FUNCTION__
, result
);
2930 utun_nxdp_init(__unused kern_nexus_domain_provider_t domprov
)
2936 utun_nxdp_fini(__unused kern_nexus_domain_provider_t domprov
)
2942 utun_register_nexus(void)
2944 const struct kern_nexus_domain_provider_init dp_init
= {
2945 .nxdpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
2947 .nxdpi_init
= utun_nxdp_init
,
2948 .nxdpi_fini
= utun_nxdp_fini
2952 /* utun_nxdp_init() is called before this function returns */
2953 err
= kern_nexus_register_domain_provider(NEXUS_TYPE_NET_IF
,
2954 (const uint8_t *) "com.apple.utun",
2955 &dp_init
, sizeof(dp_init
),
2958 os_log_error(OS_LOG_DEFAULT
, "%s: failed to register domain provider\n", __func__
);
2964 utun_interface_needs_netagent(ifnet_t interface
)
2966 struct utun_pcb
*pcb
= NULL
;
2968 if (interface
== NULL
) {
2972 pcb
= ifnet_softc(interface
);
2978 return pcb
->utun_needs_netagent
== true;
2982 utun_ifnet_set_attrs(ifnet_t ifp
)
2984 /* Set flags and additional information. */
2985 ifnet_set_mtu(ifp
, 1500);
2986 ifnet_set_flags(ifp
, IFF_UP
| IFF_MULTICAST
| IFF_POINTOPOINT
, 0xffff);
2988 /* The interface must generate its own IPv6 LinkLocal address,
2989 * if possible following the recommendation of RFC2472 to the 64bit interface ID
2991 ifnet_set_eflags(ifp
, IFEF_NOAUTOIPV6LL
, IFEF_NOAUTOIPV6LL
);
2997 utun_netif_prepare(kern_nexus_t nexus
, ifnet_t ifp
)
2999 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3000 pcb
->utun_netif_nexus
= nexus
;
3001 return utun_ifnet_set_attrs(ifp
);
3005 utun_nexus_pre_connect(kern_nexus_provider_t nxprov
,
3006 proc_t p
, kern_nexus_t nexus
,
3007 nexus_port_t nexus_port
, kern_channel_t channel
, void **ch_ctx
)
3009 #pragma unused(nxprov, p)
3010 #pragma unused(nexus, nexus_port, channel, ch_ctx)
3015 utun_nexus_connected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3016 kern_channel_t channel
)
3018 #pragma unused(nxprov, channel)
3019 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3020 boolean_t ok
= ifnet_is_attached(pcb
->utun_ifp
, 1);
3021 if (pcb
->utun_netif_nexus
== nexus
) {
3022 pcb
->utun_netif_connected
= true;
3024 return ok
? 0 : ENXIO
;
3028 utun_nexus_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3029 kern_channel_t channel
)
3031 #pragma unused(nxprov, nexus, channel)
3035 utun_netif_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3036 kern_channel_t channel
)
3038 #pragma unused(nxprov, nexus, channel)
3042 utun_nexus_disconnected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3043 kern_channel_t channel
)
3045 #pragma unused(nxprov, channel)
3046 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3047 if (pcb
->utun_netif_nexus
== nexus
) {
3048 pcb
->utun_netif_connected
= false;
3049 if (pcb
->utun_attach_fsw
) {
3050 // disconnected by flowswitch that was attached by us
3051 pcb
->utun_netif_nexus
= NULL
;
3054 ifnet_decr_iorefcnt(pcb
->utun_ifp
);
3058 utun_kpipe_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3059 kern_channel_t channel
, kern_channel_ring_t ring
,
3060 boolean_t is_tx_ring
, void **ring_ctx
)
3062 #pragma unused(nxprov)
3063 #pragma unused(channel)
3064 #pragma unused(ring_ctx)
3065 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3067 VERIFY(pcb
->utun_kpipe_rxring
== NULL
);
3068 pcb
->utun_kpipe_rxring
= ring
;
3070 VERIFY(pcb
->utun_kpipe_txring
== NULL
);
3071 pcb
->utun_kpipe_txring
= ring
;
3077 utun_kpipe_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3078 kern_channel_ring_t ring
)
3080 #pragma unused(nxprov)
3081 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3082 if (pcb
->utun_kpipe_rxring
== ring
) {
3083 pcb
->utun_kpipe_rxring
= NULL
;
3084 } else if (pcb
->utun_kpipe_txring
== ring
) {
3085 pcb
->utun_kpipe_txring
= NULL
;
3090 utun_kpipe_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3091 kern_channel_ring_t tx_ring
, uint32_t flags
)
3093 #pragma unused(nxprov)
3094 #pragma unused(flags)
3095 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3097 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
3098 int channel_enabled
= pcb
->utun_kpipe_enabled
;
3099 if (!channel_enabled
) {
3100 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3104 if (pcb
->utun_use_netif
) {
3105 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
3106 if (tx_slot
== NULL
) {
3107 // Nothing to write, bail
3108 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3112 // Signal the netif ring to read
3113 kern_channel_ring_t rx_ring
= pcb
->utun_netif_rxring
;
3114 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3115 if (rx_ring
!= NULL
) {
3116 kern_channel_notify(rx_ring
, 0);
3119 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3121 struct ifnet_stat_increment_param incs
= {};
3122 struct kern_channel_ring_stat_increment tx_ring_stats
= {};
3123 MBUFQ_HEAD(mbufq
) mbq
;
3125 kern_channel_slot_t tx_pslot
= NULL
;
3126 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
3127 while (tx_slot
!= NULL
) {
3128 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
3132 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
3138 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
3139 VERIFY(tx_buf
!= NULL
);
3140 uint8_t *tx_baddr
= kern_buflet_get_data_address(tx_buf
);
3141 VERIFY(tx_baddr
!= 0);
3142 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
3144 size_t length
= MIN(kern_packet_get_data_length(tx_ph
),
3145 pcb
->utun_slot_size
);
3148 if (length
>= UTUN_HEADER_SIZE(pcb
) &&
3149 !(pcb
->utun_flags
& UTUN_FLAGS_NO_INPUT
)) {
3150 errno_t error
= mbuf_gethdr(MBUF_WAITOK
, MBUF_TYPE_HEADER
, &data
);
3152 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_WAITOK
);
3155 * The userland ABI requires the first four bytes have
3156 * the protocol family in network byte order: swap them
3158 *(uint32_t *)mbuf_data(data
) = ntohl(*(uint32_t *)mbuf_data(data
));
3159 mbuf_pkthdr_setrcvif(data
, pcb
->utun_ifp
);
3160 bpf_tap_in(pcb
->utun_ifp
, DLT_NULL
, data
, 0, 0);
3162 incs
.bytes_in
+= length
;
3163 MBUFQ_ENQUEUE(&mbq
, data
);
3167 kern_channel_advance_slot(tx_ring
, tx_pslot
);
3168 tx_ring_stats
.kcrsi_slots_transferred
= incs
.packets_in
;
3169 tx_ring_stats
.kcrsi_bytes_transferred
= incs
.bytes_in
;
3170 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
3171 (void) kern_channel_reclaim(tx_ring
);
3173 if (!MBUFQ_EMPTY(&mbq
)) {
3174 (void) ifnet_input_extended(pcb
->utun_ifp
, MBUFQ_FIRST(&mbq
),
3175 MBUFQ_LAST(&mbq
), &incs
);
3184 utun_kpipe_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
3185 kern_channel_ring_t rx_ring
, uint32_t flags
)
3187 #pragma unused(nxprov)
3188 #pragma unused(flags)
3189 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
3190 struct kern_channel_ring_stat_increment rx_ring_stats
= {};
3192 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
3194 int channel_enabled
= pcb
->utun_kpipe_enabled
;
3195 if (!channel_enabled
) {
3196 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3200 /* reclaim user-released slots */
3201 (void) kern_channel_reclaim(rx_ring
);
3203 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
3205 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3209 if (pcb
->utun_use_netif
) {
3210 kern_channel_ring_t tx_ring
= pcb
->utun_netif_txring
;
3211 if (tx_ring
== NULL
||
3212 pcb
->utun_netif_nexus
== NULL
) {
3213 // Net-If TX ring not set up yet, nothing to read
3214 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3218 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(pcb
->utun_netif_nexus
)->nif_stats
;
3220 // Unlock utun before entering ring
3221 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3223 (void)kr_enter(tx_ring
, TRUE
);
3225 // Lock again after entering and validate
3226 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
3227 if (tx_ring
!= pcb
->utun_netif_txring
) {
3228 // Ring no longer valid
3229 // Unlock first, then exit ring
3230 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3235 struct kern_channel_ring_stat_increment tx_ring_stats
;
3236 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
3237 kern_channel_slot_t tx_pslot
= NULL
;
3238 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
3239 if (tx_slot
== NULL
) {
3240 // Nothing to read, don't bother signalling
3241 // Unlock first, then exit ring
3242 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3247 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
3248 VERIFY(rx_pp
!= NULL
);
3249 kern_channel_slot_t rx_pslot
= NULL
;
3250 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
3252 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
3254 kern_buflet_t rx_buf
;
3257 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
3261 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
3263 /* Skip slot if packet is zero-length or marked as dropped (QUMF_DROPPED) */
3268 // Allocate rx packet
3269 kern_packet_t rx_ph
= 0;
3270 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
3271 if (__improbable(error
!= 0)) {
3272 os_log_error(OS_LOG_DEFAULT
, "utun_kpipe_sync_rx %s: failed to allocate packet\n",
3273 pcb
->utun_ifp
->if_xname
);
3277 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
3278 VERIFY(tx_buf
!= NULL
);
3279 uint8_t *tx_baddr
= kern_buflet_get_data_address(tx_buf
);
3280 VERIFY(tx_baddr
!= NULL
);
3281 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
3283 bpf_tap_packet_out(pcb
->utun_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
3285 length
= MIN(kern_packet_get_data_length(tx_ph
) + UTUN_HEADER_SIZE(pcb
),
3286 pcb
->utun_slot_size
);
3288 tx_ring_stats
.kcrsi_slots_transferred
++;
3289 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
3291 if (length
< UTUN_HEADER_SIZE(pcb
) ||
3292 length
> pcb
->utun_slot_size
||
3293 length
> rx_pp
->pp_buflet_size
||
3294 (pcb
->utun_flags
& UTUN_FLAGS_NO_OUTPUT
)) {
3296 kern_pbufpool_free(rx_pp
, rx_ph
);
3297 os_log_error(OS_LOG_DEFAULT
, "utun_kpipe_sync_rx %s: invalid length %zu header_size %zu\n",
3298 pcb
->utun_ifp
->if_xname
, length
, UTUN_HEADER_SIZE(pcb
));
3299 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
3300 STATS_INC(nifs
, NETIF_STATS_DROP
);
3304 /* fillout packet */
3305 rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
3306 VERIFY(rx_buf
!= NULL
);
3307 rx_baddr
= kern_buflet_get_data_address(rx_buf
);
3308 VERIFY(rx_baddr
!= NULL
);
3312 uint8_t vhl
= *(uint8_t *)(tx_baddr
);
3313 u_int ip_version
= (vhl
>> 4);
3314 switch (ip_version
) {
3324 os_log_error(OS_LOG_DEFAULT
, "utun_kpipe_sync_rx %s: unknown ip version %u vhl %u header_size %zu\n",
3325 pcb
->utun_ifp
->if_xname
, ip_version
, vhl
, UTUN_HEADER_SIZE(pcb
));
3332 memcpy((void *)rx_baddr
, &af
, sizeof(af
));
3333 if (pcb
->utun_flags
& UTUN_FLAGS_ENABLE_PROC_UUID
) {
3334 kern_packet_get_euuid(tx_ph
, (void *)(rx_baddr
+ sizeof(af
)));
3337 // Copy data from tx to rx
3338 memcpy((void *)(rx_baddr
+ UTUN_HEADER_SIZE(pcb
)), (void *)tx_baddr
, length
- UTUN_HEADER_SIZE(pcb
));
3339 kern_packet_clear_flow_uuid(rx_ph
); // zero flow id
3341 /* finalize and attach the packet */
3342 error
= kern_buflet_set_data_offset(rx_buf
, 0);
3344 error
= kern_buflet_set_data_length(rx_buf
, length
);
3346 error
= kern_packet_finalize(rx_ph
);
3348 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
3351 STATS_INC(nifs
, NETIF_STATS_TX_PACKETS
);
3352 STATS_INC(nifs
, NETIF_STATS_TX_COPY_DIRECT
);
3354 rx_ring_stats
.kcrsi_slots_transferred
++;
3355 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
3358 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
3362 kern_channel_advance_slot(rx_ring
, rx_pslot
);
3363 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->utun_ifp
, &rx_ring_stats
);
3367 kern_channel_advance_slot(tx_ring
, tx_pslot
);
3368 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
3369 (void)kern_channel_reclaim(tx_ring
);
3372 /* just like utun_ctl_rcvd(), always reenable output */
3373 errno_t error
= ifnet_enable_output(pcb
->utun_ifp
);
3375 os_log_error(OS_LOG_DEFAULT
, "utun_kpipe_sync_rx: ifnet_enable_output returned error %d\n", error
);
3378 // Unlock first, then exit ring
3379 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3381 if (tx_pslot
!= NULL
) {
3382 kern_channel_notify(tx_ring
, 0);
3386 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3388 uint32_t mb_cnt
= 0;
3389 uint32_t mb_len
= 0;
3390 struct mbuf
*mb_head
= NULL
;
3391 struct mbuf
*mb_tail
= NULL
;
3393 if (ifnet_dequeue_multi(pcb
->utun_ifp
, avail
, &mb_head
,
3394 &mb_tail
, &mb_cnt
, &mb_len
) != 0) {
3397 VERIFY(mb_cnt
<= avail
);
3399 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
3400 VERIFY(rx_pp
!= NULL
);
3401 kern_channel_slot_t rx_pslot
= NULL
;
3402 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
3406 if ((data
= mb_head
) == NULL
) {
3407 VERIFY(mb_cnt
== 0);
3410 mb_head
= mbuf_nextpkt(mb_head
);
3411 mbuf_setnextpkt(data
, NULL
);
3412 VERIFY(mb_cnt
!= 0);
3414 length
= mbuf_pkthdr_len(data
);
3415 if (length
< UTUN_HEADER_SIZE(pcb
) ||
3416 length
> pcb
->utun_slot_size
||
3417 (pcb
->utun_flags
& UTUN_FLAGS_NO_OUTPUT
)) {
3422 bpf_tap_out(pcb
->utun_ifp
, DLT_NULL
, data
, 0, 0);
3424 // Allocate rx packet
3425 kern_packet_t rx_ph
= 0;
3426 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
3427 if (__improbable(error
!= 0)) {
3428 os_log_error(OS_LOG_DEFAULT
, "utun_kpipe_sync_rx %s: failed to allocate packet\n",
3429 pcb
->utun_ifp
->if_xname
);
3434 * The ABI requires the protocol in network byte order
3436 *(u_int32_t
*)mbuf_data(data
) = htonl(*(u_int32_t
*)mbuf_data(data
));
3438 // Fillout rx packet
3439 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
3440 VERIFY(rx_buf
!= NULL
);
3441 void *rx_baddr
= kern_buflet_get_data_address(rx_buf
);
3442 VERIFY(rx_baddr
!= NULL
);
3444 // Copy-in data from mbuf to buflet
3445 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
3446 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
3448 // Finalize and attach the packet
3449 error
= kern_buflet_set_data_offset(rx_buf
, 0);
3451 error
= kern_buflet_set_data_length(rx_buf
, length
);
3453 error
= kern_packet_finalize(rx_ph
);
3455 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
3458 rx_ring_stats
.kcrsi_slots_transferred
++;
3459 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
3461 if (!pcb
->utun_ext_ifdata_stats
) {
3462 ifnet_stat_increment_out(pcb
->utun_ifp
, 1, length
, 0);
3468 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
3471 kern_channel_advance_slot(rx_ring
, rx_pslot
);
3472 kern_channel_increment_ring_stats(rx_ring
, &rx_ring_stats
);
3474 if (mb_head
!= NULL
) {
3475 VERIFY(mb_cnt
!= 0);
3476 mbuf_freem_list(mb_head
);
3483 #endif // UTUN_NEXUS
3487 * These are place holders until coreTLS kext stops calling them
3489 errno_t
utun_ctl_register_dtls(void *reg
);
3490 int utun_pkt_dtls_input(struct utun_pcb
*pcb
, mbuf_t
*pkt
, protocol_family_t family
);
3491 void utun_ctl_disable_crypto_dtls(struct utun_pcb
*pcb
);
3494 utun_ctl_register_dtls(void *reg
)
3501 utun_pkt_dtls_input(struct utun_pcb
*pcb
, mbuf_t
*pkt
, protocol_family_t family
)
3505 #pragma unused(family)
3510 utun_ctl_disable_crypto_dtls(struct utun_pcb
*pcb
)