2 * Copyright (c) 2008-2017 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
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>
60 extern unsigned int if_enable_netagent
;
63 static nexus_controller_t utun_ncd
;
64 static int utun_ncd_refcount
;
65 static uuid_t utun_kpipe_uuid
;
66 static uuid_t utun_nx_dom_prov
;
68 typedef struct utun_nx
{
80 /* Control block allocated for each kernel control connection */
82 TAILQ_ENTRY(utun_pcb
) utun_chain
;
83 kern_ctl_ref utun_ctlref
;
86 u_int32_t utun_unique_id
;
88 int utun_ext_ifdata_stats
;
89 u_int32_t utun_max_pending_packets
;
90 char utun_if_xname
[IFXNAMSIZ
];
91 char utun_unique_name
[IFXNAMSIZ
];
92 // PCB lock protects state fields and rings
93 decl_lck_rw_data(, utun_pcb_lock
);
94 struct mbuf
* utun_input_chain
;
95 struct mbuf
* utun_input_chain_last
;
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
;
107 kern_nexus_t utun_netif_nexus
;
108 void * utun_netif_rxring
;
109 void * utun_netif_txring
;
110 uint64_t utun_netif_txring_size
;
112 u_int32_t utun_slot_size
;
113 u_int32_t utun_netif_ring_size
;
114 u_int32_t utun_tx_fsw_ring_size
;
115 u_int32_t utun_rx_fsw_ring_size
;
120 /* Kernel Control functions */
121 static errno_t
utun_ctl_bind(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
123 static errno_t
utun_ctl_connect(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
125 static errno_t
utun_ctl_disconnect(kern_ctl_ref kctlref
, u_int32_t unit
,
127 static errno_t
utun_ctl_send(kern_ctl_ref kctlref
, u_int32_t unit
,
128 void *unitinfo
, mbuf_t m
, int flags
);
129 static errno_t
utun_ctl_getopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
130 int opt
, void *data
, size_t *len
);
131 static errno_t
utun_ctl_setopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
132 int opt
, void *data
, size_t len
);
133 static void utun_ctl_rcvd(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
136 /* Network Interface functions */
137 static void utun_start(ifnet_t interface
);
138 static errno_t
utun_framer(ifnet_t interface
, mbuf_t
*packet
,
139 const struct sockaddr
*dest
, const char *desk_linkaddr
,
140 const char *frame_type
, u_int32_t
*prepend_len
, u_int32_t
*postpend_len
);
141 static errno_t
utun_output(ifnet_t interface
, mbuf_t data
);
142 static errno_t
utun_demux(ifnet_t interface
, mbuf_t data
, char *frame_header
,
143 protocol_family_t
*protocol
);
144 static errno_t
utun_add_proto(ifnet_t interface
, protocol_family_t protocol
,
145 const struct ifnet_demux_desc
*demux_array
,
146 u_int32_t demux_count
);
147 static errno_t
utun_del_proto(ifnet_t interface
, protocol_family_t protocol
);
148 static errno_t
utun_ioctl(ifnet_t interface
, u_long cmd
, void *data
);
149 static void utun_detached(ifnet_t interface
);
151 /* Protocol handlers */
152 static errno_t
utun_attach_proto(ifnet_t interface
, protocol_family_t proto
);
153 static errno_t
utun_proto_input(ifnet_t interface
, protocol_family_t protocol
,
154 mbuf_t m
, char *frame_header
);
155 static errno_t
utun_proto_pre_output(ifnet_t interface
, protocol_family_t protocol
,
156 mbuf_t
*packet
, const struct sockaddr
*dest
, void *route
,
157 char *frame_type
, char *link_layer_dest
);
158 static errno_t
utun_pkt_input(struct utun_pcb
*pcb
, mbuf_t m
);
162 #define UTUN_IF_DEFAULT_SLOT_SIZE 2048
163 #define UTUN_IF_DEFAULT_RING_SIZE 64
164 #define UTUN_IF_DEFAULT_TX_FSW_RING_SIZE 64
165 #define UTUN_IF_DEFAULT_RX_FSW_RING_SIZE 128
166 #define UTUN_IF_HEADROOM_SIZE 32
168 #define UTUN_IF_MIN_RING_SIZE 16
169 #define UTUN_IF_MAX_RING_SIZE 1024
171 #define UTUN_IF_MIN_SLOT_SIZE 1024
172 #define UTUN_IF_MAX_SLOT_SIZE 4096
174 static int sysctl_if_utun_ring_size SYSCTL_HANDLER_ARGS
;
175 static int sysctl_if_utun_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
176 static int sysctl_if_utun_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
178 static int if_utun_ring_size
= UTUN_IF_DEFAULT_RING_SIZE
;
179 static int if_utun_tx_fsw_ring_size
= UTUN_IF_DEFAULT_TX_FSW_RING_SIZE
;
180 static int if_utun_rx_fsw_ring_size
= UTUN_IF_DEFAULT_RX_FSW_RING_SIZE
;
182 SYSCTL_DECL(_net_utun
);
183 SYSCTL_NODE(_net
, OID_AUTO
, utun
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "UTun");
185 SYSCTL_PROC(_net_utun
, OID_AUTO
, ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
186 &if_utun_ring_size
, UTUN_IF_DEFAULT_RING_SIZE
, &sysctl_if_utun_ring_size
, "I", "");
187 SYSCTL_PROC(_net_utun
, OID_AUTO
, tx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
188 &if_utun_tx_fsw_ring_size
, UTUN_IF_DEFAULT_TX_FSW_RING_SIZE
, &sysctl_if_utun_tx_fsw_ring_size
, "I", "");
189 SYSCTL_PROC(_net_utun
, OID_AUTO
, rx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
190 &if_utun_rx_fsw_ring_size
, UTUN_IF_DEFAULT_RX_FSW_RING_SIZE
, &sysctl_if_utun_rx_fsw_ring_size
, "I", "");
193 utun_register_nexus(void);
196 utun_netif_prepare(__unused kern_nexus_t nexus
, ifnet_t ifp
);
198 utun_nexus_pre_connect(kern_nexus_provider_t nxprov
,
199 proc_t p
, kern_nexus_t nexus
,
200 nexus_port_t nexus_port
, kern_channel_t channel
, void **ch_ctx
);
202 utun_nexus_connected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
203 kern_channel_t channel
);
205 utun_netif_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
206 kern_channel_t channel
);
208 utun_nexus_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
209 kern_channel_t channel
);
211 utun_nexus_disconnected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
212 kern_channel_t channel
);
214 utun_kpipe_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
215 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
218 utun_kpipe_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
219 kern_channel_ring_t ring
);
221 utun_kpipe_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
222 kern_channel_ring_t ring
, uint32_t flags
);
224 utun_kpipe_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
225 kern_channel_ring_t ring
, uint32_t flags
);
228 #define UTUN_DEFAULT_MTU 1500
229 #define UTUN_HEADER_SIZE(_pcb) (sizeof(u_int32_t) + (((_pcb)->utun_flags & UTUN_FLAGS_ENABLE_PROC_UUID) ? sizeof(uuid_t) : 0))
231 static kern_ctl_ref utun_kctlref
;
232 static u_int32_t utun_family
;
233 static lck_attr_t
*utun_lck_attr
;
234 static lck_grp_attr_t
*utun_lck_grp_attr
;
235 static lck_grp_t
*utun_lck_grp
;
236 static lck_mtx_t utun_lock
;
238 TAILQ_HEAD(utun_list
, utun_pcb
) utun_head
;
240 #define UTUN_PCB_ZONE_MAX 32
241 #define UTUN_PCB_ZONE_NAME "net.if_utun"
243 static unsigned int utun_pcb_size
; /* size of zone element */
244 static struct zone
*utun_pcb_zone
; /* zone for utun_pcb */
249 sysctl_if_utun_ring_size SYSCTL_HANDLER_ARGS
251 #pragma unused(arg1, arg2)
252 int value
= if_utun_ring_size
;
254 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
255 if (error
|| !req
->newptr
) {
259 if (value
< UTUN_IF_MIN_RING_SIZE
||
260 value
> UTUN_IF_MAX_RING_SIZE
) {
264 if_utun_ring_size
= value
;
270 sysctl_if_utun_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
272 #pragma unused(arg1, arg2)
273 int value
= if_utun_tx_fsw_ring_size
;
275 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
276 if (error
|| !req
->newptr
) {
280 if (value
< UTUN_IF_MIN_RING_SIZE
||
281 value
> UTUN_IF_MAX_RING_SIZE
) {
285 if_utun_tx_fsw_ring_size
= value
;
291 sysctl_if_utun_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
293 #pragma unused(arg1, arg2)
294 int value
= if_utun_rx_fsw_ring_size
;
296 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
297 if (error
|| !req
->newptr
) {
301 if (value
< UTUN_IF_MIN_RING_SIZE
||
302 value
> UTUN_IF_MAX_RING_SIZE
) {
306 if_utun_rx_fsw_ring_size
= value
;
312 utun_netif_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
313 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
316 #pragma unused(nxprov)
317 #pragma unused(channel)
318 #pragma unused(ring_ctx)
319 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
321 VERIFY(pcb
->utun_netif_rxring
== NULL
);
322 pcb
->utun_netif_rxring
= ring
;
324 VERIFY(pcb
->utun_netif_txring
== NULL
);
325 pcb
->utun_netif_txring
= ring
;
331 utun_netif_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
332 kern_channel_ring_t ring
)
334 #pragma unused(nxprov)
335 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
336 if (pcb
->utun_netif_rxring
== ring
) {
337 pcb
->utun_netif_rxring
= NULL
;
338 } else if (pcb
->utun_netif_txring
== ring
) {
339 pcb
->utun_netif_txring
= NULL
;
344 utun_netif_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
345 kern_channel_ring_t tx_ring
, uint32_t flags
)
347 #pragma unused(nxprov)
348 #pragma unused(flags)
349 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
351 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
353 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
355 struct kern_channel_ring_stat_increment tx_ring_stats
;
356 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
357 kern_channel_slot_t tx_pslot
= NULL
;
358 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
360 STATS_INC(nifs
, NETIF_STATS_TXSYNC
);
362 if (tx_slot
== NULL
) {
363 // Nothing to write, don't bother signalling
364 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
368 if (pcb
->utun_kpipe_enabled
) {
369 kern_channel_ring_t rx_ring
= pcb
->utun_kpipe_rxring
;
370 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
372 // Signal the kernel pipe ring to read
373 if (rx_ring
!= NULL
) {
374 kern_channel_notify(rx_ring
, 0);
379 // If we're here, we're injecting into the utun kernel control socket
380 while (tx_slot
!= NULL
) {
384 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
389 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
392 (void) kern_channel_slot_detach_packet(tx_ring
, tx_slot
, tx_ph
);
396 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
398 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
399 VERIFY(tx_buf
!= NULL
);
401 /* tx_baddr is the absolute buffer address */
402 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
403 VERIFY(tx_baddr
!= 0);
405 bpf_tap_packet_out(pcb
->utun_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
407 uint16_t tx_offset
= kern_buflet_get_data_offset(tx_buf
);
408 uint32_t tx_length
= kern_buflet_get_data_length(tx_buf
);
410 // The offset must be large enough for the headers
411 VERIFY(tx_offset
>= UTUN_HEADER_SIZE(pcb
));
415 uint8_t vhl
= *(uint8_t *)(tx_baddr
+ tx_offset
);
416 u_int ip_version
= (vhl
>> 4);
417 switch (ip_version
) {
427 printf("utun_netif_sync_tx %s: unknown ip version %u vhl %u tx_offset %u len %u header_size %zu\n",
428 pcb
->utun_ifp
->if_xname
, ip_version
, vhl
, tx_offset
, tx_length
,
429 UTUN_HEADER_SIZE(pcb
));
434 tx_offset
-= UTUN_HEADER_SIZE(pcb
);
435 tx_length
+= UTUN_HEADER_SIZE(pcb
);
436 tx_baddr
+= tx_offset
;
438 length
= MIN(tx_length
, pcb
->utun_slot_size
);
441 memcpy(tx_baddr
, &af
, sizeof(af
));
442 if (pcb
->utun_flags
& UTUN_FLAGS_ENABLE_PROC_UUID
) {
443 kern_packet_get_euuid(tx_ph
, (void *)(tx_baddr
+ sizeof(af
)));
447 errno_t error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
449 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
451 error
= utun_output(pcb
->utun_ifp
, data
);
453 printf("utun_netif_sync_tx %s - utun_output error %d\n", pcb
->utun_ifp
->if_xname
, error
);
456 printf("utun_netif_sync_tx %s - mbuf_copyback(%zu) error %d\n", pcb
->utun_ifp
->if_xname
, length
, error
);
457 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
458 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
463 printf("utun_netif_sync_tx %s - mbuf_gethdr error %d\n", pcb
->utun_ifp
->if_xname
, error
);
464 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
465 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
468 printf("utun_netif_sync_tx %s - 0 length packet\n", pcb
->utun_ifp
->if_xname
);
469 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
470 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
473 kern_pbufpool_free(tx_ring
->ckr_pp
, tx_ph
);
479 STATS_INC(nifs
, NETIF_STATS_TXPKTS
);
480 STATS_INC(nifs
, NETIF_STATS_TXCOPY_MBUF
);
482 tx_ring_stats
.kcrsi_slots_transferred
++;
483 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
487 kern_channel_advance_slot(tx_ring
, tx_pslot
);
488 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
489 (void)kern_channel_reclaim(tx_ring
);
492 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
498 utun_netif_tx_doorbell(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
499 kern_channel_ring_t ring
, __unused
uint32_t flags
)
501 #pragma unused(nxprov)
502 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
503 boolean_t more
= false;
507 * Refill and sync the ring; we may be racing against another thread doing
508 * an RX sync that also wants to do kr_enter(), and so use the blocking
511 rc
= kern_channel_tx_refill_canblock(ring
, UINT32_MAX
, UINT32_MAX
, true, &more
);
512 if (rc
!= 0 && rc
!= EAGAIN
&& rc
!= EBUSY
) {
513 printf("%s, tx refill failed %d\n", __func__
, rc
);
516 (void) kr_enter(ring
, TRUE
);
517 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
519 if (pcb
->utun_kpipe_enabled
) {
520 uint32_t tx_available
= kern_channel_available_slot_count(ring
);
521 if (pcb
->utun_netif_txring_size
> 0 &&
522 tx_available
>= pcb
->utun_netif_txring_size
- 1) {
523 // No room left in tx ring, disable output for now
524 errno_t error
= ifnet_disable_output(pcb
->utun_ifp
);
526 printf("utun_netif_tx_doorbell: ifnet_disable_output returned error %d\n", error
);
531 if (pcb
->utun_kpipe_enabled
) {
532 kern_channel_ring_t rx_ring
= pcb
->utun_kpipe_rxring
;
534 // Unlock while calling notify
535 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
536 // Signal the kernel pipe ring to read
537 if (rx_ring
!= NULL
) {
538 kern_channel_notify(rx_ring
, 0);
541 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
550 utun_netif_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
551 kern_channel_ring_t rx_ring
, uint32_t flags
)
553 #pragma unused(nxprov)
554 #pragma unused(flags)
555 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
556 struct kern_channel_ring_stat_increment rx_ring_stats
;
558 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
560 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
562 // Reclaim user-released slots
563 (void) kern_channel_reclaim(rx_ring
);
565 STATS_INC(nifs
, NETIF_STATS_RXSYNC
);
567 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
569 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
573 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
574 VERIFY(rx_pp
!= NULL
);
575 bzero(&rx_ring_stats
, sizeof(rx_ring_stats
));
576 kern_channel_slot_t rx_pslot
= NULL
;
577 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
579 while (rx_slot
!= NULL
) {
580 // Check for a waiting packet
581 lck_mtx_lock(&pcb
->utun_input_chain_lock
);
582 mbuf_t data
= pcb
->utun_input_chain
;
584 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
588 // Allocate rx packet
589 kern_packet_t rx_ph
= 0;
590 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
591 if (unlikely(error
!= 0)) {
592 STATS_INC(nifs
, NETIF_STATS_NOMEM_PKT
);
593 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
594 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
598 // Advance waiting packets
599 pcb
->utun_input_chain
= data
->m_nextpkt
;
600 data
->m_nextpkt
= NULL
;
601 if (pcb
->utun_input_chain
== NULL
) {
602 pcb
->utun_input_chain_last
= NULL
;
604 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
606 size_t header_offset
= UTUN_HEADER_SIZE(pcb
);
607 size_t length
= mbuf_pkthdr_len(data
);
609 if (length
< header_offset
) {
612 kern_pbufpool_free(rx_pp
, rx_ph
);
613 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
614 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
615 printf("utun_netif_sync_rx %s: legacy packet length too short for header %zu < %zu\n",
616 pcb
->utun_ifp
->if_xname
, length
, header_offset
);
620 length
-= header_offset
;
621 if (length
> rx_pp
->pp_buflet_size
) {
624 kern_pbufpool_free(rx_pp
, rx_ph
);
625 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
626 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
627 printf("utun_netif_sync_rx %s: legacy packet length %zu > %u\n",
628 pcb
->utun_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
632 mbuf_pkthdr_setrcvif(data
, pcb
->utun_ifp
);
635 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
636 VERIFY(rx_buf
!= NULL
);
637 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
638 VERIFY(rx_baddr
!= NULL
);
640 // Copy-in data from mbuf to buflet
641 mbuf_copydata(data
, header_offset
, length
, (void *)rx_baddr
);
642 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
644 // Finalize and attach the packet
645 error
= kern_buflet_set_data_offset(rx_buf
, 0);
647 error
= kern_buflet_set_data_length(rx_buf
, length
);
649 error
= kern_packet_set_link_header_offset(rx_ph
, 0);
651 error
= kern_packet_set_network_header_offset(rx_ph
, 0);
653 error
= kern_packet_finalize(rx_ph
);
655 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
658 STATS_INC(nifs
, NETIF_STATS_RXPKTS
);
659 STATS_INC(nifs
, NETIF_STATS_RXCOPY_MBUF
);
660 bpf_tap_packet_in(pcb
->utun_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
662 rx_ring_stats
.kcrsi_slots_transferred
++;
663 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
669 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
672 struct kern_channel_ring_stat_increment tx_ring_stats
;
673 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
674 kern_channel_ring_t tx_ring
= pcb
->utun_kpipe_txring
;
675 kern_channel_slot_t tx_pslot
= NULL
;
676 kern_channel_slot_t tx_slot
= NULL
;
677 if (tx_ring
== NULL
) {
678 // Net-If TX ring not set up yet, nothing to read
682 // Unlock utun before entering ring
683 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
685 (void)kr_enter(tx_ring
, TRUE
);
687 // Lock again after entering and validate
688 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
689 if (tx_ring
!= pcb
->utun_kpipe_txring
) {
693 tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
694 if (tx_slot
== NULL
) {
695 // Nothing to read, don't bother signalling
699 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
700 // Allocate rx packet
701 kern_packet_t rx_ph
= 0;
702 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
706 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
708 /* Skip slot if packet is zero-length or marked as dropped (QUMF_DROPPED) */
713 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
714 if (unlikely(error
!= 0)) {
715 STATS_INC(nifs
, NETIF_STATS_NOMEM_PKT
);
716 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
720 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
721 VERIFY(tx_buf
!= NULL
);
722 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
723 VERIFY(tx_baddr
!= 0);
724 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
726 // Check packet length
727 size_t header_offset
= UTUN_HEADER_SIZE(pcb
);
728 uint32_t tx_length
= kern_packet_get_data_length(tx_ph
);
729 if (tx_length
< header_offset
) {
730 // Packet is too small
731 kern_pbufpool_free(rx_pp
, rx_ph
);
732 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
733 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
734 printf("utun_netif_sync_rx %s: packet length too short for header %u < %zu\n",
735 pcb
->utun_ifp
->if_xname
, tx_length
, header_offset
);
739 size_t length
= MIN(tx_length
- header_offset
,
740 pcb
->utun_slot_size
);
742 tx_ring_stats
.kcrsi_slots_transferred
++;
743 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
746 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
747 VERIFY(rx_buf
!= NULL
);
748 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
749 VERIFY(rx_baddr
!= NULL
);
751 // Copy-in data from tx to rx
752 memcpy((void *)rx_baddr
, (void *)(tx_baddr
+ header_offset
), length
);
753 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
755 // Finalize and attach the packet
756 error
= kern_buflet_set_data_offset(rx_buf
, 0);
758 error
= kern_buflet_set_data_length(rx_buf
, length
);
760 error
= kern_packet_set_link_header_offset(rx_ph
, 0);
762 error
= kern_packet_set_network_header_offset(rx_ph
, 0);
764 error
= kern_packet_finalize(rx_ph
);
766 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
769 STATS_INC(nifs
, NETIF_STATS_RXPKTS
);
770 STATS_INC(nifs
, NETIF_STATS_RXCOPY_DIRECT
);
771 bpf_tap_packet_in(pcb
->utun_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
773 rx_ring_stats
.kcrsi_slots_transferred
++;
774 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
777 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
782 kern_channel_advance_slot(rx_ring
, rx_pslot
);
783 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->utun_ifp
, &rx_ring_stats
);
787 kern_channel_advance_slot(tx_ring
, tx_pslot
);
788 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
789 (void)kern_channel_reclaim(tx_ring
);
792 // Unlock first, then exit ring
793 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
794 if (tx_ring
!= NULL
) {
795 if (tx_pslot
!= NULL
) {
796 kern_channel_notify(tx_ring
, 0);
805 utun_nexus_ifattach(struct utun_pcb
*pcb
,
806 struct ifnet_init_eparams
*init_params
,
810 nexus_controller_t controller
= kern_nexus_shared_controller();
811 struct kern_nexus_net_init net_init
;
813 nexus_name_t provider_name
;
814 snprintf((char *)provider_name
, sizeof(provider_name
),
815 "com.apple.netif.utun%d", pcb
->utun_unit
);
817 struct kern_nexus_provider_init prov_init
= {
818 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
819 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
820 .nxpi_pre_connect
= utun_nexus_pre_connect
,
821 .nxpi_connected
= utun_nexus_connected
,
822 .nxpi_pre_disconnect
= utun_netif_pre_disconnect
,
823 .nxpi_disconnected
= utun_nexus_disconnected
,
824 .nxpi_ring_init
= utun_netif_ring_init
,
825 .nxpi_ring_fini
= utun_netif_ring_fini
,
826 .nxpi_slot_init
= NULL
,
827 .nxpi_slot_fini
= NULL
,
828 .nxpi_sync_tx
= utun_netif_sync_tx
,
829 .nxpi_sync_rx
= utun_netif_sync_rx
,
830 .nxpi_tx_doorbell
= utun_netif_tx_doorbell
,
833 nexus_attr_t nxa
= NULL
;
834 err
= kern_nexus_attr_create(&nxa
);
836 printf("%s: kern_nexus_attr_create failed: %d\n",
841 uint64_t slot_buffer_size
= pcb
->utun_slot_size
;
842 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
845 // Reset ring size for netif nexus to limit memory usage
846 uint64_t ring_size
= pcb
->utun_netif_ring_size
;
847 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
849 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
852 pcb
->utun_netif_txring_size
= ring_size
;
854 err
= kern_nexus_controller_register_provider(controller
,
860 &pcb
->utun_nx
.if_provider
);
862 printf("%s register provider failed, error %d\n",
867 bzero(&net_init
, sizeof(net_init
));
868 net_init
.nxneti_version
= KERN_NEXUS_NET_CURRENT_VERSION
;
869 net_init
.nxneti_flags
= 0;
870 net_init
.nxneti_eparams
= init_params
;
871 net_init
.nxneti_lladdr
= NULL
;
872 net_init
.nxneti_prepare
= utun_netif_prepare
;
873 err
= kern_nexus_controller_alloc_net_provider_instance(controller
,
874 pcb
->utun_nx
.if_provider
,
876 &pcb
->utun_nx
.if_instance
,
880 printf("%s alloc_net_provider_instance failed, %d\n",
882 kern_nexus_controller_deregister_provider(controller
,
883 pcb
->utun_nx
.if_provider
);
884 uuid_clear(pcb
->utun_nx
.if_provider
);
890 kern_nexus_attr_destroy(nxa
);
896 utun_detach_provider_and_instance(uuid_t provider
, uuid_t instance
)
898 nexus_controller_t controller
= kern_nexus_shared_controller();
901 if (!uuid_is_null(instance
)) {
902 err
= kern_nexus_controller_free_provider_instance(controller
,
905 printf("%s free_provider_instance failed %d\n",
908 uuid_clear(instance
);
910 if (!uuid_is_null(provider
)) {
911 err
= kern_nexus_controller_deregister_provider(controller
,
914 printf("%s deregister_provider %d\n", __func__
, err
);
916 uuid_clear(provider
);
922 utun_nexus_detach(utun_nx_t nx
)
924 nexus_controller_t controller
= kern_nexus_shared_controller();
927 if (!uuid_is_null(nx
->ms_host
)) {
928 err
= kern_nexus_ifdetach(controller
,
932 printf("%s: kern_nexus_ifdetach ms host failed %d\n",
937 if (!uuid_is_null(nx
->ms_device
)) {
938 err
= kern_nexus_ifdetach(controller
,
942 printf("%s: kern_nexus_ifdetach ms device failed %d\n",
947 utun_detach_provider_and_instance(nx
->if_provider
,
949 utun_detach_provider_and_instance(nx
->ms_provider
,
952 memset(nx
, 0, sizeof(*nx
));
956 utun_create_fs_provider_and_instance(struct utun_pcb
*pcb
,
957 uint32_t subtype
, const char *type_name
,
959 uuid_t
*provider
, uuid_t
*instance
)
961 nexus_attr_t attr
= NULL
;
962 nexus_controller_t controller
= kern_nexus_shared_controller();
965 struct kern_nexus_init init
;
966 nexus_name_t provider_name
;
968 err
= kern_nexus_get_builtin_domain_provider(NEXUS_TYPE_FLOW_SWITCH
,
971 printf("%s can't get %s provider, error %d\n",
972 __func__
, type_name
, err
);
976 err
= kern_nexus_attr_create(&attr
);
978 printf("%s: kern_nexus_attr_create failed: %d\n",
983 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_EXTENSIONS
, subtype
);
986 uint64_t slot_buffer_size
= pcb
->utun_slot_size
;
987 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
990 // Reset ring size for flowswitch nexus to limit memory usage. Larger RX than netif.
991 uint64_t tx_ring_size
= pcb
->utun_tx_fsw_ring_size
;
992 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_TX_SLOTS
, tx_ring_size
);
994 uint64_t rx_ring_size
= pcb
->utun_rx_fsw_ring_size
;
995 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_RX_SLOTS
, rx_ring_size
);
998 snprintf((char *)provider_name
, sizeof(provider_name
),
999 "com.apple.%s.%s", type_name
, ifname
);
1000 err
= kern_nexus_controller_register_provider(controller
,
1007 kern_nexus_attr_destroy(attr
);
1010 printf("%s register %s provider failed, error %d\n",
1011 __func__
, type_name
, err
);
1014 bzero(&init
, sizeof (init
));
1015 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
1016 err
= kern_nexus_controller_alloc_provider_instance(controller
,
1021 printf("%s alloc_provider_instance %s failed, %d\n",
1022 __func__
, type_name
, err
);
1023 kern_nexus_controller_deregister_provider(controller
,
1025 uuid_clear(*provider
);
1032 utun_multistack_attach(struct utun_pcb
*pcb
)
1034 nexus_controller_t controller
= kern_nexus_shared_controller();
1036 utun_nx_t nx
= &pcb
->utun_nx
;
1038 // Allocate multistack flowswitch
1039 err
= utun_create_fs_provider_and_instance(pcb
,
1040 NEXUS_EXTENSION_FSW_TYPE_MULTISTACK
,
1042 pcb
->utun_ifp
->if_xname
,
1046 printf("%s: failed to create bridge provider and instance\n",
1051 // Attach multistack to device port
1052 err
= kern_nexus_ifattach(controller
, nx
->ms_instance
,
1053 NULL
, nx
->if_instance
,
1054 FALSE
, &nx
->ms_device
);
1056 printf("%s kern_nexus_ifattach ms device %d\n", __func__
, err
);
1060 // Attach multistack to host port
1061 err
= kern_nexus_ifattach(controller
, nx
->ms_instance
,
1062 NULL
, nx
->if_instance
,
1063 TRUE
, &nx
->ms_host
);
1065 printf("%s kern_nexus_ifattach ms host %d\n", __func__
, err
);
1069 // Extract the agent UUID and save for later
1070 struct kern_nexus
*multistack_nx
= nx_find(nx
->ms_instance
, false);
1071 if (multistack_nx
!= NULL
) {
1072 struct nx_flowswitch
*flowswitch
= NX_FSW_PRIVATE(multistack_nx
);
1073 if (flowswitch
!= NULL
) {
1074 FSW_RLOCK(flowswitch
);
1075 struct fsw_ms_context
*ms_context
= (struct fsw_ms_context
*)flowswitch
->fsw_ops_private
;
1076 if (ms_context
!= NULL
) {
1077 uuid_copy(nx
->ms_agent
, ms_context
->mc_agent_uuid
);
1079 printf("utun_multistack_attach - fsw_ms_context is NULL\n");
1081 FSW_UNLOCK(flowswitch
);
1083 printf("utun_multistack_attach - flowswitch is NULL\n");
1085 nx_release(multistack_nx
);
1087 printf("utun_multistack_attach - unable to find multistack nexus\n");
1093 utun_nexus_detach(nx
);
1095 errno_t detach_error
= 0;
1096 if ((detach_error
= ifnet_detach(pcb
->utun_ifp
)) != 0) {
1097 panic("utun_multistack_attach - ifnet_detach failed: %d\n", detach_error
);
1105 utun_register_kernel_pipe_nexus(void)
1107 nexus_attr_t nxa
= NULL
;
1110 lck_mtx_lock(&utun_lock
);
1111 if (utun_ncd_refcount
++) {
1112 lck_mtx_unlock(&utun_lock
);
1116 result
= kern_nexus_controller_create(&utun_ncd
);
1118 printf("%s: kern_nexus_controller_create failed: %d\n",
1119 __FUNCTION__
, result
);
1124 result
= kern_nexus_get_builtin_domain_provider(
1125 NEXUS_TYPE_KERNEL_PIPE
, &dom_prov
);
1127 printf("%s: kern_nexus_get_builtin_domain_provider failed: %d\n",
1128 __FUNCTION__
, result
);
1132 struct kern_nexus_provider_init prov_init
= {
1133 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
1134 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
1135 .nxpi_pre_connect
= utun_nexus_pre_connect
,
1136 .nxpi_connected
= utun_nexus_connected
,
1137 .nxpi_pre_disconnect
= utun_nexus_pre_disconnect
,
1138 .nxpi_disconnected
= utun_nexus_disconnected
,
1139 .nxpi_ring_init
= utun_kpipe_ring_init
,
1140 .nxpi_ring_fini
= utun_kpipe_ring_fini
,
1141 .nxpi_slot_init
= NULL
,
1142 .nxpi_slot_fini
= NULL
,
1143 .nxpi_sync_tx
= utun_kpipe_sync_tx
,
1144 .nxpi_sync_rx
= utun_kpipe_sync_rx
,
1145 .nxpi_tx_doorbell
= NULL
,
1148 result
= kern_nexus_attr_create(&nxa
);
1150 printf("%s: kern_nexus_attr_create failed: %d\n",
1151 __FUNCTION__
, result
);
1155 uint64_t slot_buffer_size
= UTUN_IF_DEFAULT_SLOT_SIZE
;
1156 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1157 VERIFY(result
== 0);
1159 // Reset ring size for kernel pipe nexus to limit memory usage
1160 uint64_t ring_size
= if_utun_ring_size
;
1161 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
1162 VERIFY(result
== 0);
1163 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
1164 VERIFY(result
== 0);
1166 result
= kern_nexus_controller_register_provider(utun_ncd
,
1168 (const uint8_t *)"com.apple.nexus.utun.kpipe",
1174 printf("%s: kern_nexus_controller_register_provider failed: %d\n",
1175 __FUNCTION__
, result
);
1181 kern_nexus_attr_destroy(nxa
);
1186 kern_nexus_controller_destroy(utun_ncd
);
1189 utun_ncd_refcount
= 0;
1192 lck_mtx_unlock(&utun_lock
);
1198 utun_unregister_kernel_pipe_nexus(void)
1200 lck_mtx_lock(&utun_lock
);
1202 VERIFY(utun_ncd_refcount
> 0);
1204 if (--utun_ncd_refcount
== 0) {
1205 kern_nexus_controller_destroy(utun_ncd
);
1209 lck_mtx_unlock(&utun_lock
);
1212 // For use by socket option, not internally
1214 utun_disable_channel(struct utun_pcb
*pcb
)
1220 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
1222 enabled
= pcb
->utun_kpipe_enabled
;
1223 uuid_copy(uuid
, pcb
->utun_kpipe_uuid
);
1225 VERIFY(uuid_is_null(pcb
->utun_kpipe_uuid
) == !enabled
);
1227 pcb
->utun_kpipe_enabled
= 0;
1228 uuid_clear(pcb
->utun_kpipe_uuid
);
1230 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1233 result
= kern_nexus_controller_free_provider_instance(utun_ncd
, uuid
);
1239 utun_unregister_kernel_pipe_nexus();
1246 utun_enable_channel(struct utun_pcb
*pcb
, struct proc
*proc
)
1248 struct kern_nexus_init init
;
1251 result
= utun_register_kernel_pipe_nexus();
1258 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
1260 if (pcb
->utun_kpipe_enabled
) {
1261 result
= EEXIST
; // return success instead?
1266 * Make sure we can fit packets in the channel buffers and
1267 * Allow an extra 4 bytes for the protocol number header in the channel
1269 if (pcb
->utun_ifp
->if_mtu
+ UTUN_HEADER_SIZE(pcb
) > pcb
->utun_slot_size
) {
1270 result
= EOPNOTSUPP
;
1274 VERIFY(uuid_is_null(pcb
->utun_kpipe_uuid
));
1275 bzero(&init
, sizeof (init
));
1276 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
1277 result
= kern_nexus_controller_alloc_provider_instance(utun_ncd
,
1278 utun_kpipe_uuid
, pcb
, &pcb
->utun_kpipe_uuid
, &init
);
1283 nexus_port_t port
= NEXUS_PORT_KERNEL_PIPE_CLIENT
;
1284 result
= kern_nexus_controller_bind_provider_instance(utun_ncd
,
1285 pcb
->utun_kpipe_uuid
, &port
,
1286 proc_pid(proc
), NULL
, NULL
, 0, NEXUS_BIND_PID
);
1288 kern_nexus_controller_free_provider_instance(utun_ncd
,
1289 pcb
->utun_kpipe_uuid
);
1290 uuid_clear(pcb
->utun_kpipe_uuid
);
1294 pcb
->utun_kpipe_enabled
= 1;
1297 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1300 utun_unregister_kernel_pipe_nexus();
1306 #endif // UTUN_NEXUS
1309 utun_register_control(void)
1311 struct kern_ctl_reg kern_ctl
;
1314 /* Find a unique value for our interface family */
1315 result
= mbuf_tag_id_find(UTUN_CONTROL_NAME
, &utun_family
);
1317 printf("utun_register_control - mbuf_tag_id_find_internal failed: %d\n", result
);
1321 utun_pcb_size
= sizeof(struct utun_pcb
);
1322 utun_pcb_zone
= zinit(utun_pcb_size
,
1323 UTUN_PCB_ZONE_MAX
* utun_pcb_size
,
1324 0, UTUN_PCB_ZONE_NAME
);
1325 if (utun_pcb_zone
== NULL
) {
1326 printf("utun_register_control - zinit(utun_pcb) failed");
1331 utun_register_nexus();
1332 #endif // UTUN_NEXUS
1334 TAILQ_INIT(&utun_head
);
1336 bzero(&kern_ctl
, sizeof(kern_ctl
));
1337 strlcpy(kern_ctl
.ctl_name
, UTUN_CONTROL_NAME
, sizeof(kern_ctl
.ctl_name
));
1338 kern_ctl
.ctl_name
[sizeof(kern_ctl
.ctl_name
) - 1] = 0;
1339 kern_ctl
.ctl_flags
= CTL_FLAG_PRIVILEGED
| CTL_FLAG_REG_EXTENDED
; /* Require root */
1340 kern_ctl
.ctl_sendsize
= 512 * 1024;
1341 kern_ctl
.ctl_recvsize
= 512 * 1024;
1342 kern_ctl
.ctl_bind
= utun_ctl_bind
;
1343 kern_ctl
.ctl_connect
= utun_ctl_connect
;
1344 kern_ctl
.ctl_disconnect
= utun_ctl_disconnect
;
1345 kern_ctl
.ctl_send
= utun_ctl_send
;
1346 kern_ctl
.ctl_setopt
= utun_ctl_setopt
;
1347 kern_ctl
.ctl_getopt
= utun_ctl_getopt
;
1348 kern_ctl
.ctl_rcvd
= utun_ctl_rcvd
;
1350 result
= ctl_register(&kern_ctl
, &utun_kctlref
);
1352 printf("utun_register_control - ctl_register failed: %d\n", result
);
1356 /* Register the protocol plumbers */
1357 if ((result
= proto_register_plumber(PF_INET
, utun_family
,
1358 utun_attach_proto
, NULL
)) != 0) {
1359 printf("utun_register_control - proto_register_plumber(PF_INET, %d) failed: %d\n",
1360 utun_family
, result
);
1361 ctl_deregister(utun_kctlref
);
1365 /* Register the protocol plumbers */
1366 if ((result
= proto_register_plumber(PF_INET6
, utun_family
,
1367 utun_attach_proto
, NULL
)) != 0) {
1368 proto_unregister_plumber(PF_INET
, utun_family
);
1369 ctl_deregister(utun_kctlref
);
1370 printf("utun_register_control - proto_register_plumber(PF_INET6, %d) failed: %d\n",
1371 utun_family
, result
);
1375 utun_lck_attr
= lck_attr_alloc_init();
1376 utun_lck_grp_attr
= lck_grp_attr_alloc_init();
1377 utun_lck_grp
= lck_grp_alloc_init("utun", utun_lck_grp_attr
);
1379 lck_mtx_init(&utun_lock
, utun_lck_grp
, utun_lck_attr
);
1384 /* Kernel control functions */
1387 utun_free_pcb(struct utun_pcb
*pcb
, bool in_list
)
1390 mbuf_freem_list(pcb
->utun_input_chain
);
1391 lck_mtx_destroy(&pcb
->utun_input_chain_lock
, utun_lck_grp
);
1392 #endif // UTUN_NEXUS
1393 lck_rw_destroy(&pcb
->utun_pcb_lock
, utun_lck_grp
);
1395 lck_mtx_lock(&utun_lock
);
1396 TAILQ_REMOVE(&utun_head
, pcb
, utun_chain
);
1397 lck_mtx_unlock(&utun_lock
);
1399 zfree(utun_pcb_zone
, pcb
);
1403 utun_ctl_bind(kern_ctl_ref kctlref
,
1404 struct sockaddr_ctl
*sac
,
1407 struct utun_pcb
*pcb
= zalloc(utun_pcb_zone
);
1408 memset(pcb
, 0, sizeof(*pcb
));
1411 pcb
->utun_ctlref
= kctlref
;
1412 pcb
->utun_unit
= sac
->sc_unit
;
1413 pcb
->utun_max_pending_packets
= 1;
1416 pcb
->utun_use_netif
= false;
1417 pcb
->utun_slot_size
= UTUN_IF_DEFAULT_SLOT_SIZE
;
1418 pcb
->utun_netif_ring_size
= UTUN_IF_DEFAULT_RING_SIZE
;
1419 pcb
->utun_tx_fsw_ring_size
= UTUN_IF_DEFAULT_TX_FSW_RING_SIZE
;
1420 pcb
->utun_rx_fsw_ring_size
= UTUN_IF_DEFAULT_RX_FSW_RING_SIZE
;
1421 #endif // UTUN_NEXUS
1423 lck_mtx_init(&pcb
->utun_input_chain_lock
, utun_lck_grp
, utun_lck_attr
);
1424 lck_rw_init(&pcb
->utun_pcb_lock
, utun_lck_grp
, utun_lck_attr
);
1430 utun_ctl_connect(kern_ctl_ref kctlref
,
1431 struct sockaddr_ctl
*sac
,
1434 struct ifnet_init_eparams utun_init
= {};
1437 if (*unitinfo
== NULL
) {
1438 (void)utun_ctl_bind(kctlref
, sac
, unitinfo
);
1441 struct utun_pcb
*pcb
= *unitinfo
;
1443 lck_mtx_lock(&utun_lock
);
1445 /* Find some open interface id */
1446 u_int32_t chosen_unique_id
= 1;
1447 struct utun_pcb
*next_pcb
= TAILQ_LAST(&utun_head
, utun_list
);
1448 if (next_pcb
!= NULL
) {
1449 /* List was not empty, add one to the last item */
1450 chosen_unique_id
= next_pcb
->utun_unique_id
+ 1;
1454 * If this wrapped the id number, start looking at
1455 * the front of the list for an unused id.
1457 if (chosen_unique_id
== 0) {
1458 /* Find the next unused ID */
1459 chosen_unique_id
= 1;
1460 TAILQ_FOREACH(next_pcb
, &utun_head
, utun_chain
) {
1461 if (next_pcb
->utun_unique_id
> chosen_unique_id
) {
1462 /* We found a gap */
1466 chosen_unique_id
= next_pcb
->utun_unique_id
+ 1;
1471 pcb
->utun_unique_id
= chosen_unique_id
;
1473 if (next_pcb
!= NULL
) {
1474 TAILQ_INSERT_BEFORE(next_pcb
, pcb
, utun_chain
);
1476 TAILQ_INSERT_TAIL(&utun_head
, pcb
, utun_chain
);
1478 lck_mtx_unlock(&utun_lock
);
1480 snprintf(pcb
->utun_if_xname
, sizeof(pcb
->utun_if_xname
), "utun%d", pcb
->utun_unit
- 1);
1481 snprintf(pcb
->utun_unique_name
, sizeof(pcb
->utun_unique_name
), "utunid%d", pcb
->utun_unique_id
- 1);
1482 printf("utun_ctl_connect: creating interface %s (id %s)\n", pcb
->utun_if_xname
, pcb
->utun_unique_name
);
1484 /* Create the interface */
1485 bzero(&utun_init
, sizeof(utun_init
));
1486 utun_init
.ver
= IFNET_INIT_CURRENT_VERSION
;
1487 utun_init
.len
= sizeof (utun_init
);
1490 if (pcb
->utun_use_netif
) {
1491 utun_init
.flags
= (IFNET_INIT_SKYWALK_NATIVE
| IFNET_INIT_NX_NOAUTO
);
1492 utun_init
.tx_headroom
= UTUN_IF_HEADROOM_SIZE
;
1494 #endif // UTUN_NEXUS
1496 utun_init
.flags
= IFNET_INIT_NX_NOAUTO
;
1497 utun_init
.start
= utun_start
;
1498 utun_init
.framer_extended
= utun_framer
;
1500 utun_init
.name
= "utun";
1501 utun_init
.unit
= pcb
->utun_unit
- 1;
1502 utun_init
.uniqueid
= pcb
->utun_unique_name
;
1503 utun_init
.uniqueid_len
= strlen(pcb
->utun_unique_name
);
1504 utun_init
.family
= utun_family
;
1505 utun_init
.subfamily
= IFNET_SUBFAMILY_UTUN
;
1506 utun_init
.type
= IFT_OTHER
;
1507 utun_init
.demux
= utun_demux
;
1508 utun_init
.add_proto
= utun_add_proto
;
1509 utun_init
.del_proto
= utun_del_proto
;
1510 utun_init
.softc
= pcb
;
1511 utun_init
.ioctl
= utun_ioctl
;
1512 utun_init
.detach
= utun_detached
;
1515 if (pcb
->utun_use_netif
) {
1516 result
= utun_nexus_ifattach(pcb
, &utun_init
, &pcb
->utun_ifp
);
1518 printf("utun_ctl_connect - utun_nexus_ifattach failed: %d\n", result
);
1519 utun_free_pcb(pcb
, true);
1524 result
= utun_multistack_attach(pcb
);
1526 printf("utun_ctl_connect - utun_multistack_attach failed: %d\n", result
);
1532 bpfattach(pcb
->utun_ifp
, DLT_RAW
, 0);
1534 #endif // UTUN_NEXUS
1537 * Upon success, this holds an ifnet reference which we will
1538 * release via ifnet_release() at final detach time.
1540 result
= ifnet_allocate_extended(&utun_init
, &pcb
->utun_ifp
);
1542 printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result
);
1543 utun_free_pcb(pcb
, true);
1548 /* Set flags and additional information. */
1549 ifnet_set_mtu(pcb
->utun_ifp
, UTUN_DEFAULT_MTU
);
1550 ifnet_set_flags(pcb
->utun_ifp
, IFF_UP
| IFF_MULTICAST
| IFF_POINTOPOINT
, 0xffff);
1552 /* The interface must generate its own IPv6 LinkLocal address,
1553 * if possible following the recommendation of RFC2472 to the 64bit interface ID
1555 ifnet_set_eflags(pcb
->utun_ifp
, IFEF_NOAUTOIPV6LL
, IFEF_NOAUTOIPV6LL
);
1557 /* Reset the stats in case as the interface may have been recycled */
1558 struct ifnet_stats_param stats
;
1559 bzero(&stats
, sizeof(struct ifnet_stats_param
));
1560 ifnet_set_stat(pcb
->utun_ifp
, &stats
);
1562 /* Attach the interface */
1563 result
= ifnet_attach(pcb
->utun_ifp
, NULL
);
1565 printf("utun_ctl_connect - ifnet_attach failed: %d\n", result
);
1566 /* Release reference now since attach failed */
1567 ifnet_release(pcb
->utun_ifp
);
1568 utun_free_pcb(pcb
, true);
1574 bpfattach(pcb
->utun_ifp
, DLT_NULL
, UTUN_HEADER_SIZE(pcb
));
1577 /* The interfaces resoures allocated, mark it as running */
1578 ifnet_set_flags(pcb
->utun_ifp
, IFF_RUNNING
, IFF_RUNNING
);
1584 utun_detach_ip(ifnet_t interface
,
1585 protocol_family_t protocol
,
1588 errno_t result
= EPROTONOSUPPORT
;
1590 /* Attempt a detach */
1591 if (protocol
== PF_INET
) {
1594 bzero(&ifr
, sizeof(ifr
));
1595 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
1596 ifnet_name(interface
), ifnet_unit(interface
));
1598 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH
, &ifr
);
1599 } else if (protocol
== PF_INET6
) {
1600 struct in6_ifreq ifr6
;
1602 bzero(&ifr6
, sizeof(ifr6
));
1603 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
1604 ifnet_name(interface
), ifnet_unit(interface
));
1606 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH_IN6
, &ifr6
);
1613 utun_remove_address(ifnet_t interface
,
1614 protocol_family_t protocol
,
1620 /* Attempt a detach */
1621 if (protocol
== PF_INET
) {
1624 bzero(&ifr
, sizeof(ifr
));
1625 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
1626 ifnet_name(interface
), ifnet_unit(interface
));
1627 result
= ifaddr_address(address
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
1629 printf("utun_remove_address - ifaddr_address failed: %d", result
);
1631 result
= sock_ioctl(pf_socket
, SIOCDIFADDR
, &ifr
);
1633 printf("utun_remove_address - SIOCDIFADDR failed: %d", result
);
1636 } else if (protocol
== PF_INET6
) {
1637 struct in6_ifreq ifr6
;
1639 bzero(&ifr6
, sizeof(ifr6
));
1640 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
1641 ifnet_name(interface
), ifnet_unit(interface
));
1642 result
= ifaddr_address(address
, (struct sockaddr
*)&ifr6
.ifr_addr
,
1643 sizeof(ifr6
.ifr_addr
));
1645 printf("utun_remove_address - ifaddr_address failed (v6): %d",
1648 result
= sock_ioctl(pf_socket
, SIOCDIFADDR_IN6
, &ifr6
);
1650 printf("utun_remove_address - SIOCDIFADDR_IN6 failed: %d",
1658 utun_cleanup_family(ifnet_t interface
,
1659 protocol_family_t protocol
)
1662 socket_t pf_socket
= NULL
;
1663 ifaddr_t
*addresses
= NULL
;
1666 if (protocol
!= PF_INET
&& protocol
!= PF_INET6
) {
1667 printf("utun_cleanup_family - invalid protocol family %d\n", protocol
);
1671 /* Create a socket for removing addresses and detaching the protocol */
1672 result
= sock_socket(protocol
, SOCK_DGRAM
, 0, NULL
, NULL
, &pf_socket
);
1674 if (result
!= EAFNOSUPPORT
)
1675 printf("utun_cleanup_family - failed to create %s socket: %d\n",
1676 protocol
== PF_INET
? "IP" : "IPv6", result
);
1680 /* always set SS_PRIV, we want to close and detach regardless */
1681 sock_setpriv(pf_socket
, 1);
1683 result
= utun_detach_ip(interface
, protocol
, pf_socket
);
1684 if (result
== 0 || result
== ENXIO
) {
1685 /* We are done! We either detached or weren't attached. */
1687 } else if (result
!= EBUSY
) {
1688 /* Uh, not really sure what happened here... */
1689 printf("utun_cleanup_family - utun_detach_ip failed: %d\n", result
);
1694 * At this point, we received an EBUSY error. This means there are
1695 * addresses attached. We should detach them and then try again.
1697 result
= ifnet_get_address_list_family(interface
, &addresses
, protocol
);
1699 printf("fnet_get_address_list_family(%s%d, 0xblah, %s) - failed: %d\n",
1700 ifnet_name(interface
), ifnet_unit(interface
),
1701 protocol
== PF_INET
? "PF_INET" : "PF_INET6", result
);
1705 for (i
= 0; addresses
[i
] != 0; i
++) {
1706 utun_remove_address(interface
, protocol
, addresses
[i
], pf_socket
);
1708 ifnet_free_address_list(addresses
);
1712 * The addresses should be gone, we should try the remove again.
1714 result
= utun_detach_ip(interface
, protocol
, pf_socket
);
1715 if (result
!= 0 && result
!= ENXIO
) {
1716 printf("utun_cleanup_family - utun_detach_ip failed: %d\n", result
);
1720 if (pf_socket
!= NULL
) {
1721 sock_close(pf_socket
);
1724 if (addresses
!= NULL
) {
1725 ifnet_free_address_list(addresses
);
1730 utun_ctl_disconnect(__unused kern_ctl_ref kctlref
,
1731 __unused u_int32_t unit
,
1734 struct utun_pcb
*pcb
= unitinfo
;
1743 // Tell the nexus to stop all rings
1744 if (pcb
->utun_netif_nexus
!= NULL
) {
1745 kern_nexus_stop(pcb
->utun_netif_nexus
);
1747 #endif // UTUN_NEXUS
1749 lck_rw_lock_exclusive(&pcb
->utun_pcb_lock
);
1753 uuid_copy(kpipe_uuid
, pcb
->utun_kpipe_uuid
);
1754 uuid_clear(pcb
->utun_kpipe_uuid
);
1755 pcb
->utun_kpipe_enabled
= FALSE
;
1756 #endif // UTUN_NEXUS
1758 pcb
->utun_ctlref
= NULL
;
1760 ifp
= pcb
->utun_ifp
;
1763 // Tell the nexus to stop all rings
1764 if (pcb
->utun_netif_nexus
!= NULL
) {
1766 * Quiesce the interface and flush any pending outbound packets.
1770 /* Increment refcnt, but detach interface */
1771 ifnet_incr_iorefcnt(ifp
);
1772 if ((result
= ifnet_detach(ifp
)) != 0) {
1773 panic("utun_ctl_disconnect - ifnet_detach failed: %d\n", result
);
1777 * We want to do everything in our power to ensure that the interface
1778 * really goes away when the socket is closed. We must remove IP/IPv6
1779 * addresses and detach the protocols. Finally, we can remove and
1780 * release the interface.
1782 utun_cleanup_family(ifp
, AF_INET
);
1783 utun_cleanup_family(ifp
, AF_INET6
);
1785 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1787 if (!uuid_is_null(kpipe_uuid
)) {
1788 if (kern_nexus_controller_free_provider_instance(utun_ncd
, kpipe_uuid
) == 0) {
1789 utun_unregister_kernel_pipe_nexus();
1792 utun_nexus_detach(&pcb
->utun_nx
);
1794 /* Decrement refcnt to finish detaching and freeing */
1795 ifnet_decr_iorefcnt(ifp
);
1797 #endif // UTUN_NEXUS
1799 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1802 if (!uuid_is_null(kpipe_uuid
)) {
1803 if (kern_nexus_controller_free_provider_instance(utun_ncd
, kpipe_uuid
) == 0) {
1804 utun_unregister_kernel_pipe_nexus();
1807 #endif // UTUN_NEXUS
1810 * We want to do everything in our power to ensure that the interface
1811 * really goes away when the socket is closed. We must remove IP/IPv6
1812 * addresses and detach the protocols. Finally, we can remove and
1813 * release the interface.
1815 utun_cleanup_family(ifp
, AF_INET
);
1816 utun_cleanup_family(ifp
, AF_INET6
);
1819 * Detach now; utun_detach() will be called asynchronously once
1820 * the I/O reference count drops to 0. There we will invoke
1823 if ((result
= ifnet_detach(ifp
)) != 0) {
1824 printf("utun_ctl_disconnect - ifnet_detach failed: %d\n", result
);
1828 // Bound, but not connected
1829 lck_rw_unlock_exclusive(&pcb
->utun_pcb_lock
);
1830 utun_free_pcb(pcb
, false);
1837 utun_ctl_send(__unused kern_ctl_ref kctlref
,
1838 __unused u_int32_t unit
,
1844 * The userland ABI requires the first four bytes have the protocol family
1845 * in network byte order: swap them
1847 if (m_pktlen(m
) >= (int32_t)UTUN_HEADER_SIZE((struct utun_pcb
*)unitinfo
)) {
1848 *(protocol_family_t
*)mbuf_data(m
) = ntohl(*(protocol_family_t
*)mbuf_data(m
));
1850 printf("%s - unexpected short mbuf pkt len %d\n", __func__
, m_pktlen(m
) );
1853 return utun_pkt_input((struct utun_pcb
*)unitinfo
, m
);
1857 utun_ctl_setopt(__unused kern_ctl_ref kctlref
,
1858 __unused u_int32_t unit
,
1864 struct utun_pcb
*pcb
= unitinfo
;
1866 /* check for privileges for privileged options */
1868 case UTUN_OPT_FLAGS
:
1869 case UTUN_OPT_EXT_IFDATA_STATS
:
1870 case UTUN_OPT_SET_DELEGATE_INTERFACE
:
1871 if (kauth_cred_issuser(kauth_cred_get()) == 0) {
1878 case UTUN_OPT_FLAGS
:
1879 if (len
!= sizeof(u_int32_t
)) {
1882 if (pcb
->utun_ifp
== NULL
) {
1883 // Only can set after connecting
1888 if (pcb
->utun_use_netif
) {
1889 pcb
->utun_flags
= *(u_int32_t
*)data
;
1891 #endif // UTUN_NEXUS
1893 u_int32_t old_flags
= pcb
->utun_flags
;
1894 pcb
->utun_flags
= *(u_int32_t
*)data
;
1895 if (((old_flags
^ pcb
->utun_flags
) & UTUN_FLAGS_ENABLE_PROC_UUID
)) {
1896 // If UTUN_FLAGS_ENABLE_PROC_UUID flag changed, update bpf
1897 bpfdetach(pcb
->utun_ifp
);
1898 bpfattach(pcb
->utun_ifp
, DLT_NULL
, UTUN_HEADER_SIZE(pcb
));
1904 case UTUN_OPT_EXT_IFDATA_STATS
:
1905 if (len
!= sizeof(int)) {
1909 if (pcb
->utun_ifp
== NULL
) {
1910 // Only can set after connecting
1914 pcb
->utun_ext_ifdata_stats
= (*(int *)data
) ? 1 : 0;
1917 case UTUN_OPT_INC_IFDATA_STATS_IN
:
1918 case UTUN_OPT_INC_IFDATA_STATS_OUT
: {
1919 struct utun_stats_param
*utsp
= (struct utun_stats_param
*)data
;
1921 if (utsp
== NULL
|| len
< sizeof(struct utun_stats_param
)) {
1925 if (pcb
->utun_ifp
== NULL
) {
1926 // Only can set after connecting
1930 if (!pcb
->utun_ext_ifdata_stats
) {
1934 if (opt
== UTUN_OPT_INC_IFDATA_STATS_IN
)
1935 ifnet_stat_increment_in(pcb
->utun_ifp
, utsp
->utsp_packets
,
1936 utsp
->utsp_bytes
, utsp
->utsp_errors
);
1938 ifnet_stat_increment_out(pcb
->utun_ifp
, utsp
->utsp_packets
,
1939 utsp
->utsp_bytes
, utsp
->utsp_errors
);
1942 case UTUN_OPT_SET_DELEGATE_INTERFACE
: {
1943 ifnet_t del_ifp
= NULL
;
1944 char name
[IFNAMSIZ
];
1946 if (len
> IFNAMSIZ
- 1) {
1950 if (pcb
->utun_ifp
== NULL
) {
1951 // Only can set after connecting
1955 if (len
!= 0) { /* if len==0, del_ifp will be NULL causing the delegate to be removed */
1956 bcopy(data
, name
, len
);
1958 result
= ifnet_find_by_name(name
, &del_ifp
);
1961 result
= ifnet_set_delegate(pcb
->utun_ifp
, del_ifp
);
1963 ifnet_release(del_ifp
);
1967 case UTUN_OPT_MAX_PENDING_PACKETS
: {
1968 u_int32_t max_pending_packets
= 0;
1969 if (len
!= sizeof(u_int32_t
)) {
1973 max_pending_packets
= *(u_int32_t
*)data
;
1974 if (max_pending_packets
== 0) {
1978 pcb
->utun_max_pending_packets
= max_pending_packets
;
1982 case UTUN_OPT_ENABLE_CHANNEL
: {
1983 if (len
!= sizeof(int)) {
1987 if (pcb
->utun_ifp
== NULL
) {
1988 // Only can set after connecting
1993 result
= utun_enable_channel(pcb
, current_proc());
1995 result
= utun_disable_channel(pcb
);
1999 case UTUN_OPT_ENABLE_FLOWSWITCH
: {
2000 if (len
!= sizeof(int)) {
2004 if (pcb
->utun_ifp
== NULL
) {
2005 // Only can set after connecting
2009 if (!if_enable_netagent
) {
2013 if (uuid_is_null(pcb
->utun_nx
.ms_agent
)) {
2019 if_add_netagent(pcb
->utun_ifp
, pcb
->utun_nx
.ms_agent
);
2021 if_delete_netagent(pcb
->utun_ifp
, pcb
->utun_nx
.ms_agent
);
2025 case UTUN_OPT_ENABLE_NETIF
: {
2026 if (len
!= sizeof(int)) {
2030 if (pcb
->utun_ifp
!= NULL
) {
2031 // Only can set before connecting
2035 pcb
->utun_use_netif
= true;
2038 case UTUN_OPT_SLOT_SIZE
: {
2039 if (len
!= sizeof(u_int32_t
)) {
2043 if (pcb
->utun_ifp
!= NULL
) {
2044 // Only can set before connecting
2048 u_int32_t slot_size
= *(u_int32_t
*)data
;
2049 if (slot_size
< UTUN_IF_MIN_SLOT_SIZE
||
2050 slot_size
> UTUN_IF_MAX_SLOT_SIZE
) {
2053 pcb
->utun_slot_size
= slot_size
;
2056 case UTUN_OPT_NETIF_RING_SIZE
: {
2057 if (len
!= sizeof(u_int32_t
)) {
2061 if (pcb
->utun_ifp
!= NULL
) {
2062 // Only can set before connecting
2066 u_int32_t ring_size
= *(u_int32_t
*)data
;
2067 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2068 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2071 pcb
->utun_netif_ring_size
= ring_size
;
2074 case UTUN_OPT_TX_FSW_RING_SIZE
: {
2075 if (len
!= sizeof(u_int32_t
)) {
2079 if (pcb
->utun_ifp
!= NULL
) {
2080 // Only can set before connecting
2084 u_int32_t ring_size
= *(u_int32_t
*)data
;
2085 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2086 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2089 pcb
->utun_tx_fsw_ring_size
= ring_size
;
2092 case UTUN_OPT_RX_FSW_RING_SIZE
: {
2093 if (len
!= sizeof(u_int32_t
)) {
2097 if (pcb
->utun_ifp
!= NULL
) {
2098 // Only can set before connecting
2102 u_int32_t ring_size
= *(u_int32_t
*)data
;
2103 if (ring_size
< UTUN_IF_MIN_RING_SIZE
||
2104 ring_size
> UTUN_IF_MAX_RING_SIZE
) {
2107 pcb
->utun_rx_fsw_ring_size
= ring_size
;
2110 #endif // UTUN_NEXUS
2112 result
= ENOPROTOOPT
;
2121 utun_ctl_getopt(__unused kern_ctl_ref kctlref
,
2122 __unused u_int32_t unit
,
2128 struct utun_pcb
*pcb
= unitinfo
;
2132 case UTUN_OPT_FLAGS
:
2133 if (*len
!= sizeof(u_int32_t
)) {
2136 *(u_int32_t
*)data
= pcb
->utun_flags
;
2140 case UTUN_OPT_EXT_IFDATA_STATS
:
2141 if (*len
!= sizeof(int)) {
2144 *(int *)data
= (pcb
->utun_ext_ifdata_stats
) ? 1 : 0;
2148 case UTUN_OPT_IFNAME
:
2149 if (*len
< MIN(strlen(pcb
->utun_if_xname
) + 1, sizeof(pcb
->utun_if_xname
))) {
2152 if (pcb
->utun_ifp
== NULL
) {
2153 // Only can get after connecting
2157 *len
= snprintf(data
, *len
, "%s", pcb
->utun_if_xname
) + 1;
2161 case UTUN_OPT_MAX_PENDING_PACKETS
: {
2162 if (*len
!= sizeof(u_int32_t
)) {
2165 *((u_int32_t
*)data
) = pcb
->utun_max_pending_packets
;
2171 case UTUN_OPT_GET_CHANNEL_UUID
: {
2172 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2173 if (uuid_is_null(pcb
->utun_kpipe_uuid
)) {
2175 } else if (*len
!= sizeof(uuid_t
)) {
2178 uuid_copy(data
, pcb
->utun_kpipe_uuid
);
2180 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2183 case UTUN_OPT_SLOT_SIZE
: {
2184 if (*len
!= sizeof(u_int32_t
)) {
2187 *(u_int32_t
*)data
= pcb
->utun_slot_size
;
2191 case UTUN_OPT_NETIF_RING_SIZE
: {
2192 if (*len
!= sizeof(u_int32_t
)) {
2195 *(u_int32_t
*)data
= pcb
->utun_netif_ring_size
;
2199 case UTUN_OPT_TX_FSW_RING_SIZE
: {
2200 if (*len
!= sizeof(u_int32_t
)) {
2203 *(u_int32_t
*)data
= pcb
->utun_tx_fsw_ring_size
;
2207 case UTUN_OPT_RX_FSW_RING_SIZE
: {
2208 if (*len
!= sizeof(u_int32_t
)) {
2211 *(u_int32_t
*)data
= pcb
->utun_rx_fsw_ring_size
;
2215 #endif // UTUN_NEXUS
2218 result
= ENOPROTOOPT
;
2226 utun_ctl_rcvd(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
, int flags
)
2228 #pragma unused(flags)
2229 bool reenable_output
= false;
2230 struct utun_pcb
*pcb
= unitinfo
;
2234 ifnet_lock_exclusive(pcb
->utun_ifp
);
2236 u_int32_t utun_packet_cnt
;
2237 errno_t error_pc
= ctl_getenqueuepacketcount(kctlref
, unit
, &utun_packet_cnt
);
2238 if (error_pc
!= 0) {
2239 printf("utun_ctl_rcvd: ctl_getenqueuepacketcount returned error %d\n", error_pc
);
2240 utun_packet_cnt
= 0;
2243 if (utun_packet_cnt
< pcb
->utun_max_pending_packets
) {
2244 reenable_output
= true;
2247 if (reenable_output
) {
2248 errno_t error
= ifnet_enable_output(pcb
->utun_ifp
);
2250 printf("utun_ctl_rcvd: ifnet_enable_output returned error %d\n", error
);
2253 ifnet_lock_done(pcb
->utun_ifp
);
2256 /* Network Interface functions */
2258 utun_start(ifnet_t interface
)
2261 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2263 VERIFY(pcb
!= NULL
);
2266 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2267 if (pcb
->utun_kpipe_enabled
) {
2268 /* It's possible to have channels enabled, but not yet have the channel opened,
2269 * in which case the rxring will not be set
2271 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2272 if (pcb
->utun_kpipe_rxring
!= NULL
) {
2273 kern_channel_notify(pcb
->utun_kpipe_rxring
, 0);
2277 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2278 #endif // UTUN_NEXUS
2281 bool can_accept_packets
= true;
2282 ifnet_lock_shared(pcb
->utun_ifp
);
2284 u_int32_t utun_packet_cnt
;
2285 errno_t error_pc
= ctl_getenqueuepacketcount(pcb
->utun_ctlref
, pcb
->utun_unit
, &utun_packet_cnt
);
2286 if (error_pc
!= 0) {
2287 printf("utun_start: ctl_getenqueuepacketcount returned error %d\n", error_pc
);
2288 utun_packet_cnt
= 0;
2291 can_accept_packets
= (utun_packet_cnt
< pcb
->utun_max_pending_packets
);
2292 if (!can_accept_packets
&& pcb
->utun_ctlref
) {
2293 u_int32_t difference
= 0;
2294 if (ctl_getenqueuereadable(pcb
->utun_ctlref
, pcb
->utun_unit
, &difference
) == 0) {
2295 if (difference
> 0) {
2296 // If the low-water mark has not yet been reached, we still need to enqueue data
2298 can_accept_packets
= true;
2302 if (!can_accept_packets
) {
2303 errno_t error
= ifnet_disable_output(interface
);
2305 printf("utun_start: ifnet_disable_output returned error %d\n", error
);
2307 ifnet_lock_done(pcb
->utun_ifp
);
2310 ifnet_lock_done(pcb
->utun_ifp
);
2311 if (ifnet_dequeue(interface
, &data
) != 0) {
2314 if (utun_output(interface
, data
) != 0) {
2321 utun_output(ifnet_t interface
,
2324 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2327 VERIFY(interface
== pcb
->utun_ifp
);
2330 if (!pcb
->utun_use_netif
)
2331 #endif // UTUN_NEXUS
2333 if (m_pktlen(data
) >= (int32_t)UTUN_HEADER_SIZE(pcb
)) {
2334 bpf_tap_out(pcb
->utun_ifp
, DLT_NULL
, data
, 0, 0);
2338 if (pcb
->utun_flags
& UTUN_FLAGS_NO_OUTPUT
) {
2344 // otherwise, fall thru to ctl_enqueumbuf
2345 if (pcb
->utun_ctlref
) {
2349 * The ABI requires the protocol in network byte order
2351 if (m_pktlen(data
) >= (int32_t)UTUN_HEADER_SIZE(pcb
)) {
2352 *(u_int32_t
*)mbuf_data(data
) = htonl(*(u_int32_t
*)mbuf_data(data
));
2355 length
= mbuf_pkthdr_len(data
);
2356 result
= ctl_enqueuembuf(pcb
->utun_ctlref
, pcb
->utun_unit
, data
, CTL_DATA_EOR
);
2359 printf("utun_output - ctl_enqueuembuf failed: %d\n", result
);
2361 if (!pcb
->utun_use_netif
)
2362 #endif // UTUN_NEXUS
2364 ifnet_stat_increment_out(interface
, 0, 0, 1);
2368 if (!pcb
->utun_use_netif
)
2369 #endif // UTUN_NEXUS
2371 if (!pcb
->utun_ext_ifdata_stats
) {
2372 ifnet_stat_increment_out(interface
, 1, length
, 0);
2384 utun_demux(__unused ifnet_t interface
,
2386 __unused
char *frame_header
,
2387 protocol_family_t
*protocol
)
2389 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2393 while (data
!= NULL
&& mbuf_len(data
) < 1) {
2394 data
= mbuf_next(data
);
2402 if (pcb
->utun_use_netif
) {
2403 ip
= mtod(data
, struct ip
*);
2404 ip_version
= ip
->ip_v
;
2406 switch(ip_version
) {
2408 *protocol
= PF_INET
;
2411 *protocol
= PF_INET6
;
2418 #endif // UTUN_NEXUS
2420 *protocol
= *(u_int32_t
*)mbuf_data(data
);
2427 utun_framer(ifnet_t interface
,
2429 __unused
const struct sockaddr
*dest
,
2430 __unused
const char *desk_linkaddr
,
2431 const char *frame_type
,
2432 u_int32_t
*prepend_len
,
2433 u_int32_t
*postpend_len
)
2435 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2436 VERIFY(interface
== pcb
->utun_ifp
);
2438 u_int32_t header_length
= UTUN_HEADER_SIZE(pcb
);
2439 if (mbuf_prepend(packet
, header_length
, MBUF_DONTWAIT
) != 0) {
2440 printf("utun_framer - ifnet_output prepend failed\n");
2442 ifnet_stat_increment_out(interface
, 0, 0, 1);
2444 // just return, because the buffer was freed in mbuf_prepend
2447 if (prepend_len
!= NULL
) {
2448 *prepend_len
= header_length
;
2450 if (postpend_len
!= NULL
) {
2454 // place protocol number at the beginning of the mbuf
2455 *(protocol_family_t
*)mbuf_data(*packet
) = *(protocol_family_t
*)(uintptr_t)(size_t)frame_type
;
2462 utun_add_proto(__unused ifnet_t interface
,
2463 protocol_family_t protocol
,
2464 __unused
const struct ifnet_demux_desc
*demux_array
,
2465 __unused u_int32_t demux_count
)
2480 utun_del_proto(__unused ifnet_t interface
,
2481 __unused protocol_family_t protocol
)
2487 utun_ioctl(ifnet_t interface
,
2491 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2497 if (pcb
->utun_use_netif
) {
2498 // Make sure we can fit packets in the channel buffers
2499 // Allow for the headroom in the slot
2500 if (((uint64_t)((struct ifreq
*)data
)->ifr_mtu
) + UTUN_IF_HEADROOM_SIZE
> pcb
->utun_slot_size
) {
2503 ifnet_set_mtu(interface
, (uint32_t)((struct ifreq
*)data
)->ifr_mtu
);
2506 #endif // UTUN_NEXUS
2508 ifnet_set_mtu(interface
, ((struct ifreq
*)data
)->ifr_mtu
);
2514 /* ifioctl() takes care of it */
2518 result
= EOPNOTSUPP
;
2525 utun_detached(ifnet_t interface
)
2527 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2528 (void)ifnet_release(interface
);
2529 utun_free_pcb(pcb
, true);
2532 /* Protocol Handlers */
2535 utun_proto_input(__unused ifnet_t interface
,
2536 protocol_family_t protocol
,
2538 __unused
char *frame_header
)
2540 struct utun_pcb
*pcb
= ifnet_softc(interface
);
2542 if (!pcb
->utun_use_netif
)
2543 #endif // UTUN_NEXUS
2545 mbuf_adj(m
, UTUN_HEADER_SIZE(pcb
));
2547 if (proto_input(protocol
, m
) != 0) {
2550 if (!pcb
->utun_use_netif
)
2551 #endif // UTUN_NEXUS
2553 ifnet_stat_increment_in(interface
, 0, 0, 1);
2557 if (!pcb
->utun_use_netif
)
2558 #endif // UTUN_NEXUS
2560 ifnet_stat_increment_in(interface
, 1, m
->m_pkthdr
.len
, 0);
2568 utun_proto_pre_output(__unused ifnet_t interface
,
2569 protocol_family_t protocol
,
2570 __unused mbuf_t
*packet
,
2571 __unused
const struct sockaddr
*dest
,
2572 __unused
void *route
,
2574 __unused
char *link_layer_dest
)
2576 *(protocol_family_t
*)(void *)frame_type
= protocol
;
2581 utun_attach_proto(ifnet_t interface
,
2582 protocol_family_t protocol
)
2584 struct ifnet_attach_proto_param proto
;
2586 bzero(&proto
, sizeof(proto
));
2587 proto
.input
= utun_proto_input
;
2588 proto
.pre_output
= utun_proto_pre_output
;
2590 errno_t result
= ifnet_attach_protocol(interface
, protocol
, &proto
);
2591 if (result
!= 0 && result
!= EEXIST
) {
2592 printf("utun_attach_inet - ifnet_attach_protocol %d failed: %d\n",
2600 utun_pkt_input(struct utun_pcb
*pcb
, mbuf_t packet
)
2603 if (pcb
->utun_use_netif
) {
2604 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2606 lck_mtx_lock(&pcb
->utun_input_chain_lock
);
2607 if (pcb
->utun_input_chain
!= NULL
) {
2608 pcb
->utun_input_chain_last
->m_nextpkt
= packet
;
2610 pcb
->utun_input_chain
= packet
;
2612 while (packet
->m_nextpkt
) {
2613 VERIFY(packet
!= packet
->m_nextpkt
);
2614 packet
= packet
->m_nextpkt
;
2616 pcb
->utun_input_chain_last
= packet
;
2617 lck_mtx_unlock(&pcb
->utun_input_chain_lock
);
2619 kern_channel_ring_t rx_ring
= pcb
->utun_netif_rxring
;
2620 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2622 if (rx_ring
!= NULL
) {
2623 kern_channel_notify(rx_ring
, 0);
2628 #endif // IPSEC_NEXUS
2630 mbuf_pkthdr_setrcvif(packet
, pcb
->utun_ifp
);
2632 if (m_pktlen(packet
) >= (int32_t)UTUN_HEADER_SIZE(pcb
)) {
2633 bpf_tap_in(pcb
->utun_ifp
, DLT_NULL
, packet
, 0, 0);
2635 if (pcb
->utun_flags
& UTUN_FLAGS_NO_INPUT
) {
2642 if (!pcb
->utun_ext_ifdata_stats
) {
2643 struct ifnet_stat_increment_param incs
= {};
2644 incs
.packets_in
= 1;
2645 incs
.bytes_in
= mbuf_pkthdr_len(packet
);
2646 result
= ifnet_input(pcb
->utun_ifp
, packet
, &incs
);
2648 result
= ifnet_input(pcb
->utun_ifp
, packet
, NULL
);
2651 ifnet_stat_increment_in(pcb
->utun_ifp
, 0, 0, 1);
2653 printf("%s - ifnet_input failed: %d\n", __FUNCTION__
, result
);
2664 utun_nxdp_init(__unused kern_nexus_domain_provider_t domprov
)
2670 utun_nxdp_fini(__unused kern_nexus_domain_provider_t domprov
)
2676 utun_register_nexus(void)
2678 const struct kern_nexus_domain_provider_init dp_init
= {
2679 .nxdpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
2681 .nxdpi_init
= utun_nxdp_init
,
2682 .nxdpi_fini
= utun_nxdp_fini
2686 /* utun_nxdp_init() is called before this function returns */
2687 err
= kern_nexus_register_domain_provider(NEXUS_TYPE_NET_IF
,
2688 (const uint8_t *) "com.apple.utun",
2689 &dp_init
, sizeof(dp_init
),
2692 printf("%s: failed to register domain provider\n", __func__
);
2699 utun_ifnet_set_attrs(ifnet_t ifp
)
2701 /* Set flags and additional information. */
2702 ifnet_set_mtu(ifp
, 1500);
2703 ifnet_set_flags(ifp
, IFF_UP
| IFF_MULTICAST
| IFF_POINTOPOINT
, 0xffff);
2705 /* The interface must generate its own IPv6 LinkLocal address,
2706 * if possible following the recommendation of RFC2472 to the 64bit interface ID
2708 ifnet_set_eflags(ifp
, IFEF_NOAUTOIPV6LL
, IFEF_NOAUTOIPV6LL
);
2714 utun_netif_prepare(kern_nexus_t nexus
, ifnet_t ifp
)
2716 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2717 pcb
->utun_netif_nexus
= nexus
;
2718 return (utun_ifnet_set_attrs(ifp
));
2722 utun_nexus_pre_connect(kern_nexus_provider_t nxprov
,
2723 proc_t p
, kern_nexus_t nexus
,
2724 nexus_port_t nexus_port
, kern_channel_t channel
, void **ch_ctx
)
2726 #pragma unused(nxprov, p)
2727 #pragma unused(nexus, nexus_port, channel, ch_ctx)
2732 utun_nexus_connected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2733 kern_channel_t channel
)
2735 #pragma unused(nxprov, channel)
2736 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2737 boolean_t ok
= ifnet_is_attached(pcb
->utun_ifp
, 1);
2738 return (ok
? 0 : ENXIO
);
2742 utun_nexus_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2743 kern_channel_t channel
)
2745 #pragma unused(nxprov, nexus, channel)
2749 utun_netif_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2750 kern_channel_t channel
)
2752 #pragma unused(nxprov, nexus, channel)
2756 utun_nexus_disconnected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2757 kern_channel_t channel
)
2759 #pragma unused(nxprov, channel)
2760 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2761 if (pcb
->utun_netif_nexus
== nexus
) {
2762 pcb
->utun_netif_nexus
= NULL
;
2764 ifnet_decr_iorefcnt(pcb
->utun_ifp
);
2768 utun_kpipe_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2769 kern_channel_t channel
, kern_channel_ring_t ring
,
2770 boolean_t is_tx_ring
, void **ring_ctx
)
2772 #pragma unused(nxprov)
2773 #pragma unused(channel)
2774 #pragma unused(ring_ctx)
2775 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2777 VERIFY(pcb
->utun_kpipe_rxring
== NULL
);
2778 pcb
->utun_kpipe_rxring
= ring
;
2780 VERIFY(pcb
->utun_kpipe_txring
== NULL
);
2781 pcb
->utun_kpipe_txring
= ring
;
2787 utun_kpipe_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2788 kern_channel_ring_t ring
)
2790 #pragma unused(nxprov)
2791 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2792 if (pcb
->utun_kpipe_rxring
== ring
) {
2793 pcb
->utun_kpipe_rxring
= NULL
;
2794 } else if (pcb
->utun_kpipe_txring
== ring
) {
2795 pcb
->utun_kpipe_txring
= NULL
;
2800 utun_kpipe_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2801 kern_channel_ring_t tx_ring
, uint32_t flags
)
2803 #pragma unused(nxprov)
2804 #pragma unused(flags)
2805 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2807 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2808 int channel_enabled
= pcb
->utun_kpipe_enabled
;
2809 if (!channel_enabled
) {
2810 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2814 if (pcb
->utun_use_netif
) {
2815 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
2816 if (tx_slot
== NULL
) {
2817 // Nothing to write, bail
2818 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2822 // Signal the netif ring to read
2823 kern_channel_ring_t rx_ring
= pcb
->utun_netif_rxring
;
2824 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2825 if (rx_ring
!= NULL
) {
2826 kern_channel_notify(rx_ring
, 0);
2829 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2831 struct ifnet_stat_increment_param incs
= {};
2832 struct kern_channel_ring_stat_increment tx_ring_stats
= {};
2833 MBUFQ_HEAD(mbufq
) mbq
;
2835 kern_channel_slot_t tx_pslot
= NULL
;
2836 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
2837 while (tx_slot
!= NULL
) {
2838 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
2842 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
2848 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
2849 VERIFY(tx_buf
!= NULL
);
2850 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
2851 VERIFY(tx_baddr
!= 0);
2852 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
2854 size_t length
= MIN(kern_packet_get_data_length(tx_ph
),
2855 pcb
->utun_slot_size
);
2858 if (length
>= UTUN_HEADER_SIZE(pcb
) &&
2859 !(pcb
->utun_flags
& UTUN_FLAGS_NO_INPUT
)) {
2860 errno_t error
= mbuf_gethdr(MBUF_WAITOK
, MBUF_TYPE_HEADER
, &data
);
2862 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_WAITOK
);
2865 * The userland ABI requires the first four bytes have
2866 * the protocol family in network byte order: swap them
2868 *(uint32_t *)mbuf_data(data
) = ntohl(*(uint32_t *)mbuf_data(data
));
2869 mbuf_pkthdr_setrcvif(data
, pcb
->utun_ifp
);
2870 bpf_tap_in(pcb
->utun_ifp
, DLT_NULL
, data
, 0, 0);
2872 incs
.bytes_in
+= length
;
2873 MBUFQ_ENQUEUE(&mbq
, data
);
2877 kern_channel_advance_slot(tx_ring
, tx_pslot
);
2878 tx_ring_stats
.kcrsi_slots_transferred
= incs
.packets_in
;
2879 tx_ring_stats
.kcrsi_bytes_transferred
= incs
.bytes_in
;
2880 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
2881 (void) kern_channel_reclaim(tx_ring
);
2883 if (!MBUFQ_EMPTY(&mbq
)) {
2884 (void) ifnet_input_extended(pcb
->utun_ifp
, MBUFQ_FIRST(&mbq
),
2885 MBUFQ_LAST(&mbq
), &incs
);
2894 utun_kpipe_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
2895 kern_channel_ring_t rx_ring
, uint32_t flags
)
2897 #pragma unused(nxprov)
2898 #pragma unused(flags)
2899 struct utun_pcb
*pcb
= kern_nexus_get_context(nexus
);
2900 struct kern_channel_ring_stat_increment rx_ring_stats
= {};
2902 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2904 int channel_enabled
= pcb
->utun_kpipe_enabled
;
2905 if (!channel_enabled
) {
2906 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2910 /* reclaim user-released slots */
2911 (void) kern_channel_reclaim(rx_ring
);
2913 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
2915 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2919 if (pcb
->utun_use_netif
) {
2920 kern_channel_ring_t tx_ring
= pcb
->utun_netif_txring
;
2921 if (tx_ring
== NULL
||
2922 pcb
->utun_netif_nexus
== NULL
) {
2923 // Net-If TX ring not set up yet, nothing to read
2924 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2928 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(pcb
->utun_netif_nexus
)->nif_stats
;
2930 // Unlock utun before entering ring
2931 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2933 (void)kr_enter(tx_ring
, TRUE
);
2935 // Lock again after entering and validate
2936 lck_rw_lock_shared(&pcb
->utun_pcb_lock
);
2937 if (tx_ring
!= pcb
->utun_netif_txring
) {
2938 // Ring no longer valid
2939 // Unlock first, then exit ring
2940 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2945 struct kern_channel_ring_stat_increment tx_ring_stats
;
2946 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
2947 kern_channel_slot_t tx_pslot
= NULL
;
2948 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
2949 if (tx_slot
== NULL
) {
2950 // Nothing to read, don't bother signalling
2951 // Unlock first, then exit ring
2952 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
2957 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
2958 VERIFY(rx_pp
!= NULL
);
2959 kern_channel_slot_t rx_pslot
= NULL
;
2960 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
2962 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
2964 kern_buflet_t rx_buf
;
2967 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
2971 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
2973 /* Skip slot if packet is zero-length or marked as dropped (QUMF_DROPPED) */
2978 // Allocate rx packet
2979 kern_packet_t rx_ph
= 0;
2980 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
2981 if (unlikely(error
!= 0)) {
2982 printf("utun_kpipe_sync_rx %s: failed to allocate packet\n",
2983 pcb
->utun_ifp
->if_xname
);
2987 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
2988 VERIFY(tx_buf
!= NULL
);
2989 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
2990 VERIFY(tx_baddr
!= NULL
);
2991 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
2993 bpf_tap_packet_out(pcb
->utun_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
2995 length
= MIN(kern_packet_get_data_length(tx_ph
) + UTUN_HEADER_SIZE(pcb
),
2996 pcb
->utun_slot_size
);
2998 tx_ring_stats
.kcrsi_slots_transferred
++;
2999 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
3001 if (length
< UTUN_HEADER_SIZE(pcb
) ||
3002 length
> pcb
->utun_slot_size
||
3003 length
> rx_pp
->pp_buflet_size
||
3004 (pcb
->utun_flags
& UTUN_FLAGS_NO_OUTPUT
)) {
3006 kern_pbufpool_free(rx_pp
, rx_ph
);
3007 printf("utun_kpipe_sync_rx %s: invalid length %zu header_size %zu\n",
3008 pcb
->utun_ifp
->if_xname
, length
, UTUN_HEADER_SIZE(pcb
));
3009 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
3010 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
3014 /* fillout packet */
3015 rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
3016 VERIFY(rx_buf
!= NULL
);
3017 rx_baddr
= kern_buflet_get_object_address(rx_buf
);
3018 VERIFY(rx_baddr
!= NULL
);
3022 uint8_t vhl
= *(uint8_t *)(tx_baddr
);
3023 u_int ip_version
= (vhl
>> 4);
3024 switch (ip_version
) {
3034 printf("utun_kpipe_sync_rx %s: unknown ip version %u vhl %u header_size %zu\n",
3035 pcb
->utun_ifp
->if_xname
, ip_version
, vhl
, UTUN_HEADER_SIZE(pcb
));
3042 memcpy((void *)rx_baddr
, &af
, sizeof(af
));
3043 if (pcb
->utun_flags
& UTUN_FLAGS_ENABLE_PROC_UUID
) {
3044 kern_packet_get_euuid(tx_ph
, (void *)(rx_baddr
+ sizeof(af
)));
3047 // Copy data from tx to rx
3048 memcpy((void *)(rx_baddr
+ UTUN_HEADER_SIZE(pcb
)), (void *)tx_baddr
, length
- UTUN_HEADER_SIZE(pcb
));
3049 kern_packet_clear_flow_uuid(rx_ph
); // zero flow id
3051 /* finalize and attach the packet */
3052 error
= kern_buflet_set_data_offset(rx_buf
, 0);
3054 error
= kern_buflet_set_data_length(rx_buf
, length
);
3056 error
= kern_packet_finalize(rx_ph
);
3058 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
3061 STATS_INC(nifs
, NETIF_STATS_TXPKTS
);
3062 STATS_INC(nifs
, NETIF_STATS_TXCOPY_DIRECT
);
3064 rx_ring_stats
.kcrsi_slots_transferred
++;
3065 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
3068 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
3072 kern_channel_advance_slot(rx_ring
, rx_pslot
);
3073 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->utun_ifp
, &rx_ring_stats
);
3077 kern_channel_advance_slot(tx_ring
, tx_pslot
);
3078 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->utun_ifp
, &tx_ring_stats
);
3079 (void)kern_channel_reclaim(tx_ring
);
3082 /* just like utun_ctl_rcvd(), always reenable output */
3083 errno_t error
= ifnet_enable_output(pcb
->utun_ifp
);
3085 printf("utun_kpipe_sync_rx: ifnet_enable_output returned error %d\n", error
);
3088 // Unlock first, then exit ring
3089 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3091 if (tx_pslot
!= NULL
) {
3092 kern_channel_notify(tx_ring
, 0);
3096 lck_rw_unlock_shared(&pcb
->utun_pcb_lock
);
3098 uint32_t mb_cnt
= 0;
3099 uint32_t mb_len
= 0;
3100 struct mbuf
*mb_head
= NULL
;
3101 struct mbuf
*mb_tail
= NULL
;
3103 if (ifnet_dequeue_multi(pcb
->utun_ifp
, avail
, &mb_head
,
3104 &mb_tail
, &mb_cnt
, &mb_len
) != 0) {
3107 VERIFY(mb_cnt
<= avail
);
3109 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
3110 VERIFY(rx_pp
!= NULL
);
3111 kern_channel_slot_t rx_pslot
= NULL
;
3112 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
3116 if ((data
= mb_head
) == NULL
) {
3117 VERIFY(mb_cnt
== 0);
3120 mb_head
= mbuf_nextpkt(mb_head
);
3121 mbuf_setnextpkt(data
, NULL
);
3122 VERIFY(mb_cnt
!= 0);
3124 length
= mbuf_pkthdr_len(data
);
3125 if (length
< UTUN_HEADER_SIZE(pcb
) ||
3126 length
> pcb
->utun_slot_size
||
3127 (pcb
->utun_flags
& UTUN_FLAGS_NO_OUTPUT
)) {
3132 bpf_tap_out(pcb
->utun_ifp
, DLT_NULL
, data
, 0, 0);
3134 // Allocate rx packet
3135 kern_packet_t rx_ph
= 0;
3136 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
3137 if (unlikely(error
!= 0)) {
3138 printf("utun_kpipe_sync_rx %s: failed to allocate packet\n",
3139 pcb
->utun_ifp
->if_xname
);
3144 * The ABI requires the protocol in network byte order
3146 *(u_int32_t
*)mbuf_data(data
) = htonl(*(u_int32_t
*)mbuf_data(data
));
3148 // Fillout rx packet
3149 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
3150 VERIFY(rx_buf
!= NULL
);
3151 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
3152 VERIFY(rx_baddr
!= NULL
);
3154 // Copy-in data from mbuf to buflet
3155 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
3156 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
3158 // Finalize and attach the packet
3159 error
= kern_buflet_set_data_offset(rx_buf
, 0);
3161 error
= kern_buflet_set_data_length(rx_buf
, length
);
3163 error
= kern_packet_finalize(rx_ph
);
3165 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
3168 rx_ring_stats
.kcrsi_slots_transferred
++;
3169 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
3171 if (!pcb
->utun_ext_ifdata_stats
) {
3172 ifnet_stat_increment_out(pcb
->utun_ifp
, 1, length
, 0);
3178 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
3181 kern_channel_advance_slot(rx_ring
, rx_pslot
);
3182 kern_channel_increment_ring_stats(rx_ring
, &rx_ring_stats
);
3184 if (mb_head
!= NULL
) {
3185 VERIFY(mb_cnt
!= 0);
3186 mbuf_freem_list(mb_head
);
3193 #endif // UTUN_NEXUS
3197 * These are place holders until coreTLS kext stops calling them
3199 errno_t
utun_ctl_register_dtls (void *reg
);
3200 int utun_pkt_dtls_input(struct utun_pcb
*pcb
, mbuf_t
*pkt
, protocol_family_t family
);
3201 void utun_ctl_disable_crypto_dtls(struct utun_pcb
*pcb
);
3204 utun_ctl_register_dtls (void *reg
)
3211 utun_pkt_dtls_input(struct utun_pcb
*pcb
, mbuf_t
*pkt
, protocol_family_t family
)
3215 #pragma unused(family)
3220 utun_ctl_disable_crypto_dtls(struct utun_pcb
*pcb
)