2 * Copyright (c) 2012-2019 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@
30 #include <sys/systm.h>
31 #include <sys/kern_control.h>
32 #include <net/kpi_protocol.h>
33 #include <net/kpi_interface.h>
34 #include <sys/socket.h>
35 #include <sys/socketvar.h>
37 #include <net/if_types.h>
39 #include <net/if_ipsec.h>
41 #include <sys/sockio.h>
42 #include <netinet/in.h>
43 #include <netinet/ip6.h>
44 #include <netinet6/in6_var.h>
45 #include <netinet6/ip6_var.h>
46 #include <sys/kauth.h>
47 #include <netinet6/ipsec.h>
48 #include <netinet6/ipsec6.h>
49 #include <netinet6/esp.h>
50 #include <netinet6/esp6.h>
51 #include <netinet/ip.h>
52 #include <net/flowadv.h>
54 #include <netkey/key.h>
55 #include <net/pktap.h>
56 #include <kern/zalloc.h>
61 extern int net_qos_policy_restricted
;
62 extern int net_qos_policy_restrict_avapps
;
64 /* Kernel Control functions */
65 static errno_t
ipsec_ctl_bind(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
67 static errno_t
ipsec_ctl_connect(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
69 static errno_t
ipsec_ctl_disconnect(kern_ctl_ref kctlref
, u_int32_t unit
,
71 static errno_t
ipsec_ctl_send(kern_ctl_ref kctlref
, u_int32_t unit
,
72 void *unitinfo
, mbuf_t m
, int flags
);
73 static errno_t
ipsec_ctl_getopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
74 int opt
, void *data
, size_t *len
);
75 static errno_t
ipsec_ctl_setopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
76 int opt
, void *data
, size_t len
);
78 /* Network Interface functions */
79 static void ipsec_start(ifnet_t interface
);
80 static errno_t
ipsec_output(ifnet_t interface
, mbuf_t data
);
81 static errno_t
ipsec_demux(ifnet_t interface
, mbuf_t data
, char *frame_header
,
82 protocol_family_t
*protocol
);
83 static errno_t
ipsec_add_proto(ifnet_t interface
, protocol_family_t protocol
,
84 const struct ifnet_demux_desc
*demux_array
,
85 u_int32_t demux_count
);
86 static errno_t
ipsec_del_proto(ifnet_t interface
, protocol_family_t protocol
);
87 static errno_t
ipsec_ioctl(ifnet_t interface
, u_long cmd
, void *data
);
88 static void ipsec_detached(ifnet_t interface
);
90 /* Protocol handlers */
91 static errno_t
ipsec_attach_proto(ifnet_t interface
, protocol_family_t proto
);
92 static errno_t
ipsec_proto_input(ifnet_t interface
, protocol_family_t protocol
,
93 mbuf_t m
, char *frame_header
);
94 static errno_t
ipsec_proto_pre_output(ifnet_t interface
, protocol_family_t protocol
,
95 mbuf_t
*packet
, const struct sockaddr
*dest
, void *route
,
96 char *frame_type
, char *link_layer_dest
);
98 static kern_ctl_ref ipsec_kctlref
;
99 static lck_attr_t
*ipsec_lck_attr
;
100 static lck_grp_attr_t
*ipsec_lck_grp_attr
;
101 static lck_grp_t
*ipsec_lck_grp
;
102 static lck_mtx_t ipsec_lock
;
106 SYSCTL_DECL(_net_ipsec
);
107 SYSCTL_NODE(_net
, OID_AUTO
, ipsec
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "IPsec");
108 static int if_ipsec_verify_interface_creation
= 0;
109 SYSCTL_INT(_net_ipsec
, OID_AUTO
, verify_interface_creation
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &if_ipsec_verify_interface_creation
, 0, "");
111 #define IPSEC_IF_VERIFY(_e) if (__improbable(if_ipsec_verify_interface_creation)) { VERIFY(_e); }
113 #define IPSEC_IF_DEFAULT_SLOT_SIZE 2048
114 #define IPSEC_IF_DEFAULT_RING_SIZE 64
115 #define IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE 64
116 #define IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE 128
117 #define IPSEC_IF_DEFAULT_BUF_SEG_SIZE skmem_usr_buf_seg_size
119 #define IPSEC_IF_WMM_RING_COUNT NEXUS_NUM_WMM_QUEUES
120 #define IPSEC_IF_MAX_RING_COUNT IPSEC_IF_WMM_RING_COUNT
121 #define IPSEC_NETIF_WMM_TX_RING_COUNT IPSEC_IF_WMM_RING_COUNT
122 #define IPSEC_NETIF_WMM_RX_RING_COUNT 1
123 #define IPSEC_NETIF_MAX_TX_RING_COUNT IPSEC_NETIF_WMM_TX_RING_COUNT
124 #define IPSEC_NETIF_MAX_RX_RING_COUNT IPSEC_NETIF_WMM_RX_RING_COUNT
126 #define IPSEC_IF_MIN_RING_SIZE 8
127 #define IPSEC_IF_MAX_RING_SIZE 1024
129 #define IPSEC_IF_MIN_SLOT_SIZE 1024
130 #define IPSEC_IF_MAX_SLOT_SIZE 4096
132 #define IPSEC_DEFAULT_MAX_PENDING_INPUT_COUNT 512
134 static int if_ipsec_max_pending_input
= IPSEC_DEFAULT_MAX_PENDING_INPUT_COUNT
;
136 static int sysctl_if_ipsec_ring_size SYSCTL_HANDLER_ARGS
;
137 static int sysctl_if_ipsec_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
138 static int sysctl_if_ipsec_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
140 static int if_ipsec_ring_size
= IPSEC_IF_DEFAULT_RING_SIZE
;
141 static int if_ipsec_tx_fsw_ring_size
= IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE
;
142 static int if_ipsec_rx_fsw_ring_size
= IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE
;
144 SYSCTL_INT(_net_ipsec
, OID_AUTO
, max_pending_input
, CTLFLAG_LOCKED
| CTLFLAG_RW
, &if_ipsec_max_pending_input
, 0, "");
145 SYSCTL_PROC(_net_ipsec
, OID_AUTO
, ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
146 &if_ipsec_ring_size
, IPSEC_IF_DEFAULT_RING_SIZE
, &sysctl_if_ipsec_ring_size
, "I", "");
147 SYSCTL_PROC(_net_ipsec
, OID_AUTO
, tx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
148 &if_ipsec_tx_fsw_ring_size
, IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE
, &sysctl_if_ipsec_tx_fsw_ring_size
, "I", "");
149 SYSCTL_PROC(_net_ipsec
, OID_AUTO
, rx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
150 &if_ipsec_rx_fsw_ring_size
, IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE
, &sysctl_if_ipsec_rx_fsw_ring_size
, "I", "");
152 static int if_ipsec_debug
= 0;
153 SYSCTL_INT(_net_ipsec
, OID_AUTO
, debug
, CTLFLAG_LOCKED
| CTLFLAG_RW
, &if_ipsec_debug
, 0, "");
156 ipsec_register_nexus(void);
158 typedef struct ipsec_nx
{
168 static nexus_controller_t ipsec_ncd
;
169 static int ipsec_ncd_refcount
;
170 static uuid_t ipsec_kpipe_uuid
;
172 #endif // IPSEC_NEXUS
174 /* Control block allocated for each kernel control connection */
176 TAILQ_ENTRY(ipsec_pcb
) ipsec_chain
;
177 kern_ctl_ref ipsec_ctlref
;
179 u_int32_t ipsec_unit
;
180 u_int32_t ipsec_unique_id
;
181 // These external flags can be set with IPSEC_OPT_FLAGS
182 u_int32_t ipsec_external_flags
;
183 // These internal flags are only used within this driver
184 u_int32_t ipsec_internal_flags
;
185 u_int32_t ipsec_input_frag_size
;
186 bool ipsec_frag_size_set
;
187 int ipsec_ext_ifdata_stats
;
188 mbuf_svc_class_t ipsec_output_service_class
;
189 char ipsec_if_xname
[IFXNAMSIZ
];
190 char ipsec_unique_name
[IFXNAMSIZ
];
191 // PCB lock protects state fields, like ipsec_kpipe_count
192 decl_lck_rw_data(, ipsec_pcb_lock
);
193 // lock to protect ipsec_pcb_data_move & ipsec_pcb_drainers
194 decl_lck_mtx_data(, ipsec_pcb_data_move_lock
);
195 u_int32_t ipsec_pcb_data_move
; /* number of data moving contexts */
196 u_int32_t ipsec_pcb_drainers
; /* number of threads waiting to drain */
197 u_int32_t ipsec_pcb_data_path_state
; /* internal state of interface data path */
200 lck_mtx_t ipsec_input_chain_lock
;
201 lck_mtx_t ipsec_kpipe_encrypt_lock
;
202 lck_mtx_t ipsec_kpipe_decrypt_lock
;
203 struct mbuf
* ipsec_input_chain
;
204 struct mbuf
* ipsec_input_chain_last
;
205 u_int32_t ipsec_input_chain_count
;
206 // Input chain lock protects the list of input mbufs
207 // The input chain lock must be taken AFTER the PCB lock if both are held
208 struct ipsec_nx ipsec_nx
;
209 u_int32_t ipsec_kpipe_count
;
210 pid_t ipsec_kpipe_pid
;
211 uuid_t ipsec_kpipe_uuid
[IPSEC_IF_MAX_RING_COUNT
];
212 void * ipsec_kpipe_rxring
[IPSEC_IF_MAX_RING_COUNT
];
213 void * ipsec_kpipe_txring
[IPSEC_IF_MAX_RING_COUNT
];
214 kern_pbufpool_t ipsec_kpipe_pp
;
215 u_int32_t ipsec_kpipe_tx_ring_size
;
216 u_int32_t ipsec_kpipe_rx_ring_size
;
218 kern_nexus_t ipsec_netif_nexus
;
219 kern_pbufpool_t ipsec_netif_pp
;
220 void * ipsec_netif_rxring
[IPSEC_NETIF_MAX_RX_RING_COUNT
];
221 void * ipsec_netif_txring
[IPSEC_NETIF_MAX_TX_RING_COUNT
];
222 uint64_t ipsec_netif_txring_size
;
224 u_int32_t ipsec_slot_size
;
225 u_int32_t ipsec_netif_ring_size
;
226 u_int32_t ipsec_tx_fsw_ring_size
;
227 u_int32_t ipsec_rx_fsw_ring_size
;
228 bool ipsec_use_netif
;
229 bool ipsec_needs_netagent
;
230 #endif // IPSEC_NEXUS
233 /* These are internal flags not exposed outside this file */
234 #define IPSEC_FLAGS_KPIPE_ALLOCATED 1
236 /* data movement refcounting functions */
237 static boolean_t
ipsec_data_move_begin(struct ipsec_pcb
*pcb
);
238 static void ipsec_data_move_end(struct ipsec_pcb
*pcb
);
239 static void ipsec_wait_data_move_drain(struct ipsec_pcb
*pcb
);
241 /* Data path states */
242 #define IPSEC_PCB_DATA_PATH_READY 0x1
244 /* Macros to set/clear/test data path states */
245 #define IPSEC_SET_DATA_PATH_READY(_pcb) ((_pcb)->ipsec_pcb_data_path_state |= IPSEC_PCB_DATA_PATH_READY)
246 #define IPSEC_CLR_DATA_PATH_READY(_pcb) ((_pcb)->ipsec_pcb_data_path_state &= ~IPSEC_PCB_DATA_PATH_READY)
247 #define IPSEC_IS_DATA_PATH_READY(_pcb) (((_pcb)->ipsec_pcb_data_path_state & IPSEC_PCB_DATA_PATH_READY) != 0)
250 /* Macros to clear/set/test flags. */
252 ipsec_flag_set(struct ipsec_pcb
*pcb
, uint32_t flag
)
254 pcb
->ipsec_internal_flags
|= flag
;
257 ipsec_flag_clr(struct ipsec_pcb
*pcb
, uint32_t flag
)
259 pcb
->ipsec_internal_flags
&= ~flag
;
263 ipsec_flag_isset(struct ipsec_pcb
*pcb
, uint32_t flag
)
265 return !!(pcb
->ipsec_internal_flags
& flag
);
267 #endif // IPSEC_NEXUS
269 TAILQ_HEAD(ipsec_list
, ipsec_pcb
) ipsec_head
;
271 #define IPSEC_PCB_ZONE_MAX 32
272 #define IPSEC_PCB_ZONE_NAME "net.if_ipsec"
274 static unsigned int ipsec_pcb_size
; /* size of zone element */
275 static struct zone
*ipsec_pcb_zone
; /* zone for ipsec_pcb */
277 #define IPSECQ_MAXLEN 256
281 sysctl_if_ipsec_ring_size SYSCTL_HANDLER_ARGS
283 #pragma unused(arg1, arg2)
284 int value
= if_ipsec_ring_size
;
286 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
287 if (error
|| !req
->newptr
) {
291 if (value
< IPSEC_IF_MIN_RING_SIZE
||
292 value
> IPSEC_IF_MAX_RING_SIZE
) {
296 if_ipsec_ring_size
= value
;
302 sysctl_if_ipsec_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
304 #pragma unused(arg1, arg2)
305 int value
= if_ipsec_tx_fsw_ring_size
;
307 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
308 if (error
|| !req
->newptr
) {
312 if (value
< IPSEC_IF_MIN_RING_SIZE
||
313 value
> IPSEC_IF_MAX_RING_SIZE
) {
317 if_ipsec_tx_fsw_ring_size
= value
;
323 sysctl_if_ipsec_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
325 #pragma unused(arg1, arg2)
326 int value
= if_ipsec_rx_fsw_ring_size
;
328 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
329 if (error
|| !req
->newptr
) {
333 if (value
< IPSEC_IF_MIN_RING_SIZE
||
334 value
> IPSEC_IF_MAX_RING_SIZE
) {
338 if_ipsec_rx_fsw_ring_size
= value
;
345 ipsec_in_wmm_mode(struct ipsec_pcb
*pcb
)
347 return pcb
->ipsec_kpipe_count
== IPSEC_IF_WMM_RING_COUNT
;
350 #endif // IPSEC_NEXUS
353 ipsec_register_control(void)
355 struct kern_ctl_reg kern_ctl
;
358 ipsec_pcb_size
= sizeof(struct ipsec_pcb
);
359 ipsec_pcb_zone
= zinit(ipsec_pcb_size
,
360 IPSEC_PCB_ZONE_MAX
* ipsec_pcb_size
,
361 0, IPSEC_PCB_ZONE_NAME
);
362 if (ipsec_pcb_zone
== NULL
) {
363 os_log_error(OS_LOG_DEFAULT
, "ipsec_register_control - zinit(ipsec_pcb) failed");
368 ipsec_register_nexus();
369 #endif // IPSEC_NEXUS
371 TAILQ_INIT(&ipsec_head
);
373 bzero(&kern_ctl
, sizeof(kern_ctl
));
374 strlcpy(kern_ctl
.ctl_name
, IPSEC_CONTROL_NAME
, sizeof(kern_ctl
.ctl_name
));
375 kern_ctl
.ctl_name
[sizeof(kern_ctl
.ctl_name
) - 1] = 0;
376 kern_ctl
.ctl_flags
= CTL_FLAG_PRIVILEGED
; /* Require root */
377 kern_ctl
.ctl_sendsize
= 64 * 1024;
378 kern_ctl
.ctl_recvsize
= 64 * 1024;
379 kern_ctl
.ctl_bind
= ipsec_ctl_bind
;
380 kern_ctl
.ctl_connect
= ipsec_ctl_connect
;
381 kern_ctl
.ctl_disconnect
= ipsec_ctl_disconnect
;
382 kern_ctl
.ctl_send
= ipsec_ctl_send
;
383 kern_ctl
.ctl_setopt
= ipsec_ctl_setopt
;
384 kern_ctl
.ctl_getopt
= ipsec_ctl_getopt
;
386 result
= ctl_register(&kern_ctl
, &ipsec_kctlref
);
388 os_log_error(OS_LOG_DEFAULT
, "ipsec_register_control - ctl_register failed: %d\n", result
);
392 /* Register the protocol plumbers */
393 if ((result
= proto_register_plumber(PF_INET
, IFNET_FAMILY_IPSEC
,
394 ipsec_attach_proto
, NULL
)) != 0) {
395 os_log_error(OS_LOG_DEFAULT
, "ipsec_register_control - proto_register_plumber(PF_INET, IFNET_FAMILY_IPSEC) failed: %d\n",
397 ctl_deregister(ipsec_kctlref
);
401 /* Register the protocol plumbers */
402 if ((result
= proto_register_plumber(PF_INET6
, IFNET_FAMILY_IPSEC
,
403 ipsec_attach_proto
, NULL
)) != 0) {
404 proto_unregister_plumber(PF_INET
, IFNET_FAMILY_IPSEC
);
405 ctl_deregister(ipsec_kctlref
);
406 os_log_error(OS_LOG_DEFAULT
, "ipsec_register_control - proto_register_plumber(PF_INET6, IFNET_FAMILY_IPSEC) failed: %d\n",
411 ipsec_lck_attr
= lck_attr_alloc_init();
412 ipsec_lck_grp_attr
= lck_grp_attr_alloc_init();
413 ipsec_lck_grp
= lck_grp_alloc_init("ipsec", ipsec_lck_grp_attr
);
414 lck_mtx_init(&ipsec_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
421 ipsec_interface_isvalid(ifnet_t interface
)
423 struct ipsec_pcb
*pcb
= NULL
;
425 if (interface
== NULL
) {
429 pcb
= ifnet_softc(interface
);
435 /* When ctl disconnects, ipsec_unit is set to 0 */
436 if (pcb
->ipsec_unit
== 0) {
445 ipsec_interface_needs_netagent(ifnet_t interface
)
447 struct ipsec_pcb
*pcb
= NULL
;
449 if (interface
== NULL
) {
453 pcb
= ifnet_softc(interface
);
459 return pcb
->ipsec_needs_netagent
== true;
461 #endif // IPSEC_NEXUS
464 ipsec_ifnet_set_attrs(ifnet_t ifp
)
466 /* Set flags and additional information. */
467 ifnet_set_mtu(ifp
, 1500);
468 ifnet_set_flags(ifp
, IFF_UP
| IFF_MULTICAST
| IFF_POINTOPOINT
, 0xffff);
470 /* The interface must generate its own IPv6 LinkLocal address,
471 * if possible following the recommendation of RFC2472 to the 64bit interface ID
473 ifnet_set_eflags(ifp
, IFEF_NOAUTOIPV6LL
, IFEF_NOAUTOIPV6LL
);
476 /* Reset the stats in case as the interface may have been recycled */
477 struct ifnet_stats_param stats
;
478 bzero(&stats
, sizeof(struct ifnet_stats_param
));
479 ifnet_set_stat(ifp
, &stats
);
480 #endif // !IPSEC_NEXUS
487 static uuid_t ipsec_nx_dom_prov
;
490 ipsec_nxdp_init(__unused kern_nexus_domain_provider_t domprov
)
496 ipsec_nxdp_fini(__unused kern_nexus_domain_provider_t domprov
)
502 ipsec_register_nexus(void)
504 const struct kern_nexus_domain_provider_init dp_init
= {
505 .nxdpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
507 .nxdpi_init
= ipsec_nxdp_init
,
508 .nxdpi_fini
= ipsec_nxdp_fini
512 /* ipsec_nxdp_init() is called before this function returns */
513 err
= kern_nexus_register_domain_provider(NEXUS_TYPE_NET_IF
,
514 (const uint8_t *) "com.apple.ipsec",
515 &dp_init
, sizeof(dp_init
),
518 os_log_error(OS_LOG_DEFAULT
, "%s: failed to register domain provider\n", __func__
);
525 ipsec_netif_prepare(kern_nexus_t nexus
, ifnet_t ifp
)
527 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
528 pcb
->ipsec_netif_nexus
= nexus
;
529 return ipsec_ifnet_set_attrs(ifp
);
533 ipsec_nexus_pre_connect(kern_nexus_provider_t nxprov
,
534 proc_t p
, kern_nexus_t nexus
,
535 nexus_port_t nexus_port
, kern_channel_t channel
, void **ch_ctx
)
537 #pragma unused(nxprov, p)
538 #pragma unused(nexus, nexus_port, channel, ch_ctx)
543 ipsec_nexus_connected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
544 kern_channel_t channel
)
546 #pragma unused(nxprov, channel)
547 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
548 boolean_t ok
= ifnet_is_attached(pcb
->ipsec_ifp
, 1);
549 /* Mark the data path as ready */
551 lck_mtx_lock(&pcb
->ipsec_pcb_data_move_lock
);
552 IPSEC_SET_DATA_PATH_READY(pcb
);
553 lck_mtx_unlock(&pcb
->ipsec_pcb_data_move_lock
);
555 return ok
? 0 : ENXIO
;
559 ipsec_nexus_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
560 kern_channel_t channel
)
562 #pragma unused(nxprov, channel)
563 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
565 VERIFY(pcb
->ipsec_kpipe_count
!= 0);
567 /* Wait until all threads in the data paths are done. */
568 ipsec_wait_data_move_drain(pcb
);
572 ipsec_netif_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
573 kern_channel_t channel
)
575 #pragma unused(nxprov, channel)
576 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
578 /* Wait until all threads in the data paths are done. */
579 ipsec_wait_data_move_drain(pcb
);
583 ipsec_nexus_disconnected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
584 kern_channel_t channel
)
586 #pragma unused(nxprov, channel)
587 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
588 if (pcb
->ipsec_netif_nexus
== nexus
) {
589 pcb
->ipsec_netif_nexus
= NULL
;
591 ifnet_decr_iorefcnt(pcb
->ipsec_ifp
);
595 ipsec_kpipe_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
596 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
599 #pragma unused(nxprov)
600 #pragma unused(channel)
601 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
604 for (ring_idx
= 0; ring_idx
< pcb
->ipsec_kpipe_count
; ring_idx
++) {
605 if (!uuid_compare(channel
->ch_info
->cinfo_nx_uuid
, pcb
->ipsec_kpipe_uuid
[ring_idx
])) {
610 if (ring_idx
== pcb
->ipsec_kpipe_count
) {
611 uuid_string_t uuidstr
;
612 uuid_unparse(channel
->ch_info
->cinfo_nx_uuid
, uuidstr
);
613 os_log_error(OS_LOG_DEFAULT
, "%s: %s cannot find channel %s\n", __func__
, pcb
->ipsec_if_xname
, uuidstr
);
617 *ring_ctx
= (void *)(uintptr_t)ring_idx
;
620 VERIFY(pcb
->ipsec_kpipe_rxring
[ring_idx
] == NULL
);
621 pcb
->ipsec_kpipe_rxring
[ring_idx
] = ring
;
623 VERIFY(pcb
->ipsec_kpipe_txring
[ring_idx
] == NULL
);
624 pcb
->ipsec_kpipe_txring
[ring_idx
] = ring
;
630 ipsec_kpipe_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
631 kern_channel_ring_t ring
)
633 #pragma unused(nxprov)
635 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
637 for (unsigned int i
= 0; i
< pcb
->ipsec_kpipe_count
; i
++) {
638 if (pcb
->ipsec_kpipe_rxring
[i
] == ring
) {
639 pcb
->ipsec_kpipe_rxring
[i
] = NULL
;
641 } else if (pcb
->ipsec_kpipe_txring
[i
] == ring
) {
642 pcb
->ipsec_kpipe_txring
[i
] = NULL
;
650 ipsec_kpipe_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
651 kern_channel_ring_t tx_ring
, uint32_t flags
)
653 #pragma unused(nxprov)
654 #pragma unused(flags)
655 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
657 if (!ipsec_data_move_begin(pcb
)) {
658 os_log_info(OS_LOG_DEFAULT
, "%s: data path stopped for %s\n", __func__
, if_name(pcb
->ipsec_ifp
));
662 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
664 if (!ipsec_flag_isset(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
)) {
665 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
666 ipsec_data_move_end(pcb
);
670 VERIFY(pcb
->ipsec_kpipe_count
);
672 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
673 if (tx_slot
== NULL
) {
674 // Nothing to write, bail
675 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
676 ipsec_data_move_end(pcb
);
680 // Signal the netif ring to read
681 kern_channel_ring_t rx_ring
= pcb
->ipsec_netif_rxring
[0];
682 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
684 if (rx_ring
!= NULL
) {
685 kern_channel_notify(rx_ring
, 0);
688 ipsec_data_move_end(pcb
);
693 ipsec_encrypt_mbuf(ifnet_t interface
,
696 struct ipsec_output_state ipsec_state
;
700 // Make sure this packet isn't looping through the interface
701 if (necp_get_last_interface_index_from_packet(data
) == interface
->if_index
) {
703 goto ipsec_output_err
;
706 // Mark the interface so NECP can evaluate tunnel policy
707 necp_mark_packet_from_interface(data
, interface
);
709 struct ip
*ip
= mtod(data
, struct ip
*);
710 u_int ip_version
= ip
->ip_v
;
712 switch (ip_version
) {
716 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
717 ipsec_state
.m
= data
;
718 ipsec_state
.dst
= (struct sockaddr
*)&ip
->ip_dst
;
719 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
721 error
= ipsec4_interface_output(&ipsec_state
, interface
);
722 if (error
== 0 && ipsec_state
.tunneled
== 6) {
723 // Tunneled in IPv6 - packet is gone
724 // TODO: Don't lose mbuf
729 data
= ipsec_state
.m
;
730 if (error
|| data
== NULL
) {
732 os_log_error(OS_LOG_DEFAULT
, "ipsec_encrypt_mbuf: ipsec4_output error %d\n", error
);
734 goto ipsec_output_err
;
741 data
= ipsec6_splithdr(data
);
743 os_log_error(OS_LOG_DEFAULT
, "ipsec_encrypt_mbuf: ipsec6_splithdr returned NULL\n");
744 goto ipsec_output_err
;
747 struct ip6_hdr
*ip6
= mtod(data
, struct ip6_hdr
*);
749 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
750 ipsec_state
.m
= data
;
751 ipsec_state
.dst
= (struct sockaddr
*)&ip6
->ip6_dst
;
752 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
754 error
= ipsec6_interface_output(&ipsec_state
, interface
, &ip6
->ip6_nxt
, ipsec_state
.m
);
755 if (error
== 0 && ipsec_state
.tunneled
== 4) {
756 // Tunneled in IPv4 - packet is gone
757 // TODO: Don't lose mbuf
761 data
= ipsec_state
.m
;
762 if (error
|| data
== NULL
) {
764 os_log_error(OS_LOG_DEFAULT
, "ipsec_encrypt_mbuf: ipsec6_output error %d\n", error
);
766 goto ipsec_output_err
;
771 os_log_error(OS_LOG_DEFAULT
, "ipsec_encrypt_mbuf: Received unknown packet version %d\n", ip_version
);
773 goto ipsec_output_err
;
788 ipsec_kpipe_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
789 kern_channel_ring_t rx_ring
, uint32_t flags
)
791 #pragma unused(nxprov)
792 #pragma unused(flags)
793 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
794 struct kern_channel_ring_stat_increment rx_ring_stats
;
795 uint8_t ring_idx
= (uint8_t)(uintptr_t)kern_channel_ring_get_context(rx_ring
);
797 if (!ipsec_data_move_begin(pcb
)) {
798 os_log_error(OS_LOG_DEFAULT
, "%s: data path stopped for %s\n", __func__
, if_name(pcb
->ipsec_ifp
));
802 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
804 if (!ipsec_flag_isset(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
)) {
805 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
806 ipsec_data_move_end(pcb
);
810 VERIFY(pcb
->ipsec_kpipe_count
);
811 VERIFY(ring_idx
<= pcb
->ipsec_kpipe_count
);
813 // Reclaim user-released slots
814 (void) kern_channel_reclaim(rx_ring
);
816 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
818 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
819 os_log_error(OS_LOG_DEFAULT
, "%s: %s ring %s index %d no room in rx_ring\n", __func__
,
820 pcb
->ipsec_if_xname
, rx_ring
->ckr_name
, ring_idx
);
821 ipsec_data_move_end(pcb
);
825 kern_channel_ring_t tx_ring
= pcb
->ipsec_netif_txring
[ring_idx
];
826 if (tx_ring
== NULL
) {
827 // Net-If TX ring not set up yet, nothing to read
828 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
829 os_log_error(OS_LOG_DEFAULT
, "%s: %s ring %s index %d bad netif_txring 1\n", __func__
,
830 pcb
->ipsec_if_xname
, rx_ring
->ckr_name
, ring_idx
);
831 ipsec_data_move_end(pcb
);
835 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(pcb
->ipsec_netif_nexus
)->nif_stats
;
837 // Unlock ipsec before entering ring
838 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
840 (void)kr_enter(tx_ring
, TRUE
);
842 // Lock again after entering and validate
843 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
844 if (tx_ring
!= pcb
->ipsec_netif_txring
[ring_idx
]) {
845 // Ring no longer valid
846 // Unlock first, then exit ring
847 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
849 os_log_error(OS_LOG_DEFAULT
, "%s: %s ring %s index %d bad netif_txring 2\n", __func__
,
850 pcb
->ipsec_if_xname
, rx_ring
->ckr_name
, ring_idx
);
851 ipsec_data_move_end(pcb
);
855 struct kern_channel_ring_stat_increment tx_ring_stats
;
856 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
857 kern_channel_slot_t tx_pslot
= NULL
;
858 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
859 if (tx_slot
== NULL
) {
860 // Nothing to read, don't bother signalling
861 // Unlock first, then exit ring
862 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
864 ipsec_data_move_end(pcb
);
868 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
869 VERIFY(rx_pp
!= NULL
);
870 bzero(&rx_ring_stats
, sizeof(rx_ring_stats
));
871 kern_channel_slot_t rx_pslot
= NULL
;
872 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
874 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
879 // Allocate rx packet
880 kern_packet_t rx_ph
= 0;
881 error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
882 if (__improbable(error
!= 0)) {
883 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx %s: failed to allocate packet\n",
884 pcb
->ipsec_ifp
->if_xname
);
888 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
892 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
895 kern_pbufpool_free(rx_pp
, rx_ph
);
899 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
900 VERIFY(tx_buf
!= NULL
);
901 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
902 VERIFY(tx_baddr
!= NULL
);
903 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
905 bpf_tap_packet_out(pcb
->ipsec_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
907 length
= MIN(kern_packet_get_data_length(tx_ph
),
908 pcb
->ipsec_slot_size
);
910 // Increment TX stats
911 tx_ring_stats
.kcrsi_slots_transferred
++;
912 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
915 error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
917 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
919 // Encrypt and send packet
920 lck_mtx_lock(&pcb
->ipsec_kpipe_encrypt_lock
);
921 data
= ipsec_encrypt_mbuf(pcb
->ipsec_ifp
, data
);
922 lck_mtx_unlock(&pcb
->ipsec_kpipe_encrypt_lock
);
924 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx %s - mbuf_copyback(%zu) error %d\n", pcb
->ipsec_ifp
->if_xname
, length
, error
);
925 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
926 STATS_INC(nifs
, NETIF_STATS_DROP
);
931 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx %s - mbuf_gethdr error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
932 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
933 STATS_INC(nifs
, NETIF_STATS_DROP
);
936 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx %s - 0 length packet\n", pcb
->ipsec_ifp
->if_xname
);
937 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
938 STATS_INC(nifs
, NETIF_STATS_DROP
);
942 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx %s: no encrypted packet to send\n", pcb
->ipsec_ifp
->if_xname
);
943 kern_pbufpool_free(rx_pp
, rx_ph
);
947 length
= mbuf_pkthdr_len(data
);
948 if (length
> rx_pp
->pp_buflet_size
) {
951 kern_pbufpool_free(rx_pp
, rx_ph
);
952 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx %s: encrypted packet length %zu > %u\n",
953 pcb
->ipsec_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
958 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
959 VERIFY(rx_buf
!= NULL
);
960 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
961 VERIFY(rx_baddr
!= NULL
);
963 // Copy-in data from mbuf to buflet
964 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
965 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
967 // Finalize and attach the packet
968 error
= kern_buflet_set_data_offset(rx_buf
, 0);
970 error
= kern_buflet_set_data_length(rx_buf
, length
);
972 error
= kern_packet_finalize(rx_ph
);
974 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
977 STATS_INC(nifs
, NETIF_STATS_TX_PACKETS
);
978 STATS_INC(nifs
, NETIF_STATS_TX_COPY_DIRECT
);
980 rx_ring_stats
.kcrsi_slots_transferred
++;
981 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
983 if (!pcb
->ipsec_ext_ifdata_stats
) {
984 ifnet_stat_increment_out(pcb
->ipsec_ifp
, 1, length
, 0);
990 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
994 kern_channel_advance_slot(rx_ring
, rx_pslot
);
995 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->ipsec_ifp
, &rx_ring_stats
);
999 kern_channel_advance_slot(tx_ring
, tx_pslot
);
1000 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->ipsec_ifp
, &tx_ring_stats
);
1001 (void)kern_channel_reclaim(tx_ring
);
1004 /* always reenable output */
1005 errno_t error
= ifnet_enable_output(pcb
->ipsec_ifp
);
1007 os_log_error(OS_LOG_DEFAULT
, "ipsec_kpipe_sync_rx: ifnet_enable_output returned error %d\n", error
);
1010 // Unlock first, then exit ring
1011 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1013 if (tx_pslot
!= NULL
) {
1014 kern_channel_notify(tx_ring
, 0);
1018 ipsec_data_move_end(pcb
);
1023 ipsec_find_tx_ring_by_svc(kern_packet_svc_class_t svc_class
)
1025 switch (svc_class
) {
1046 ipsec_netif_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1047 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
1050 #pragma unused(nxprov)
1051 #pragma unused(channel)
1052 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1055 VERIFY(pcb
->ipsec_netif_rxring
[0] == NULL
);
1056 pcb
->ipsec_netif_rxring
[0] = ring
;
1058 uint8_t ring_idx
= 0;
1059 if (ipsec_in_wmm_mode(pcb
)) {
1061 kern_packet_svc_class_t svc_class
;
1062 err
= kern_channel_get_service_class(ring
, &svc_class
);
1064 ring_idx
= ipsec_find_tx_ring_by_svc(svc_class
);
1065 VERIFY(ring_idx
< IPSEC_IF_WMM_RING_COUNT
);
1068 *ring_ctx
= (void *)(uintptr_t)ring_idx
;
1070 VERIFY(pcb
->ipsec_netif_txring
[ring_idx
] == NULL
);
1071 pcb
->ipsec_netif_txring
[ring_idx
] = ring
;
1077 ipsec_netif_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1078 kern_channel_ring_t ring
)
1080 #pragma unused(nxprov)
1081 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1084 for (int i
= 0; i
< IPSEC_NETIF_MAX_RX_RING_COUNT
; i
++) {
1085 if (pcb
->ipsec_netif_rxring
[i
] == ring
) {
1086 pcb
->ipsec_netif_rxring
[i
] = NULL
;
1091 for (int i
= 0; i
< IPSEC_NETIF_MAX_TX_RING_COUNT
; i
++) {
1092 if (pcb
->ipsec_netif_txring
[i
] == ring
) {
1093 pcb
->ipsec_netif_txring
[i
] = NULL
;
1102 ipsec_netif_check_policy(mbuf_t data
)
1104 necp_kernel_policy_result necp_result
= 0;
1105 necp_kernel_policy_result_parameter necp_result_parameter
= {};
1106 uint32_t necp_matched_policy_id
= 0;
1108 // This packet has been marked with IP level policy, do not mark again.
1109 if (data
&& data
->m_pkthdr
.necp_mtag
.necp_policy_id
>= NECP_KERNEL_POLICY_ID_FIRST_VALID_IP
) {
1113 size_t length
= mbuf_pkthdr_len(data
);
1114 if (length
< sizeof(struct ip
)) {
1118 struct ip
*ip
= mtod(data
, struct ip
*);
1119 u_int ip_version
= ip
->ip_v
;
1120 switch (ip_version
) {
1122 necp_matched_policy_id
= necp_ip_output_find_policy_match(data
, 0, NULL
, NULL
,
1123 &necp_result
, &necp_result_parameter
);
1127 necp_matched_policy_id
= necp_ip6_output_find_policy_match(data
, 0, NULL
, NULL
,
1128 &necp_result
, &necp_result_parameter
);
1136 if (necp_result
== NECP_KERNEL_POLICY_RESULT_DROP
||
1137 necp_result
== NECP_KERNEL_POLICY_RESULT_SOCKET_DIVERT
) {
1138 /* Drop and flow divert packets should be blocked at the IP layer */
1142 necp_mark_packet_from_ip(data
, necp_matched_policy_id
);
1147 ipsec_netif_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1148 kern_channel_ring_t tx_ring
, uint32_t flags
)
1150 #pragma unused(nxprov)
1151 #pragma unused(flags)
1152 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1154 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
1156 if (!ipsec_data_move_begin(pcb
)) {
1157 os_log_error(OS_LOG_DEFAULT
, "%s: data path stopped for %s\n", __func__
, if_name(pcb
->ipsec_ifp
));
1161 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1163 struct kern_channel_ring_stat_increment tx_ring_stats
;
1164 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
1165 kern_channel_slot_t tx_pslot
= NULL
;
1166 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
1168 STATS_INC(nifs
, NETIF_STATS_TX_SYNC
);
1170 if (tx_slot
== NULL
) {
1171 // Nothing to write, don't bother signalling
1172 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1173 ipsec_data_move_end(pcb
);
1177 if (pcb
->ipsec_kpipe_count
&&
1178 ipsec_flag_isset(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
)) {
1179 // Select the corresponding kpipe rx ring
1180 uint8_t ring_idx
= (uint8_t)(uintptr_t)kern_channel_ring_get_context(tx_ring
);
1181 VERIFY(ring_idx
< IPSEC_IF_MAX_RING_COUNT
);
1182 kern_channel_ring_t rx_ring
= pcb
->ipsec_kpipe_rxring
[ring_idx
];
1184 // Unlock while calling notify
1185 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1187 // Signal the kernel pipe ring to read
1188 if (rx_ring
!= NULL
) {
1189 kern_channel_notify(rx_ring
, 0);
1192 ipsec_data_move_end(pcb
);
1196 // If we're here, we're injecting into the BSD stack
1197 while (tx_slot
!= NULL
) {
1201 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
1205 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
1211 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
1212 VERIFY(tx_buf
!= NULL
);
1213 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
1214 VERIFY(tx_baddr
!= 0);
1215 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
1217 bpf_tap_packet_out(pcb
->ipsec_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
1219 length
= MIN(kern_packet_get_data_length(tx_ph
),
1220 pcb
->ipsec_slot_size
);
1223 errno_t error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
1225 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
1227 // Mark packet from policy
1228 uint32_t policy_id
= kern_packet_get_policy_id(tx_ph
);
1229 necp_mark_packet_from_ip(data
, policy_id
);
1231 // Check policy with NECP
1232 if (!ipsec_netif_check_policy(data
)) {
1233 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_tx %s - failed policy check\n", pcb
->ipsec_ifp
->if_xname
);
1234 STATS_INC(nifs
, NETIF_STATS_DROP
);
1238 // Send through encryption
1239 error
= ipsec_output(pcb
->ipsec_ifp
, data
);
1241 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_tx %s - ipsec_output error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
1245 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_tx %s - mbuf_copyback(%zu) error %d\n", pcb
->ipsec_ifp
->if_xname
, length
, error
);
1246 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
1247 STATS_INC(nifs
, NETIF_STATS_DROP
);
1252 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_tx %s - mbuf_gethdr error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
1253 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
1254 STATS_INC(nifs
, NETIF_STATS_DROP
);
1257 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_tx %s - 0 length packet\n", pcb
->ipsec_ifp
->if_xname
);
1258 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1259 STATS_INC(nifs
, NETIF_STATS_DROP
);
1263 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_tx %s: no encrypted packet to send\n", pcb
->ipsec_ifp
->if_xname
);
1267 STATS_INC(nifs
, NETIF_STATS_TX_PACKETS
);
1268 STATS_INC(nifs
, NETIF_STATS_TX_COPY_MBUF
);
1270 tx_ring_stats
.kcrsi_slots_transferred
++;
1271 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1275 kern_channel_advance_slot(tx_ring
, tx_pslot
);
1276 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->ipsec_ifp
, &tx_ring_stats
);
1277 (void)kern_channel_reclaim(tx_ring
);
1280 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1281 ipsec_data_move_end(pcb
);
1287 ipsec_netif_tx_doorbell_one(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1288 kern_channel_ring_t ring
, uint32_t flags
, uint8_t ring_idx
)
1290 #pragma unused(nxprov)
1291 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1292 boolean_t more
= false;
1295 VERIFY((flags
& KERN_NEXUS_TXDOORBELLF_ASYNC_REFILL
) == 0);
1298 * Refill and sync the ring; we may be racing against another thread doing
1299 * an RX sync that also wants to do kr_enter(), and so use the blocking
1302 rc
= kern_channel_tx_refill_canblock(ring
, UINT32_MAX
, UINT32_MAX
, true, &more
);
1303 if (rc
!= 0 && rc
!= EAGAIN
&& rc
!= EBUSY
) {
1304 os_log_error(OS_LOG_DEFAULT
, "%s: %s ring %s tx refill failed %d\n", __func__
,
1305 pcb
->ipsec_if_xname
, ring
->ckr_name
, rc
);
1308 (void) kr_enter(ring
, TRUE
);
1309 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1310 if (ring
!= pcb
->ipsec_netif_txring
[ring_idx
]) {
1311 // ring no longer valid
1312 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1314 os_log_error(OS_LOG_DEFAULT
, "%s: %s ring %s index %d bad netif_txring 3\n", __func__
,
1315 pcb
->ipsec_if_xname
, ring
->ckr_name
, ring_idx
);
1319 if (pcb
->ipsec_kpipe_count
) {
1320 uint32_t tx_available
= kern_channel_available_slot_count(ring
);
1321 if (pcb
->ipsec_netif_txring_size
> 0 &&
1322 tx_available
>= pcb
->ipsec_netif_txring_size
- 1) {
1323 // No room left in tx ring, disable output for now
1324 errno_t error
= ifnet_disable_output(pcb
->ipsec_ifp
);
1326 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_tx_doorbell: ifnet_disable_output returned error %d\n", error
);
1331 if (pcb
->ipsec_kpipe_count
) {
1332 kern_channel_ring_t rx_ring
= pcb
->ipsec_kpipe_rxring
[ring_idx
];
1334 // Unlock while calling notify
1335 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1336 // Signal the kernel pipe ring to read
1337 if (rx_ring
!= NULL
) {
1338 kern_channel_notify(rx_ring
, 0);
1341 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1350 ipsec_netif_tx_doorbell(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1351 kern_channel_ring_t ring
, __unused
uint32_t flags
)
1354 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1356 if (!ipsec_data_move_begin(pcb
)) {
1357 os_log_error(OS_LOG_DEFAULT
, "%s: data path stopped for %s\n", __func__
, if_name(pcb
->ipsec_ifp
));
1361 if (ipsec_in_wmm_mode(pcb
)) {
1362 for (uint8_t i
= 0; i
< IPSEC_IF_WMM_RING_COUNT
; i
++) {
1363 kern_channel_ring_t nring
= pcb
->ipsec_netif_txring
[i
];
1364 ret
= ipsec_netif_tx_doorbell_one(nxprov
, nexus
, nring
, flags
, i
);
1370 ret
= ipsec_netif_tx_doorbell_one(nxprov
, nexus
, ring
, flags
, 0);
1373 ipsec_data_move_end(pcb
);
1378 ipsec_netif_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1379 kern_channel_ring_t rx_ring
, uint32_t flags
)
1381 #pragma unused(nxprov)
1382 #pragma unused(flags)
1383 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1384 struct kern_channel_ring_stat_increment rx_ring_stats
;
1386 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
1388 if (!ipsec_data_move_begin(pcb
)) {
1389 os_log_error(OS_LOG_DEFAULT
, "%s: data path stopped for %s\n", __func__
, if_name(pcb
->ipsec_ifp
));
1393 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1395 // Reclaim user-released slots
1396 (void) kern_channel_reclaim(rx_ring
);
1398 STATS_INC(nifs
, NETIF_STATS_RX_SYNC
);
1400 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
1402 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1403 ipsec_data_move_end(pcb
);
1407 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
1408 VERIFY(rx_pp
!= NULL
);
1409 bzero(&rx_ring_stats
, sizeof(rx_ring_stats
));
1410 kern_channel_slot_t rx_pslot
= NULL
;
1411 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
1413 while (rx_slot
!= NULL
) {
1414 // Check for a waiting packet
1415 lck_mtx_lock(&pcb
->ipsec_input_chain_lock
);
1416 mbuf_t data
= pcb
->ipsec_input_chain
;
1418 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1422 // Allocate rx packet
1423 kern_packet_t rx_ph
= 0;
1424 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
1425 if (__improbable(error
!= 0)) {
1426 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_PKT
);
1427 STATS_INC(nifs
, NETIF_STATS_DROP
);
1428 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1432 // Advance waiting packets
1433 if (pcb
->ipsec_input_chain_count
> 0) {
1434 pcb
->ipsec_input_chain_count
--;
1436 pcb
->ipsec_input_chain
= data
->m_nextpkt
;
1437 data
->m_nextpkt
= NULL
;
1438 if (pcb
->ipsec_input_chain
== NULL
) {
1439 pcb
->ipsec_input_chain_last
= NULL
;
1441 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1443 size_t length
= mbuf_pkthdr_len(data
);
1445 if (length
< sizeof(struct ip
)) {
1448 kern_pbufpool_free(rx_pp
, rx_ph
);
1449 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1450 STATS_INC(nifs
, NETIF_STATS_DROP
);
1451 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: legacy decrypted packet length cannot hold IP %zu < %zu\n",
1452 pcb
->ipsec_ifp
->if_xname
, length
, sizeof(struct ip
));
1457 struct ip
*ip
= mtod(data
, struct ip
*);
1458 u_int ip_version
= ip
->ip_v
;
1459 switch (ip_version
) {
1469 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: legacy unknown ip version %u\n",
1470 pcb
->ipsec_ifp
->if_xname
, ip_version
);
1475 if (length
> rx_pp
->pp_buflet_size
||
1476 (pcb
->ipsec_frag_size_set
&& length
> pcb
->ipsec_input_frag_size
)) {
1477 // We need to fragment to send up into the netif
1479 u_int32_t fragment_mtu
= rx_pp
->pp_buflet_size
;
1480 if (pcb
->ipsec_frag_size_set
&&
1481 pcb
->ipsec_input_frag_size
< rx_pp
->pp_buflet_size
) {
1482 fragment_mtu
= pcb
->ipsec_input_frag_size
;
1485 mbuf_t fragment_chain
= NULL
;
1488 // ip_fragment expects the length in host order
1489 ip
->ip_len
= ntohs(ip
->ip_len
);
1491 // ip_fragment will modify the original data, don't free
1492 int fragment_error
= ip_fragment(data
, pcb
->ipsec_ifp
, fragment_mtu
, TRUE
);
1493 if (fragment_error
== 0 && data
!= NULL
) {
1494 fragment_chain
= data
;
1496 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1497 STATS_INC(nifs
, NETIF_STATS_DROP
);
1498 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: failed to fragment IPv4 packet of length %zu (%d)\n",
1499 pcb
->ipsec_ifp
->if_xname
, length
, fragment_error
);
1504 if (length
< sizeof(struct ip6_hdr
)) {
1506 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1507 STATS_INC(nifs
, NETIF_STATS_DROP
);
1508 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: failed to fragment IPv6 packet of length %zu < %zu\n",
1509 pcb
->ipsec_ifp
->if_xname
, length
, sizeof(struct ip6_hdr
));
1511 // ip6_do_fragmentation will free the original data on success only
1512 struct ip6_hdr
*ip6
= mtod(data
, struct ip6_hdr
*);
1514 int fragment_error
= ip6_do_fragmentation(&data
, 0, pcb
->ipsec_ifp
, sizeof(struct ip6_hdr
),
1515 ip6
, NULL
, fragment_mtu
, ip6
->ip6_nxt
, htonl(ip6_randomid()));
1516 if (fragment_error
== 0 && data
!= NULL
) {
1517 fragment_chain
= data
;
1520 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1521 STATS_INC(nifs
, NETIF_STATS_DROP
);
1522 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: failed to fragment IPv6 packet of length %zu (%d)\n",
1523 pcb
->ipsec_ifp
->if_xname
, length
, fragment_error
);
1529 // Cannot fragment unknown families
1531 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1532 STATS_INC(nifs
, NETIF_STATS_DROP
);
1533 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: uknown legacy decrypted packet length %zu > %u\n",
1534 pcb
->ipsec_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
1539 if (fragment_chain
!= NULL
) {
1540 // Add fragments to chain before continuing
1541 lck_mtx_lock(&pcb
->ipsec_input_chain_lock
);
1542 if (pcb
->ipsec_input_chain
!= NULL
) {
1543 pcb
->ipsec_input_chain_last
->m_nextpkt
= fragment_chain
;
1545 pcb
->ipsec_input_chain
= fragment_chain
;
1547 pcb
->ipsec_input_chain_count
++;
1548 while (fragment_chain
->m_nextpkt
) {
1549 VERIFY(fragment_chain
!= fragment_chain
->m_nextpkt
);
1550 fragment_chain
= fragment_chain
->m_nextpkt
;
1551 pcb
->ipsec_input_chain_count
++;
1553 pcb
->ipsec_input_chain_last
= fragment_chain
;
1554 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1557 // Make sure to free unused rx packet
1558 kern_pbufpool_free(rx_pp
, rx_ph
);
1563 mbuf_pkthdr_setrcvif(data
, pcb
->ipsec_ifp
);
1565 // Fillout rx packet
1566 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
1567 VERIFY(rx_buf
!= NULL
);
1568 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
1569 VERIFY(rx_baddr
!= NULL
);
1571 // Copy-in data from mbuf to buflet
1572 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
1573 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
1575 // Finalize and attach the packet
1576 error
= kern_buflet_set_data_offset(rx_buf
, 0);
1578 error
= kern_buflet_set_data_length(rx_buf
, length
);
1580 error
= kern_packet_set_headroom(rx_ph
, 0);
1582 error
= kern_packet_finalize(rx_ph
);
1584 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
1587 STATS_INC(nifs
, NETIF_STATS_RX_PACKETS
);
1588 STATS_INC(nifs
, NETIF_STATS_RX_COPY_MBUF
);
1589 bpf_tap_packet_in(pcb
->ipsec_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
1591 rx_ring_stats
.kcrsi_slots_transferred
++;
1592 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1594 if (!pcb
->ipsec_ext_ifdata_stats
) {
1595 ifnet_stat_increment_in(pcb
->ipsec_ifp
, 1, length
, 0);
1602 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
1605 for (uint8_t ring_idx
= 0; ring_idx
< pcb
->ipsec_kpipe_count
; ring_idx
++) {
1606 struct kern_channel_ring_stat_increment tx_ring_stats
;
1607 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
1608 kern_channel_ring_t tx_ring
= pcb
->ipsec_kpipe_txring
[ring_idx
];
1609 kern_channel_slot_t tx_pslot
= NULL
;
1610 kern_channel_slot_t tx_slot
= NULL
;
1611 if (tx_ring
== NULL
) {
1612 // Net-If TX ring not set up yet, nothing to read
1617 // Unlock ipsec before entering ring
1618 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1620 (void)kr_enter(tx_ring
, TRUE
);
1622 // Lock again after entering and validate
1623 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1625 if (tx_ring
!= pcb
->ipsec_kpipe_txring
[ring_idx
]) {
1629 tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
1630 if (tx_slot
== NULL
) {
1631 // Nothing to read, don't bother signalling
1635 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
1641 // Allocate rx packet
1642 kern_packet_t rx_ph
= 0;
1643 error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
1644 if (__improbable(error
!= 0)) {
1645 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_PKT
);
1646 STATS_INC(nifs
, NETIF_STATS_DROP
);
1650 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
1654 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
1657 kern_pbufpool_free(rx_pp
, rx_ph
);
1661 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
1662 VERIFY(tx_buf
!= NULL
);
1663 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
1664 VERIFY(tx_baddr
!= 0);
1665 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
1667 length
= MIN(kern_packet_get_data_length(tx_ph
),
1668 pcb
->ipsec_slot_size
);
1670 // Increment TX stats
1671 tx_ring_stats
.kcrsi_slots_transferred
++;
1672 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1674 if (length
>= sizeof(struct ip
)) {
1675 error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
1677 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
1679 lck_mtx_lock(&pcb
->ipsec_kpipe_decrypt_lock
);
1680 struct ip
*ip
= mtod(data
, struct ip
*);
1681 u_int ip_version
= ip
->ip_v
;
1682 switch (ip_version
) {
1685 ip
->ip_len
= ntohs(ip
->ip_len
) - sizeof(struct ip
);
1686 ip
->ip_off
= ntohs(ip
->ip_off
);
1688 if (length
< ip
->ip_len
) {
1689 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: IPv4 packet length too short (%zu < %u)\n",
1690 pcb
->ipsec_ifp
->if_xname
, length
, ip
->ip_len
);
1691 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1692 STATS_INC(nifs
, NETIF_STATS_DROP
);
1696 data
= esp4_input_extended(data
, sizeof(struct ip
), pcb
->ipsec_ifp
);
1701 if (length
< sizeof(struct ip6_hdr
)) {
1702 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: IPv6 packet length too short for header %zu\n",
1703 pcb
->ipsec_ifp
->if_xname
, length
);
1704 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1705 STATS_INC(nifs
, NETIF_STATS_DROP
);
1710 struct ip6_hdr
*ip6
= mtod(data
, struct ip6_hdr
*);
1711 const size_t ip6_len
= sizeof(*ip6
) + ntohs(ip6
->ip6_plen
);
1712 if (length
< ip6_len
) {
1713 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: IPv6 packet length too short (%zu < %zu)\n",
1714 pcb
->ipsec_ifp
->if_xname
, length
, ip6_len
);
1715 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1716 STATS_INC(nifs
, NETIF_STATS_DROP
);
1720 int offset
= sizeof(struct ip6_hdr
);
1721 esp6_input_extended(&data
, &offset
, ip6
->ip6_nxt
, pcb
->ipsec_ifp
);
1727 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: unknown ip version %u\n",
1728 pcb
->ipsec_ifp
->if_xname
, ip_version
);
1729 STATS_INC(nifs
, NETIF_STATS_DROP
);
1735 lck_mtx_unlock(&pcb
->ipsec_kpipe_decrypt_lock
);
1737 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s - mbuf_copyback(%zu) error %d\n", pcb
->ipsec_ifp
->if_xname
, length
, error
);
1738 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
1739 STATS_INC(nifs
, NETIF_STATS_DROP
);
1744 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s - mbuf_gethdr error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
1745 STATS_INC(nifs
, NETIF_STATS_DROP_NOMEM_MBUF
);
1746 STATS_INC(nifs
, NETIF_STATS_DROP
);
1749 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s - bad packet length %zu\n", pcb
->ipsec_ifp
->if_xname
, length
);
1750 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1751 STATS_INC(nifs
, NETIF_STATS_DROP
);
1755 // Failed to get decrypted data data
1756 kern_pbufpool_free(rx_pp
, rx_ph
);
1760 length
= mbuf_pkthdr_len(data
);
1761 if (length
> rx_pp
->pp_buflet_size
) {
1764 kern_pbufpool_free(rx_pp
, rx_ph
);
1765 STATS_INC(nifs
, NETIF_STATS_DROP_BADLEN
);
1766 STATS_INC(nifs
, NETIF_STATS_DROP
);
1767 os_log_error(OS_LOG_DEFAULT
, "ipsec_netif_sync_rx %s: decrypted packet length %zu > %u\n",
1768 pcb
->ipsec_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
1772 mbuf_pkthdr_setrcvif(data
, pcb
->ipsec_ifp
);
1774 // Fillout rx packet
1775 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
1776 VERIFY(rx_buf
!= NULL
);
1777 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
1778 VERIFY(rx_baddr
!= NULL
);
1780 // Copy-in data from mbuf to buflet
1781 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
1782 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
1784 // Finalize and attach the packet
1785 error
= kern_buflet_set_data_offset(rx_buf
, 0);
1787 error
= kern_buflet_set_data_length(rx_buf
, length
);
1789 error
= kern_packet_set_link_header_offset(rx_ph
, 0);
1791 error
= kern_packet_set_network_header_offset(rx_ph
, 0);
1793 error
= kern_packet_finalize(rx_ph
);
1795 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
1798 STATS_INC(nifs
, NETIF_STATS_RX_PACKETS
);
1799 STATS_INC(nifs
, NETIF_STATS_RX_COPY_DIRECT
);
1800 bpf_tap_packet_in(pcb
->ipsec_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
1802 rx_ring_stats
.kcrsi_slots_transferred
++;
1803 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1805 if (!pcb
->ipsec_ext_ifdata_stats
) {
1806 ifnet_stat_increment_in(pcb
->ipsec_ifp
, 1, length
, 0);
1812 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
1817 kern_channel_advance_slot(tx_ring
, tx_pslot
);
1818 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->ipsec_ifp
, &tx_ring_stats
);
1819 (void)kern_channel_reclaim(tx_ring
);
1822 // Unlock first, then exit ring
1823 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1824 if (tx_ring
!= NULL
) {
1825 if (tx_pslot
!= NULL
) {
1826 kern_channel_notify(tx_ring
, 0);
1831 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1835 kern_channel_advance_slot(rx_ring
, rx_pslot
);
1836 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->ipsec_ifp
, &rx_ring_stats
);
1840 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1842 ipsec_data_move_end(pcb
);
1847 ipsec_nexus_ifattach(struct ipsec_pcb
*pcb
,
1848 struct ifnet_init_eparams
*init_params
,
1852 nexus_controller_t controller
= kern_nexus_shared_controller();
1853 struct kern_nexus_net_init net_init
;
1854 struct kern_pbufpool_init pp_init
;
1856 nexus_name_t provider_name
;
1857 snprintf((char *)provider_name
, sizeof(provider_name
),
1858 "com.apple.netif.%s", pcb
->ipsec_if_xname
);
1860 struct kern_nexus_provider_init prov_init
= {
1861 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
1862 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
1863 .nxpi_pre_connect
= ipsec_nexus_pre_connect
,
1864 .nxpi_connected
= ipsec_nexus_connected
,
1865 .nxpi_pre_disconnect
= ipsec_netif_pre_disconnect
,
1866 .nxpi_disconnected
= ipsec_nexus_disconnected
,
1867 .nxpi_ring_init
= ipsec_netif_ring_init
,
1868 .nxpi_ring_fini
= ipsec_netif_ring_fini
,
1869 .nxpi_slot_init
= NULL
,
1870 .nxpi_slot_fini
= NULL
,
1871 .nxpi_sync_tx
= ipsec_netif_sync_tx
,
1872 .nxpi_sync_rx
= ipsec_netif_sync_rx
,
1873 .nxpi_tx_doorbell
= ipsec_netif_tx_doorbell
,
1876 nexus_attr_t nxa
= NULL
;
1877 err
= kern_nexus_attr_create(&nxa
);
1878 IPSEC_IF_VERIFY(err
== 0);
1880 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_attr_create failed: %d\n",
1885 uint64_t slot_buffer_size
= pcb
->ipsec_slot_size
;
1886 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1889 // Reset ring size for netif nexus to limit memory usage
1890 uint64_t ring_size
= pcb
->ipsec_netif_ring_size
;
1891 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
1893 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
1898 if (ipsec_in_wmm_mode(pcb
)) {
1899 os_log(OS_LOG_DEFAULT
, "%s: %s enabling wmm mode\n",
1900 __func__
, pcb
->ipsec_if_xname
);
1902 init_params
->output_sched_model
= IFNET_SCHED_MODEL_DRIVER_MANAGED
;
1904 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_RINGS
,
1905 IPSEC_NETIF_WMM_TX_RING_COUNT
);
1907 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_RINGS
,
1908 IPSEC_NETIF_WMM_RX_RING_COUNT
);
1911 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_QMAP
, NEXUS_QMAP_TYPE_WMM
);
1915 pcb
->ipsec_netif_txring_size
= ring_size
;
1917 bzero(&pp_init
, sizeof(pp_init
));
1918 pp_init
.kbi_version
= KERN_PBUFPOOL_CURRENT_VERSION
;
1919 pp_init
.kbi_flags
|= KBIF_VIRTUAL_DEVICE
;
1920 // Note: we need more packets than can be held in the tx and rx rings because
1921 // packets can also be in the AQM queue(s)
1922 pp_init
.kbi_packets
= pcb
->ipsec_netif_ring_size
* (2 * pcb
->ipsec_kpipe_count
+ 1);
1923 pp_init
.kbi_bufsize
= pcb
->ipsec_slot_size
;
1924 pp_init
.kbi_buf_seg_size
= IPSEC_IF_DEFAULT_BUF_SEG_SIZE
;
1925 pp_init
.kbi_max_frags
= 1;
1926 (void) snprintf((char *)pp_init
.kbi_name
, sizeof(pp_init
.kbi_name
),
1927 "%s", provider_name
);
1928 pp_init
.kbi_ctx
= NULL
;
1929 pp_init
.kbi_ctx_retain
= NULL
;
1930 pp_init
.kbi_ctx_release
= NULL
;
1932 err
= kern_pbufpool_create(&pp_init
, &pcb
->ipsec_netif_pp
, NULL
);
1934 os_log_error(OS_LOG_DEFAULT
, "%s pbufbool create failed, error %d\n", __func__
, err
);
1938 err
= kern_nexus_controller_register_provider(controller
,
1944 &pcb
->ipsec_nx
.if_provider
);
1945 IPSEC_IF_VERIFY(err
== 0);
1947 os_log_error(OS_LOG_DEFAULT
, "%s register provider failed, error %d\n",
1952 bzero(&net_init
, sizeof(net_init
));
1953 net_init
.nxneti_version
= KERN_NEXUS_NET_CURRENT_VERSION
;
1954 net_init
.nxneti_flags
= 0;
1955 net_init
.nxneti_eparams
= init_params
;
1956 net_init
.nxneti_lladdr
= NULL
;
1957 net_init
.nxneti_prepare
= ipsec_netif_prepare
;
1958 net_init
.nxneti_tx_pbufpool
= pcb
->ipsec_netif_pp
;
1959 err
= kern_nexus_controller_alloc_net_provider_instance(controller
,
1960 pcb
->ipsec_nx
.if_provider
,
1962 &pcb
->ipsec_nx
.if_instance
,
1965 IPSEC_IF_VERIFY(err
== 0);
1967 os_log_error(OS_LOG_DEFAULT
, "%s alloc_net_provider_instance failed, %d\n",
1969 kern_nexus_controller_deregister_provider(controller
,
1970 pcb
->ipsec_nx
.if_provider
);
1971 uuid_clear(pcb
->ipsec_nx
.if_provider
);
1977 kern_nexus_attr_destroy(nxa
);
1979 if (err
&& pcb
->ipsec_netif_pp
!= NULL
) {
1980 kern_pbufpool_destroy(pcb
->ipsec_netif_pp
);
1981 pcb
->ipsec_netif_pp
= NULL
;
1987 ipsec_detach_provider_and_instance(uuid_t provider
, uuid_t instance
)
1989 nexus_controller_t controller
= kern_nexus_shared_controller();
1992 if (!uuid_is_null(instance
)) {
1993 err
= kern_nexus_controller_free_provider_instance(controller
,
1996 os_log_error(OS_LOG_DEFAULT
, "%s free_provider_instance failed %d\n",
1999 uuid_clear(instance
);
2001 if (!uuid_is_null(provider
)) {
2002 err
= kern_nexus_controller_deregister_provider(controller
,
2005 os_log_error(OS_LOG_DEFAULT
, "%s deregister_provider %d\n", __func__
, err
);
2007 uuid_clear(provider
);
2013 ipsec_nexus_detach(struct ipsec_pcb
*pcb
)
2015 ipsec_nx_t nx
= &pcb
->ipsec_nx
;
2016 nexus_controller_t controller
= kern_nexus_shared_controller();
2019 if (!uuid_is_null(nx
->fsw_host
)) {
2020 err
= kern_nexus_ifdetach(controller
,
2024 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_ifdetach ms host failed %d\n",
2029 if (!uuid_is_null(nx
->fsw_device
)) {
2030 err
= kern_nexus_ifdetach(controller
,
2034 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_ifdetach ms device failed %d\n",
2039 ipsec_detach_provider_and_instance(nx
->if_provider
,
2041 ipsec_detach_provider_and_instance(nx
->fsw_provider
,
2044 if (pcb
->ipsec_netif_pp
!= NULL
) {
2045 kern_pbufpool_destroy(pcb
->ipsec_netif_pp
);
2046 pcb
->ipsec_netif_pp
= NULL
;
2048 memset(nx
, 0, sizeof(*nx
));
2052 ipsec_create_fs_provider_and_instance(struct ipsec_pcb
*pcb
,
2053 const char *type_name
,
2055 uuid_t
*provider
, uuid_t
*instance
)
2057 nexus_attr_t attr
= NULL
;
2058 nexus_controller_t controller
= kern_nexus_shared_controller();
2061 struct kern_nexus_init init
;
2062 nexus_name_t provider_name
;
2064 err
= kern_nexus_get_default_domain_provider(NEXUS_TYPE_FLOW_SWITCH
,
2066 IPSEC_IF_VERIFY(err
== 0);
2068 os_log_error(OS_LOG_DEFAULT
, "%s can't get %s provider, error %d\n",
2069 __func__
, type_name
, err
);
2073 err
= kern_nexus_attr_create(&attr
);
2074 IPSEC_IF_VERIFY(err
== 0);
2076 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_attr_create failed: %d\n",
2081 uint64_t slot_buffer_size
= pcb
->ipsec_slot_size
;
2082 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
2085 // Reset ring size for flowswitch nexus to limit memory usage. Larger RX than netif.
2086 uint64_t tx_ring_size
= pcb
->ipsec_tx_fsw_ring_size
;
2087 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_TX_SLOTS
, tx_ring_size
);
2089 uint64_t rx_ring_size
= pcb
->ipsec_rx_fsw_ring_size
;
2090 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_RX_SLOTS
, rx_ring_size
);
2093 snprintf((char *)provider_name
, sizeof(provider_name
),
2094 "com.apple.%s.%s", type_name
, ifname
);
2095 err
= kern_nexus_controller_register_provider(controller
,
2102 kern_nexus_attr_destroy(attr
);
2104 IPSEC_IF_VERIFY(err
== 0);
2106 os_log_error(OS_LOG_DEFAULT
, "%s register %s provider failed, error %d\n",
2107 __func__
, type_name
, err
);
2110 bzero(&init
, sizeof(init
));
2111 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
2112 err
= kern_nexus_controller_alloc_provider_instance(controller
,
2116 IPSEC_IF_VERIFY(err
== 0);
2118 os_log_error(OS_LOG_DEFAULT
, "%s alloc_provider_instance %s failed, %d\n",
2119 __func__
, type_name
, err
);
2120 kern_nexus_controller_deregister_provider(controller
,
2122 uuid_clear(*provider
);
2129 ipsec_flowswitch_attach(struct ipsec_pcb
*pcb
)
2131 nexus_controller_t controller
= kern_nexus_shared_controller();
2133 ipsec_nx_t nx
= &pcb
->ipsec_nx
;
2135 // Allocate flowswitch
2136 err
= ipsec_create_fs_provider_and_instance(pcb
,
2138 pcb
->ipsec_ifp
->if_xname
,
2142 os_log_error(OS_LOG_DEFAULT
, "%s: failed to create bridge provider and instance\n",
2147 // Attach flowswitch to device port
2148 err
= kern_nexus_ifattach(controller
, nx
->fsw_instance
,
2149 NULL
, nx
->if_instance
,
2150 FALSE
, &nx
->fsw_device
);
2152 os_log_error(OS_LOG_DEFAULT
, "%s kern_nexus_ifattach ms device %d\n", __func__
, err
);
2156 // Attach flowswitch to host port
2157 err
= kern_nexus_ifattach(controller
, nx
->fsw_instance
,
2158 NULL
, nx
->if_instance
,
2159 TRUE
, &nx
->fsw_host
);
2161 os_log_error(OS_LOG_DEFAULT
, "%s kern_nexus_ifattach ms host %d\n", __func__
, err
);
2165 // Extract the agent UUID and save for later
2166 struct kern_nexus
*flowswitch_nx
= nx_find(nx
->fsw_instance
, false);
2167 if (flowswitch_nx
!= NULL
) {
2168 struct nx_flowswitch
*flowswitch
= NX_FSW_PRIVATE(flowswitch_nx
);
2169 if (flowswitch
!= NULL
) {
2170 FSW_RLOCK(flowswitch
);
2171 uuid_copy(nx
->fsw_agent
, flowswitch
->fsw_agent_uuid
);
2172 FSW_UNLOCK(flowswitch
);
2174 os_log_error(OS_LOG_DEFAULT
, "ipsec_flowswitch_attach - flowswitch is NULL\n");
2176 nx_release(flowswitch_nx
);
2178 os_log_error(OS_LOG_DEFAULT
, "ipsec_flowswitch_attach - unable to find flowswitch nexus\n");
2184 ipsec_nexus_detach(pcb
);
2186 errno_t detach_error
= 0;
2187 if ((detach_error
= ifnet_detach(pcb
->ipsec_ifp
)) != 0) {
2188 panic("ipsec_flowswitch_attach - ifnet_detach failed: %d\n", detach_error
);
2195 #pragma mark Kernel Pipe Nexus
2198 ipsec_register_kernel_pipe_nexus(struct ipsec_pcb
*pcb
)
2200 nexus_attr_t nxa
= NULL
;
2203 lck_mtx_lock(&ipsec_lock
);
2204 if (ipsec_ncd_refcount
++) {
2205 lck_mtx_unlock(&ipsec_lock
);
2209 result
= kern_nexus_controller_create(&ipsec_ncd
);
2211 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_controller_create failed: %d\n",
2212 __FUNCTION__
, result
);
2217 result
= kern_nexus_get_default_domain_provider(
2218 NEXUS_TYPE_KERNEL_PIPE
, &dom_prov
);
2220 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_get_default_domain_provider failed: %d\n",
2221 __FUNCTION__
, result
);
2225 struct kern_nexus_provider_init prov_init
= {
2226 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
2227 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
2228 .nxpi_pre_connect
= ipsec_nexus_pre_connect
,
2229 .nxpi_connected
= ipsec_nexus_connected
,
2230 .nxpi_pre_disconnect
= ipsec_nexus_pre_disconnect
,
2231 .nxpi_disconnected
= ipsec_nexus_disconnected
,
2232 .nxpi_ring_init
= ipsec_kpipe_ring_init
,
2233 .nxpi_ring_fini
= ipsec_kpipe_ring_fini
,
2234 .nxpi_slot_init
= NULL
,
2235 .nxpi_slot_fini
= NULL
,
2236 .nxpi_sync_tx
= ipsec_kpipe_sync_tx
,
2237 .nxpi_sync_rx
= ipsec_kpipe_sync_rx
,
2238 .nxpi_tx_doorbell
= NULL
,
2241 result
= kern_nexus_attr_create(&nxa
);
2243 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_attr_create failed: %d\n",
2244 __FUNCTION__
, result
);
2248 uint64_t slot_buffer_size
= IPSEC_IF_DEFAULT_SLOT_SIZE
;
2249 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
2250 VERIFY(result
== 0);
2252 // Reset ring size for kernel pipe nexus to limit memory usage
2253 // Note: It's better to have less on slots on the kpipe TX ring than the netif
2254 // so back pressure is applied at the AQM layer
2255 uint64_t ring_size
=
2256 pcb
->ipsec_kpipe_tx_ring_size
!= 0 ? pcb
->ipsec_kpipe_tx_ring_size
:
2257 pcb
->ipsec_netif_ring_size
!= 0 ? pcb
->ipsec_netif_ring_size
:
2259 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
2260 VERIFY(result
== 0);
2263 pcb
->ipsec_kpipe_rx_ring_size
!= 0 ? pcb
->ipsec_kpipe_rx_ring_size
:
2264 pcb
->ipsec_netif_ring_size
!= 0 ? pcb
->ipsec_netif_ring_size
:
2266 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
2267 VERIFY(result
== 0);
2269 result
= kern_nexus_controller_register_provider(ipsec_ncd
,
2271 (const uint8_t *)"com.apple.nexus.ipsec.kpipe",
2277 os_log_error(OS_LOG_DEFAULT
, "%s: kern_nexus_controller_register_provider failed: %d\n",
2278 __FUNCTION__
, result
);
2284 kern_nexus_attr_destroy(nxa
);
2289 kern_nexus_controller_destroy(ipsec_ncd
);
2292 ipsec_ncd_refcount
= 0;
2295 lck_mtx_unlock(&ipsec_lock
);
2301 ipsec_unregister_kernel_pipe_nexus(void)
2303 lck_mtx_lock(&ipsec_lock
);
2305 VERIFY(ipsec_ncd_refcount
> 0);
2307 if (--ipsec_ncd_refcount
== 0) {
2308 kern_nexus_controller_destroy(ipsec_ncd
);
2312 lck_mtx_unlock(&ipsec_lock
);
2315 /* This structure only holds onto kpipe channels that need to be
2316 * freed in the future, but are cleared from the pcb under lock
2318 struct ipsec_detached_channels
{
2321 uuid_t uuids
[IPSEC_IF_MAX_RING_COUNT
];
2325 ipsec_detach_channels(struct ipsec_pcb
*pcb
, struct ipsec_detached_channels
*dc
)
2327 LCK_RW_ASSERT(&pcb
->ipsec_pcb_lock
, LCK_RW_TYPE_EXCLUSIVE
);
2329 if (!ipsec_flag_isset(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
)) {
2330 for (int i
= 0; i
< IPSEC_IF_MAX_RING_COUNT
; i
++) {
2331 VERIFY(uuid_is_null(pcb
->ipsec_kpipe_uuid
[i
]));
2337 dc
->count
= pcb
->ipsec_kpipe_count
;
2339 VERIFY(dc
->count
>= 0);
2340 VERIFY(dc
->count
<= IPSEC_IF_MAX_RING_COUNT
);
2342 for (int i
= 0; i
< dc
->count
; i
++) {
2343 VERIFY(!uuid_is_null(pcb
->ipsec_kpipe_uuid
[i
]));
2344 uuid_copy(dc
->uuids
[i
], pcb
->ipsec_kpipe_uuid
[i
]);
2345 uuid_clear(pcb
->ipsec_kpipe_uuid
[i
]);
2347 for (int i
= dc
->count
; i
< IPSEC_IF_MAX_RING_COUNT
; i
++) {
2348 VERIFY(uuid_is_null(pcb
->ipsec_kpipe_uuid
[i
]));
2352 VERIFY(pcb
->ipsec_kpipe_pp
);
2354 VERIFY(!pcb
->ipsec_kpipe_pp
);
2357 dc
->pp
= pcb
->ipsec_kpipe_pp
;
2359 pcb
->ipsec_kpipe_pp
= NULL
;
2361 ipsec_flag_clr(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
);
2365 ipsec_free_channels(struct ipsec_detached_channels
*dc
)
2371 for (int i
= 0; i
< dc
->count
; i
++) {
2373 result
= kern_nexus_controller_free_provider_instance(ipsec_ncd
, dc
->uuids
[i
]);
2378 kern_pbufpool_destroy(dc
->pp
);
2380 ipsec_unregister_kernel_pipe_nexus();
2382 memset(dc
, 0, sizeof(*dc
));
2386 ipsec_enable_channel(struct ipsec_pcb
*pcb
, struct proc
*proc
)
2388 struct kern_nexus_init init
;
2389 struct kern_pbufpool_init pp_init
;
2392 kauth_cred_t cred
= kauth_cred_get();
2393 result
= priv_check_cred(cred
, PRIV_SKYWALK_REGISTER_KERNEL_PIPE
, 0);
2398 VERIFY(pcb
->ipsec_kpipe_count
);
2399 VERIFY(!ipsec_flag_isset(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
));
2401 result
= ipsec_register_kernel_pipe_nexus(pcb
);
2403 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
2406 os_log_error(OS_LOG_DEFAULT
, "%s: %s failed to register kernel pipe nexus\n",
2407 __func__
, pcb
->ipsec_if_xname
);
2413 bzero(&pp_init
, sizeof(pp_init
));
2414 pp_init
.kbi_version
= KERN_PBUFPOOL_CURRENT_VERSION
;
2415 pp_init
.kbi_flags
|= KBIF_VIRTUAL_DEVICE
;
2416 // Note: We only needs are many packets as can be held in the tx and rx rings
2417 pp_init
.kbi_packets
= pcb
->ipsec_netif_ring_size
* 2 * pcb
->ipsec_kpipe_count
;
2418 pp_init
.kbi_bufsize
= pcb
->ipsec_slot_size
;
2419 pp_init
.kbi_buf_seg_size
= IPSEC_IF_DEFAULT_BUF_SEG_SIZE
;
2420 pp_init
.kbi_max_frags
= 1;
2421 pp_init
.kbi_flags
|= KBIF_QUANTUM
;
2422 (void) snprintf((char *)pp_init
.kbi_name
, sizeof(pp_init
.kbi_name
),
2423 "com.apple.kpipe.%s", pcb
->ipsec_if_xname
);
2424 pp_init
.kbi_ctx
= NULL
;
2425 pp_init
.kbi_ctx_retain
= NULL
;
2426 pp_init
.kbi_ctx_release
= NULL
;
2428 result
= kern_pbufpool_create(&pp_init
, &pcb
->ipsec_kpipe_pp
,
2431 os_log_error(OS_LOG_DEFAULT
, "%s: %s pbufbool create failed, error %d\n",
2432 __func__
, pcb
->ipsec_if_xname
, result
);
2436 bzero(&init
, sizeof(init
));
2437 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
2438 init
.nxi_tx_pbufpool
= pcb
->ipsec_kpipe_pp
;
2440 for (unsigned int i
= 0; i
< pcb
->ipsec_kpipe_count
; i
++) {
2441 VERIFY(uuid_is_null(pcb
->ipsec_kpipe_uuid
[i
]));
2442 result
= kern_nexus_controller_alloc_provider_instance(ipsec_ncd
,
2443 ipsec_kpipe_uuid
, pcb
, &pcb
->ipsec_kpipe_uuid
[i
], &init
);
2446 nexus_port_t port
= NEXUS_PORT_KERNEL_PIPE_CLIENT
;
2447 pid_t pid
= pcb
->ipsec_kpipe_pid
;
2449 pid
= proc_pid(proc
);
2451 result
= kern_nexus_controller_bind_provider_instance(ipsec_ncd
,
2452 pcb
->ipsec_kpipe_uuid
[i
], &port
,
2453 pid
, NULL
, NULL
, 0, NEXUS_BIND_PID
);
2457 /* Unwind all of them on error */
2458 for (int j
= 0; j
< IPSEC_IF_MAX_RING_COUNT
; j
++) {
2459 if (!uuid_is_null(pcb
->ipsec_kpipe_uuid
[j
])) {
2460 kern_nexus_controller_free_provider_instance(ipsec_ncd
,
2461 pcb
->ipsec_kpipe_uuid
[j
]);
2462 uuid_clear(pcb
->ipsec_kpipe_uuid
[j
]);
2470 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2473 if (pcb
->ipsec_kpipe_pp
!= NULL
) {
2474 kern_pbufpool_destroy(pcb
->ipsec_kpipe_pp
);
2475 pcb
->ipsec_kpipe_pp
= NULL
;
2477 ipsec_unregister_kernel_pipe_nexus();
2479 ipsec_flag_set(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
);
2485 #endif // IPSEC_NEXUS
2488 /* Kernel control functions */
2491 ipsec_free_pcb(struct ipsec_pcb
*pcb
, bool in_list
)
2494 mbuf_freem_list(pcb
->ipsec_input_chain
);
2495 pcb
->ipsec_input_chain_count
= 0;
2496 lck_mtx_destroy(&pcb
->ipsec_input_chain_lock
, ipsec_lck_grp
);
2497 lck_mtx_destroy(&pcb
->ipsec_kpipe_encrypt_lock
, ipsec_lck_grp
);
2498 lck_mtx_destroy(&pcb
->ipsec_kpipe_decrypt_lock
, ipsec_lck_grp
);
2499 #endif // IPSEC_NEXUS
2500 lck_mtx_destroy(&pcb
->ipsec_pcb_data_move_lock
, ipsec_lck_grp
);
2501 lck_rw_destroy(&pcb
->ipsec_pcb_lock
, ipsec_lck_grp
);
2503 lck_mtx_lock(&ipsec_lock
);
2504 TAILQ_REMOVE(&ipsec_head
, pcb
, ipsec_chain
);
2505 lck_mtx_unlock(&ipsec_lock
);
2507 zfree(ipsec_pcb_zone
, pcb
);
2511 ipsec_ctl_bind(kern_ctl_ref kctlref
,
2512 struct sockaddr_ctl
*sac
,
2515 struct ipsec_pcb
*pcb
= zalloc(ipsec_pcb_zone
);
2516 memset(pcb
, 0, sizeof(*pcb
));
2518 /* Setup the protocol control block */
2520 pcb
->ipsec_ctlref
= kctlref
;
2521 pcb
->ipsec_unit
= sac
->sc_unit
;
2522 pcb
->ipsec_output_service_class
= MBUF_SC_OAM
;
2525 pcb
->ipsec_use_netif
= false;
2526 pcb
->ipsec_slot_size
= IPSEC_IF_DEFAULT_SLOT_SIZE
;
2527 pcb
->ipsec_netif_ring_size
= if_ipsec_ring_size
;
2528 pcb
->ipsec_tx_fsw_ring_size
= if_ipsec_tx_fsw_ring_size
;
2529 pcb
->ipsec_rx_fsw_ring_size
= if_ipsec_rx_fsw_ring_size
;
2530 #endif // IPSEC_NEXUS
2532 lck_rw_init(&pcb
->ipsec_pcb_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2533 lck_mtx_init(&pcb
->ipsec_pcb_data_move_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2535 pcb
->ipsec_input_chain_count
= 0;
2536 lck_mtx_init(&pcb
->ipsec_input_chain_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2537 lck_mtx_init(&pcb
->ipsec_kpipe_encrypt_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2538 lck_mtx_init(&pcb
->ipsec_kpipe_decrypt_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2539 #endif // IPSEC_NEXUS
2545 ipsec_ctl_connect(kern_ctl_ref kctlref
,
2546 struct sockaddr_ctl
*sac
,
2549 struct ifnet_init_eparams ipsec_init
= {};
2552 if (*unitinfo
== NULL
) {
2553 (void)ipsec_ctl_bind(kctlref
, sac
, unitinfo
);
2556 struct ipsec_pcb
*pcb
= *unitinfo
;
2561 lck_mtx_lock(&ipsec_lock
);
2563 /* Find some open interface id */
2564 u_int32_t chosen_unique_id
= 1;
2565 struct ipsec_pcb
*next_pcb
= TAILQ_LAST(&ipsec_head
, ipsec_list
);
2566 if (next_pcb
!= NULL
) {
2567 /* List was not empty, add one to the last item */
2568 chosen_unique_id
= next_pcb
->ipsec_unique_id
+ 1;
2572 * If this wrapped the id number, start looking at
2573 * the front of the list for an unused id.
2575 if (chosen_unique_id
== 0) {
2576 /* Find the next unused ID */
2577 chosen_unique_id
= 1;
2578 TAILQ_FOREACH(next_pcb
, &ipsec_head
, ipsec_chain
) {
2579 if (next_pcb
->ipsec_unique_id
> chosen_unique_id
) {
2580 /* We found a gap */
2584 chosen_unique_id
= next_pcb
->ipsec_unique_id
+ 1;
2589 pcb
->ipsec_unique_id
= chosen_unique_id
;
2591 if (next_pcb
!= NULL
) {
2592 TAILQ_INSERT_BEFORE(next_pcb
, pcb
, ipsec_chain
);
2594 TAILQ_INSERT_TAIL(&ipsec_head
, pcb
, ipsec_chain
);
2596 lck_mtx_unlock(&ipsec_lock
);
2598 snprintf(pcb
->ipsec_if_xname
, sizeof(pcb
->ipsec_if_xname
), "ipsec%d", pcb
->ipsec_unit
- 1);
2599 snprintf(pcb
->ipsec_unique_name
, sizeof(pcb
->ipsec_unique_name
), "ipsecid%d", pcb
->ipsec_unique_id
- 1);
2600 os_log(OS_LOG_DEFAULT
, "ipsec_ctl_connect: creating interface %s (id %s)\n", pcb
->ipsec_if_xname
, pcb
->ipsec_unique_name
);
2602 /* Create the interface */
2603 bzero(&ipsec_init
, sizeof(ipsec_init
));
2604 ipsec_init
.ver
= IFNET_INIT_CURRENT_VERSION
;
2605 ipsec_init
.len
= sizeof(ipsec_init
);
2608 if (pcb
->ipsec_use_netif
) {
2609 ipsec_init
.flags
= (IFNET_INIT_SKYWALK_NATIVE
| IFNET_INIT_NX_NOAUTO
);
2611 #endif // IPSEC_NEXUS
2613 ipsec_init
.flags
= IFNET_INIT_NX_NOAUTO
;
2614 ipsec_init
.start
= ipsec_start
;
2616 ipsec_init
.name
= "ipsec";
2617 ipsec_init
.unit
= pcb
->ipsec_unit
- 1;
2618 ipsec_init
.uniqueid
= pcb
->ipsec_unique_name
;
2619 ipsec_init
.uniqueid_len
= strlen(pcb
->ipsec_unique_name
);
2620 ipsec_init
.family
= IFNET_FAMILY_IPSEC
;
2621 ipsec_init
.type
= IFT_OTHER
;
2622 ipsec_init
.demux
= ipsec_demux
;
2623 ipsec_init
.add_proto
= ipsec_add_proto
;
2624 ipsec_init
.del_proto
= ipsec_del_proto
;
2625 ipsec_init
.softc
= pcb
;
2626 ipsec_init
.ioctl
= ipsec_ioctl
;
2627 ipsec_init
.detach
= ipsec_detached
;
2630 /* We don't support kpipes without a netif */
2631 if (pcb
->ipsec_kpipe_count
&& !pcb
->ipsec_use_netif
) {
2633 os_log_error(OS_LOG_DEFAULT
, "ipsec_ctl_connect - kpipe requires netif: failed %d\n", result
);
2634 ipsec_free_pcb(pcb
, true);
2639 if (if_ipsec_debug
!= 0) {
2640 printf("%s: %s%d use_netif %d kpipe_count %d slot_size %u ring_size %u "
2641 "kpipe_tx_ring_size %u kpipe_rx_ring_size %u\n",
2643 ipsec_init
.name
, ipsec_init
.unit
,
2644 pcb
->ipsec_use_netif
,
2645 pcb
->ipsec_kpipe_count
,
2646 pcb
->ipsec_slot_size
,
2647 pcb
->ipsec_netif_ring_size
,
2648 pcb
->ipsec_kpipe_tx_ring_size
,
2649 pcb
->ipsec_kpipe_rx_ring_size
);
2651 if (pcb
->ipsec_use_netif
) {
2652 if (pcb
->ipsec_kpipe_count
) {
2653 result
= ipsec_enable_channel(pcb
, current_proc());
2655 os_log_error(OS_LOG_DEFAULT
, "%s: %s failed to enable channels\n",
2656 __func__
, pcb
->ipsec_if_xname
);
2657 ipsec_free_pcb(pcb
, true);
2663 result
= ipsec_nexus_ifattach(pcb
, &ipsec_init
, &pcb
->ipsec_ifp
);
2665 os_log_error(OS_LOG_DEFAULT
, "ipsec_ctl_connect - ipsec_nexus_ifattach failed: %d\n", result
);
2666 ipsec_free_pcb(pcb
, true);
2671 result
= ipsec_flowswitch_attach(pcb
);
2673 os_log_error(OS_LOG_DEFAULT
, "ipsec_ctl_connect - ipsec_flowswitch_attach failed: %d\n", result
);
2674 // Do not call ipsec_free_pcb(). We will be attached already, and will be freed later
2675 // in ipsec_detached().
2681 bpfattach(pcb
->ipsec_ifp
, DLT_RAW
, 0);
2683 #endif // IPSEC_NEXUS
2685 result
= ifnet_allocate_extended(&ipsec_init
, &pcb
->ipsec_ifp
);
2687 os_log_error(OS_LOG_DEFAULT
, "ipsec_ctl_connect - ifnet_allocate failed: %d\n", result
);
2688 ipsec_free_pcb(pcb
, true);
2692 ipsec_ifnet_set_attrs(pcb
->ipsec_ifp
);
2694 /* Attach the interface */
2695 result
= ifnet_attach(pcb
->ipsec_ifp
, NULL
);
2697 os_log_error(OS_LOG_DEFAULT
, "ipsec_ctl_connect - ifnet_attach failed: %d\n", result
);
2698 ifnet_release(pcb
->ipsec_ifp
);
2699 ipsec_free_pcb(pcb
, true);
2705 bpfattach(pcb
->ipsec_ifp
, DLT_NULL
, 0);
2709 * Mark the data path as ready.
2710 * If kpipe nexus is being used then the data path is marked ready only when a kpipe channel is connected.
2712 if (pcb
->ipsec_kpipe_count
== 0) {
2713 lck_mtx_lock(&pcb
->ipsec_pcb_data_move_lock
);
2714 IPSEC_SET_DATA_PATH_READY(pcb
);
2715 lck_mtx_unlock(&pcb
->ipsec_pcb_data_move_lock
);
2718 /* The interfaces resoures allocated, mark it as running */
2719 ifnet_set_flags(pcb
->ipsec_ifp
, IFF_RUNNING
, IFF_RUNNING
);
2725 ipsec_detach_ip(ifnet_t interface
,
2726 protocol_family_t protocol
,
2729 errno_t result
= EPROTONOSUPPORT
;
2731 /* Attempt a detach */
2732 if (protocol
== PF_INET
) {
2735 bzero(&ifr
, sizeof(ifr
));
2736 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
2737 ifnet_name(interface
), ifnet_unit(interface
));
2739 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH
, &ifr
);
2740 } else if (protocol
== PF_INET6
) {
2741 struct in6_ifreq ifr6
;
2743 bzero(&ifr6
, sizeof(ifr6
));
2744 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
2745 ifnet_name(interface
), ifnet_unit(interface
));
2747 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH_IN6
, &ifr6
);
2754 ipsec_remove_address(ifnet_t interface
,
2755 protocol_family_t protocol
,
2761 /* Attempt a detach */
2762 if (protocol
== PF_INET
) {
2765 bzero(&ifr
, sizeof(ifr
));
2766 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
2767 ifnet_name(interface
), ifnet_unit(interface
));
2768 result
= ifaddr_address(address
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
2770 os_log_error(OS_LOG_DEFAULT
, "ipsec_remove_address - ifaddr_address failed: %d", result
);
2772 result
= sock_ioctl(pf_socket
, SIOCDIFADDR
, &ifr
);
2774 os_log_error(OS_LOG_DEFAULT
, "ipsec_remove_address - SIOCDIFADDR failed: %d", result
);
2777 } else if (protocol
== PF_INET6
) {
2778 struct in6_ifreq ifr6
;
2780 bzero(&ifr6
, sizeof(ifr6
));
2781 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
2782 ifnet_name(interface
), ifnet_unit(interface
));
2783 result
= ifaddr_address(address
, (struct sockaddr
*)&ifr6
.ifr_addr
,
2784 sizeof(ifr6
.ifr_addr
));
2786 os_log_error(OS_LOG_DEFAULT
, "ipsec_remove_address - ifaddr_address failed (v6): %d",
2789 result
= sock_ioctl(pf_socket
, SIOCDIFADDR_IN6
, &ifr6
);
2791 os_log_error(OS_LOG_DEFAULT
, "ipsec_remove_address - SIOCDIFADDR_IN6 failed: %d",
2799 ipsec_cleanup_family(ifnet_t interface
,
2800 protocol_family_t protocol
)
2803 socket_t pf_socket
= NULL
;
2804 ifaddr_t
*addresses
= NULL
;
2807 if (protocol
!= PF_INET
&& protocol
!= PF_INET6
) {
2808 os_log_error(OS_LOG_DEFAULT
, "ipsec_cleanup_family - invalid protocol family %d\n", protocol
);
2812 /* Create a socket for removing addresses and detaching the protocol */
2813 result
= sock_socket(protocol
, SOCK_DGRAM
, 0, NULL
, NULL
, &pf_socket
);
2815 if (result
!= EAFNOSUPPORT
) {
2816 os_log_error(OS_LOG_DEFAULT
, "ipsec_cleanup_family - failed to create %s socket: %d\n",
2817 protocol
== PF_INET
? "IP" : "IPv6", result
);
2822 /* always set SS_PRIV, we want to close and detach regardless */
2823 sock_setpriv(pf_socket
, 1);
2825 result
= ipsec_detach_ip(interface
, protocol
, pf_socket
);
2826 if (result
== 0 || result
== ENXIO
) {
2827 /* We are done! We either detached or weren't attached. */
2829 } else if (result
!= EBUSY
) {
2830 /* Uh, not really sure what happened here... */
2831 os_log_error(OS_LOG_DEFAULT
, "ipsec_cleanup_family - ipsec_detach_ip failed: %d\n", result
);
2836 * At this point, we received an EBUSY error. This means there are
2837 * addresses attached. We should detach them and then try again.
2839 result
= ifnet_get_address_list_family(interface
, &addresses
, protocol
);
2841 os_log_error(OS_LOG_DEFAULT
, "fnet_get_address_list_family(%s%d, 0xblah, %s) - failed: %d\n",
2842 ifnet_name(interface
), ifnet_unit(interface
),
2843 protocol
== PF_INET
? "PF_INET" : "PF_INET6", result
);
2847 for (i
= 0; addresses
[i
] != 0; i
++) {
2848 ipsec_remove_address(interface
, protocol
, addresses
[i
], pf_socket
);
2850 ifnet_free_address_list(addresses
);
2854 * The addresses should be gone, we should try the remove again.
2856 result
= ipsec_detach_ip(interface
, protocol
, pf_socket
);
2857 if (result
!= 0 && result
!= ENXIO
) {
2858 os_log_error(OS_LOG_DEFAULT
, "ipsec_cleanup_family - ipsec_detach_ip failed: %d\n", result
);
2862 if (pf_socket
!= NULL
) {
2863 sock_close(pf_socket
);
2866 if (addresses
!= NULL
) {
2867 ifnet_free_address_list(addresses
);
2872 ipsec_ctl_disconnect(__unused kern_ctl_ref kctlref
,
2873 __unused u_int32_t unit
,
2876 struct ipsec_pcb
*pcb
= unitinfo
;
2884 /* Wait until all threads in the data paths are done. */
2885 ipsec_wait_data_move_drain(pcb
);
2888 // Tell the nexus to stop all rings
2889 if (pcb
->ipsec_netif_nexus
!= NULL
) {
2890 kern_nexus_stop(pcb
->ipsec_netif_nexus
);
2892 #endif // IPSEC_NEXUS
2894 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
2897 if (if_ipsec_debug
!= 0) {
2898 printf("ipsec_ctl_disconnect: detaching interface %s (id %s)\n",
2899 pcb
->ipsec_if_xname
, pcb
->ipsec_unique_name
);
2902 struct ipsec_detached_channels dc
;
2903 ipsec_detach_channels(pcb
, &dc
);
2904 #endif // IPSEC_NEXUS
2906 pcb
->ipsec_ctlref
= NULL
;
2908 ifp
= pcb
->ipsec_ifp
;
2911 if (pcb
->ipsec_netif_nexus
!= NULL
) {
2913 * Quiesce the interface and flush any pending outbound packets.
2917 /* Increment refcnt, but detach interface */
2918 ifnet_incr_iorefcnt(ifp
);
2919 if ((result
= ifnet_detach(ifp
)) != 0) {
2920 panic("ipsec_ctl_disconnect - ifnet_detach failed: %d\n", result
);
2925 * We want to do everything in our power to ensure that the interface
2926 * really goes away when the socket is closed. We must remove IP/IPv6
2927 * addresses and detach the protocols. Finally, we can remove and
2928 * release the interface.
2930 key_delsp_for_ipsec_if(ifp
);
2932 ipsec_cleanup_family(ifp
, AF_INET
);
2933 ipsec_cleanup_family(ifp
, AF_INET6
);
2935 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2937 ipsec_free_channels(&dc
);
2939 ipsec_nexus_detach(pcb
);
2941 /* Decrement refcnt to finish detaching and freeing */
2942 ifnet_decr_iorefcnt(ifp
);
2944 #endif // IPSEC_NEXUS
2946 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2949 ipsec_free_channels(&dc
);
2950 #endif // IPSEC_NEXUS
2953 * We want to do everything in our power to ensure that the interface
2954 * really goes away when the socket is closed. We must remove IP/IPv6
2955 * addresses and detach the protocols. Finally, we can remove and
2956 * release the interface.
2958 key_delsp_for_ipsec_if(ifp
);
2960 ipsec_cleanup_family(ifp
, AF_INET
);
2961 ipsec_cleanup_family(ifp
, AF_INET6
);
2964 * Detach now; ipsec_detach() will be called asynchronously once
2965 * the I/O reference count drops to 0. There we will invoke
2968 if ((result
= ifnet_detach(ifp
)) != 0) {
2969 os_log_error(OS_LOG_DEFAULT
, "ipsec_ctl_disconnect - ifnet_detach failed: %d\n", result
);
2973 // Bound, but not connected
2974 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2975 ipsec_free_pcb(pcb
, false);
2982 ipsec_ctl_send(__unused kern_ctl_ref kctlref
,
2983 __unused u_int32_t unit
,
2984 __unused
void *unitinfo
,
2988 /* Receive messages from the control socket. Currently unused. */
2994 ipsec_ctl_setopt(__unused kern_ctl_ref kctlref
,
2995 __unused u_int32_t unit
,
3002 struct ipsec_pcb
*pcb
= unitinfo
;
3007 /* check for privileges for privileged options */
3009 case IPSEC_OPT_FLAGS
:
3010 case IPSEC_OPT_EXT_IFDATA_STATS
:
3011 case IPSEC_OPT_SET_DELEGATE_INTERFACE
:
3012 case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS
:
3013 if (kauth_cred_issuser(kauth_cred_get()) == 0) {
3020 case IPSEC_OPT_FLAGS
: {
3021 if (len
!= sizeof(u_int32_t
)) {
3024 pcb
->ipsec_external_flags
= *(u_int32_t
*)data
;
3029 case IPSEC_OPT_EXT_IFDATA_STATS
: {
3030 if (len
!= sizeof(int)) {
3034 if (pcb
->ipsec_ifp
== NULL
) {
3035 // Only can set after connecting
3039 pcb
->ipsec_ext_ifdata_stats
= (*(int *)data
) ? 1 : 0;
3043 case IPSEC_OPT_INC_IFDATA_STATS_IN
:
3044 case IPSEC_OPT_INC_IFDATA_STATS_OUT
: {
3045 struct ipsec_stats_param
*utsp
= (struct ipsec_stats_param
*)data
;
3047 if (utsp
== NULL
|| len
< sizeof(struct ipsec_stats_param
)) {
3051 if (pcb
->ipsec_ifp
== NULL
) {
3052 // Only can set after connecting
3056 if (!pcb
->ipsec_ext_ifdata_stats
) {
3060 if (opt
== IPSEC_OPT_INC_IFDATA_STATS_IN
) {
3061 ifnet_stat_increment_in(pcb
->ipsec_ifp
, utsp
->utsp_packets
,
3062 utsp
->utsp_bytes
, utsp
->utsp_errors
);
3064 ifnet_stat_increment_out(pcb
->ipsec_ifp
, utsp
->utsp_packets
,
3065 utsp
->utsp_bytes
, utsp
->utsp_errors
);
3070 case IPSEC_OPT_SET_DELEGATE_INTERFACE
: {
3071 ifnet_t del_ifp
= NULL
;
3072 char name
[IFNAMSIZ
];
3074 if (len
> IFNAMSIZ
- 1) {
3078 if (pcb
->ipsec_ifp
== NULL
) {
3079 // Only can set after connecting
3083 if (len
!= 0) { /* if len==0, del_ifp will be NULL causing the delegate to be removed */
3084 bcopy(data
, name
, len
);
3086 result
= ifnet_find_by_name(name
, &del_ifp
);
3089 os_log_error(OS_LOG_DEFAULT
, "%s IPSEC_OPT_SET_DELEGATE_INTERFACE %s to %s\n",
3090 __func__
, pcb
->ipsec_ifp
->if_xname
,
3091 del_ifp
? del_ifp
->if_xname
: "NULL");
3093 result
= ifnet_set_delegate(pcb
->ipsec_ifp
, del_ifp
);
3095 ifnet_release(del_ifp
);
3101 case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS
: {
3102 if (len
!= sizeof(int)) {
3106 if (pcb
->ipsec_ifp
== NULL
) {
3107 // Only can set after connecting
3111 mbuf_svc_class_t output_service_class
= so_tc2msc(*(int *)data
);
3112 if (output_service_class
== MBUF_SC_UNSPEC
) {
3113 pcb
->ipsec_output_service_class
= MBUF_SC_OAM
;
3115 pcb
->ipsec_output_service_class
= output_service_class
;
3117 os_log_error(OS_LOG_DEFAULT
, "%s IPSEC_OPT_OUTPUT_TRAFFIC_CLASS %s svc %d\n",
3118 __func__
, pcb
->ipsec_ifp
->if_xname
,
3119 pcb
->ipsec_output_service_class
);
3124 case IPSEC_OPT_ENABLE_CHANNEL
: {
3125 if (len
!= sizeof(int)) {
3129 if (pcb
->ipsec_ifp
!= NULL
) {
3130 // Only can set before connecting
3134 if ((*(int *)data
) != 0 &&
3135 (*(int *)data
) != 1 &&
3136 (*(int *)data
) != IPSEC_IF_WMM_RING_COUNT
) {
3140 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
3141 pcb
->ipsec_kpipe_count
= *(int *)data
;
3142 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
3146 case IPSEC_OPT_CHANNEL_BIND_PID
: {
3147 if (len
!= sizeof(pid_t
)) {
3151 if (pcb
->ipsec_ifp
!= NULL
) {
3152 // Only can set before connecting
3156 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
3157 pcb
->ipsec_kpipe_pid
= *(pid_t
*)data
;
3158 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
3162 case IPSEC_OPT_ENABLE_FLOWSWITCH
: {
3163 if (len
!= sizeof(int)) {
3167 if (pcb
->ipsec_ifp
== NULL
) {
3168 // Only can set after connecting
3172 if (!if_is_fsw_transport_netagent_enabled()) {
3176 if (uuid_is_null(pcb
->ipsec_nx
.fsw_agent
)) {
3181 uint32_t flags
= netagent_get_flags(pcb
->ipsec_nx
.fsw_agent
);
3184 flags
|= (NETAGENT_FLAG_NEXUS_PROVIDER
|
3185 NETAGENT_FLAG_NEXUS_LISTENER
);
3186 result
= netagent_set_flags(pcb
->ipsec_nx
.fsw_agent
, flags
);
3187 pcb
->ipsec_needs_netagent
= true;
3189 pcb
->ipsec_needs_netagent
= false;
3190 flags
&= ~(NETAGENT_FLAG_NEXUS_PROVIDER
|
3191 NETAGENT_FLAG_NEXUS_LISTENER
);
3192 result
= netagent_set_flags(pcb
->ipsec_nx
.fsw_agent
, flags
);
3197 case IPSEC_OPT_INPUT_FRAG_SIZE
: {
3198 if (len
!= sizeof(u_int32_t
)) {
3202 u_int32_t input_frag_size
= *(u_int32_t
*)data
;
3203 if (input_frag_size
<= sizeof(struct ip6_hdr
)) {
3204 pcb
->ipsec_frag_size_set
= FALSE
;
3205 pcb
->ipsec_input_frag_size
= 0;
3207 pcb
->ipsec_frag_size_set
= TRUE
;
3208 pcb
->ipsec_input_frag_size
= input_frag_size
;
3212 case IPSEC_OPT_ENABLE_NETIF
: {
3213 if (len
!= sizeof(int)) {
3217 if (pcb
->ipsec_ifp
!= NULL
) {
3218 // Only can set before connecting
3222 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
3223 pcb
->ipsec_use_netif
= !!(*(int *)data
);
3224 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
3227 case IPSEC_OPT_SLOT_SIZE
: {
3228 if (len
!= sizeof(u_int32_t
)) {
3232 if (pcb
->ipsec_ifp
!= NULL
) {
3233 // Only can set before connecting
3237 u_int32_t slot_size
= *(u_int32_t
*)data
;
3238 if (slot_size
< IPSEC_IF_MIN_SLOT_SIZE
||
3239 slot_size
> IPSEC_IF_MAX_SLOT_SIZE
) {
3242 pcb
->ipsec_slot_size
= slot_size
;
3243 if (if_ipsec_debug
!= 0) {
3244 printf("%s: IPSEC_OPT_SLOT_SIZE %u\n", __func__
, slot_size
);
3248 case IPSEC_OPT_NETIF_RING_SIZE
: {
3249 if (len
!= sizeof(u_int32_t
)) {
3253 if (pcb
->ipsec_ifp
!= NULL
) {
3254 // Only can set before connecting
3258 u_int32_t ring_size
= *(u_int32_t
*)data
;
3259 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
3260 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
3263 pcb
->ipsec_netif_ring_size
= ring_size
;
3264 if (if_ipsec_debug
!= 0) {
3265 printf("%s: IPSEC_OPT_NETIF_RING_SIZE %u\n", __func__
, ring_size
);
3269 case IPSEC_OPT_TX_FSW_RING_SIZE
: {
3270 if (len
!= sizeof(u_int32_t
)) {
3274 if (pcb
->ipsec_ifp
!= NULL
) {
3275 // Only can set before connecting
3279 u_int32_t ring_size
= *(u_int32_t
*)data
;
3280 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
3281 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
3284 pcb
->ipsec_tx_fsw_ring_size
= ring_size
;
3285 if (if_ipsec_debug
!= 0) {
3286 printf("%s: IPSEC_OPT_TX_FSW_RING_SIZE %u\n", __func__
, ring_size
);
3290 case IPSEC_OPT_RX_FSW_RING_SIZE
: {
3291 if (len
!= sizeof(u_int32_t
)) {
3295 if (pcb
->ipsec_ifp
!= NULL
) {
3296 // Only can set before connecting
3300 u_int32_t ring_size
= *(u_int32_t
*)data
;
3301 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
3302 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
3305 pcb
->ipsec_rx_fsw_ring_size
= ring_size
;
3306 if (if_ipsec_debug
!= 0) {
3307 printf("%s: IPSEC_OPT_TX_FSW_RING_SIZE %u\n", __func__
, ring_size
);
3311 case IPSEC_OPT_KPIPE_TX_RING_SIZE
: {
3312 if (len
!= sizeof(u_int32_t
)) {
3316 if (pcb
->ipsec_ifp
!= NULL
) {
3317 // Only can set before connecting
3321 u_int32_t ring_size
= *(u_int32_t
*)data
;
3322 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
3323 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
3326 pcb
->ipsec_kpipe_tx_ring_size
= ring_size
;
3327 if (if_ipsec_debug
!= 0) {
3328 printf("%s: IPSEC_OPT_KPIPE_TX_RING_SIZE %u\n", __func__
, ring_size
);
3332 case IPSEC_OPT_KPIPE_RX_RING_SIZE
: {
3333 if (len
!= sizeof(u_int32_t
)) {
3337 if (pcb
->ipsec_ifp
!= NULL
) {
3338 // Only can set before connecting
3342 u_int32_t ring_size
= *(u_int32_t
*)data
;
3343 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
3344 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
3347 pcb
->ipsec_kpipe_rx_ring_size
= ring_size
;
3348 if (if_ipsec_debug
!= 0) {
3349 printf("%s: IPSEC_OPT_KPIPE_RX_RING_SIZE %u\n", __func__
, ring_size
);
3354 #endif // IPSEC_NEXUS
3357 result
= ENOPROTOOPT
;
3366 ipsec_ctl_getopt(__unused kern_ctl_ref kctlref
,
3367 __unused u_int32_t unit
,
3374 struct ipsec_pcb
*pcb
= unitinfo
;
3380 case IPSEC_OPT_FLAGS
: {
3381 if (*len
!= sizeof(u_int32_t
)) {
3384 *(u_int32_t
*)data
= pcb
->ipsec_external_flags
;
3389 case IPSEC_OPT_EXT_IFDATA_STATS
: {
3390 if (*len
!= sizeof(int)) {
3393 *(int *)data
= (pcb
->ipsec_ext_ifdata_stats
) ? 1 : 0;
3398 case IPSEC_OPT_IFNAME
: {
3399 if (*len
< MIN(strlen(pcb
->ipsec_if_xname
) + 1, sizeof(pcb
->ipsec_if_xname
))) {
3402 if (pcb
->ipsec_ifp
== NULL
) {
3403 // Only can get after connecting
3407 *len
= snprintf(data
, *len
, "%s", pcb
->ipsec_if_xname
) + 1;
3412 case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS
: {
3413 if (*len
!= sizeof(int)) {
3416 *(int *)data
= so_svc2tc(pcb
->ipsec_output_service_class
);
3423 case IPSEC_OPT_ENABLE_CHANNEL
: {
3424 if (*len
!= sizeof(int)) {
3427 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
3428 *(int *)data
= pcb
->ipsec_kpipe_count
;
3429 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
3434 case IPSEC_OPT_CHANNEL_BIND_PID
: {
3435 if (*len
!= sizeof(pid_t
)) {
3438 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
3439 *(pid_t
*)data
= pcb
->ipsec_kpipe_pid
;
3440 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
3445 case IPSEC_OPT_ENABLE_FLOWSWITCH
: {
3446 if (*len
!= sizeof(int)) {
3449 *(int *)data
= if_check_netagent(pcb
->ipsec_ifp
, pcb
->ipsec_nx
.fsw_agent
);
3454 case IPSEC_OPT_ENABLE_NETIF
: {
3455 if (*len
!= sizeof(int)) {
3458 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
3459 *(int *)data
= !!pcb
->ipsec_use_netif
;
3460 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
3465 case IPSEC_OPT_GET_CHANNEL_UUID
: {
3466 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
3467 if (!ipsec_flag_isset(pcb
, IPSEC_FLAGS_KPIPE_ALLOCATED
)) {
3469 } else if (*len
!= sizeof(uuid_t
) * pcb
->ipsec_kpipe_count
) {
3472 for (unsigned int i
= 0; i
< pcb
->ipsec_kpipe_count
; i
++) {
3473 uuid_copy(((uuid_t
*)data
)[i
], pcb
->ipsec_kpipe_uuid
[i
]);
3476 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
3480 case IPSEC_OPT_INPUT_FRAG_SIZE
: {
3481 if (*len
!= sizeof(u_int32_t
)) {
3484 *(u_int32_t
*)data
= pcb
->ipsec_input_frag_size
;
3488 case IPSEC_OPT_SLOT_SIZE
: {
3489 if (*len
!= sizeof(u_int32_t
)) {
3492 *(u_int32_t
*)data
= pcb
->ipsec_slot_size
;
3496 case IPSEC_OPT_NETIF_RING_SIZE
: {
3497 if (*len
!= sizeof(u_int32_t
)) {
3500 *(u_int32_t
*)data
= pcb
->ipsec_netif_ring_size
;
3504 case IPSEC_OPT_TX_FSW_RING_SIZE
: {
3505 if (*len
!= sizeof(u_int32_t
)) {
3508 *(u_int32_t
*)data
= pcb
->ipsec_tx_fsw_ring_size
;
3512 case IPSEC_OPT_RX_FSW_RING_SIZE
: {
3513 if (*len
!= sizeof(u_int32_t
)) {
3516 *(u_int32_t
*)data
= pcb
->ipsec_rx_fsw_ring_size
;
3520 case IPSEC_OPT_KPIPE_TX_RING_SIZE
: {
3521 if (*len
!= sizeof(u_int32_t
)) {
3524 *(u_int32_t
*)data
= pcb
->ipsec_kpipe_tx_ring_size
;
3528 case IPSEC_OPT_KPIPE_RX_RING_SIZE
: {
3529 if (*len
!= sizeof(u_int32_t
)) {
3532 *(u_int32_t
*)data
= pcb
->ipsec_kpipe_rx_ring_size
;
3537 #endif // IPSEC_NEXUS
3540 result
= ENOPROTOOPT
;
3548 /* Network Interface functions */
3550 ipsec_output(ifnet_t interface
,
3553 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3554 struct ipsec_output_state ipsec_state
;
3556 struct route_in6 ro6
;
3559 struct ip6_hdr
*ip6
;
3560 struct ip_out_args ipoa
;
3561 struct ip6_out_args ip6oa
;
3563 u_int ip_version
= 0;
3565 struct flowadv
*adv
= NULL
;
3567 // Make sure this packet isn't looping through the interface
3568 if (necp_get_last_interface_index_from_packet(data
) == interface
->if_index
) {
3570 goto ipsec_output_err
;
3573 // Mark the interface so NECP can evaluate tunnel policy
3574 necp_mark_packet_from_interface(data
, interface
);
3576 ip
= mtod(data
, struct ip
*);
3577 ip_version
= ip
->ip_v
;
3579 switch (ip_version
) {
3582 if (!pcb
->ipsec_use_netif
)
3583 #endif // IPSEC_NEXUS
3586 bpf_tap_out(pcb
->ipsec_ifp
, DLT_NULL
, data
, &af
, sizeof(af
));
3589 /* Apply encryption */
3590 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
3591 ipsec_state
.m
= data
;
3592 ipsec_state
.dst
= (struct sockaddr
*)&ip
->ip_dst
;
3593 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
3595 error
= ipsec4_interface_output(&ipsec_state
, interface
);
3596 /* Tunneled in IPv6 - packet is gone */
3597 if (error
== 0 && ipsec_state
.tunneled
== 6) {
3601 data
= ipsec_state
.m
;
3602 if (error
|| data
== NULL
) {
3604 os_log_error(OS_LOG_DEFAULT
, "ipsec_output: ipsec4_output error %d.\n", error
);
3606 goto ipsec_output_err
;
3609 /* Set traffic class, set flow */
3610 m_set_service_class(data
, pcb
->ipsec_output_service_class
);
3611 data
->m_pkthdr
.pkt_flowsrc
= FLOWSRC_IFNET
;
3612 data
->m_pkthdr
.pkt_flowid
= interface
->if_flowhash
;
3613 data
->m_pkthdr
.pkt_proto
= ip
->ip_p
;
3614 data
->m_pkthdr
.pkt_flags
= (PKTF_FLOW_ID
| PKTF_FLOW_ADV
| PKTF_FLOW_LOCALSRC
);
3616 /* Flip endian-ness for ip_output */
3617 ip
= mtod(data
, struct ip
*);
3621 /* Increment statistics */
3622 length
= mbuf_pkthdr_len(data
);
3623 ifnet_stat_increment_out(interface
, 1, length
, 0);
3625 /* Send to ip_output */
3626 memset(&ro
, 0, sizeof(ro
));
3628 flags
= (IP_OUTARGS
| /* Passing out args to specify interface */
3629 IP_NOIPSEC
); /* To ensure the packet doesn't go through ipsec twice */
3631 memset(&ipoa
, 0, sizeof(ipoa
));
3632 ipoa
.ipoa_flowadv
.code
= 0;
3633 ipoa
.ipoa_flags
= IPOAF_SELECT_SRCIF
| IPOAF_BOUND_SRCADDR
;
3634 if (ipsec_state
.outgoing_if
) {
3635 ipoa
.ipoa_boundif
= ipsec_state
.outgoing_if
;
3636 ipoa
.ipoa_flags
|= IPOAF_BOUND_IF
;
3638 ipsec_set_ipoa_for_interface(pcb
->ipsec_ifp
, &ipoa
);
3640 adv
= &ipoa
.ipoa_flowadv
;
3642 (void)ip_output(data
, NULL
, &ro
, flags
, NULL
, &ipoa
);
3645 if (adv
->code
== FADV_FLOW_CONTROLLED
|| adv
->code
== FADV_SUSPENDED
) {
3647 ifnet_disable_output(interface
);
3654 if (!pcb
->ipsec_use_netif
)
3655 #endif // IPSEC_NEXUS
3658 bpf_tap_out(pcb
->ipsec_ifp
, DLT_NULL
, data
, &af
, sizeof(af
));
3661 data
= ipsec6_splithdr(data
);
3663 os_log_error(OS_LOG_DEFAULT
, "ipsec_output: ipsec6_splithdr returned NULL\n");
3664 goto ipsec_output_err
;
3667 ip6
= mtod(data
, struct ip6_hdr
*);
3669 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
3670 ipsec_state
.m
= data
;
3671 ipsec_state
.dst
= (struct sockaddr
*)&ip6
->ip6_dst
;
3672 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
3674 error
= ipsec6_interface_output(&ipsec_state
, interface
, &ip6
->ip6_nxt
, ipsec_state
.m
);
3675 if (error
== 0 && ipsec_state
.tunneled
== 4) { /* tunneled in IPv4 - packet is gone */
3678 data
= ipsec_state
.m
;
3679 if (error
|| data
== NULL
) {
3681 os_log_error(OS_LOG_DEFAULT
, "ipsec_output: ipsec6_output error %d\n", error
);
3683 goto ipsec_output_err
;
3686 /* Set traffic class, set flow */
3687 m_set_service_class(data
, pcb
->ipsec_output_service_class
);
3688 data
->m_pkthdr
.pkt_flowsrc
= FLOWSRC_IFNET
;
3689 data
->m_pkthdr
.pkt_flowid
= interface
->if_flowhash
;
3690 data
->m_pkthdr
.pkt_proto
= ip6
->ip6_nxt
;
3691 data
->m_pkthdr
.pkt_flags
= (PKTF_FLOW_ID
| PKTF_FLOW_ADV
| PKTF_FLOW_LOCALSRC
);
3693 /* Increment statistics */
3694 length
= mbuf_pkthdr_len(data
);
3695 ifnet_stat_increment_out(interface
, 1, length
, 0);
3697 /* Send to ip6_output */
3698 memset(&ro6
, 0, sizeof(ro6
));
3700 flags
= IPV6_OUTARGS
;
3702 memset(&ip6oa
, 0, sizeof(ip6oa
));
3703 ip6oa
.ip6oa_flowadv
.code
= 0;
3704 ip6oa
.ip6oa_flags
= IP6OAF_SELECT_SRCIF
| IP6OAF_BOUND_SRCADDR
;
3705 if (ipsec_state
.outgoing_if
) {
3706 ip6oa
.ip6oa_boundif
= ipsec_state
.outgoing_if
;
3707 ip6oa
.ip6oa_flags
|= IP6OAF_BOUND_IF
;
3709 ipsec_set_ip6oa_for_interface(pcb
->ipsec_ifp
, &ip6oa
);
3711 adv
= &ip6oa
.ip6oa_flowadv
;
3713 (void) ip6_output(data
, NULL
, &ro6
, flags
, NULL
, NULL
, &ip6oa
);
3716 if (adv
->code
== FADV_FLOW_CONTROLLED
|| adv
->code
== FADV_SUSPENDED
) {
3718 ifnet_disable_output(interface
);
3724 os_log_error(OS_LOG_DEFAULT
, "ipsec_output: Received unknown packet version %d.\n", ip_version
);
3726 goto ipsec_output_err
;
3741 ipsec_start(ifnet_t interface
)
3744 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3746 VERIFY(pcb
!= NULL
);
3748 if (ifnet_dequeue(interface
, &data
) != 0) {
3751 if (ipsec_output(interface
, data
) != 0) {
3757 /* Network Interface functions */
3759 ipsec_demux(__unused ifnet_t interface
,
3761 __unused
char *frame_header
,
3762 protocol_family_t
*protocol
)
3767 while (data
!= NULL
&& mbuf_len(data
) < 1) {
3768 data
= mbuf_next(data
);
3775 ip
= mtod(data
, struct ip
*);
3776 ip_version
= ip
->ip_v
;
3778 switch (ip_version
) {
3780 *protocol
= PF_INET
;
3783 *protocol
= PF_INET6
;
3793 ipsec_add_proto(__unused ifnet_t interface
,
3794 protocol_family_t protocol
,
3795 __unused
const struct ifnet_demux_desc
*demux_array
,
3796 __unused u_int32_t demux_count
)
3811 ipsec_del_proto(__unused ifnet_t interface
,
3812 __unused protocol_family_t protocol
)
3818 ipsec_ioctl(ifnet_t interface
,
3823 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3830 if (pcb
->ipsec_use_netif
) {
3831 // Make sure we can fit packets in the channel buffers
3832 if (((uint64_t)((struct ifreq
*)data
)->ifr_mtu
) > pcb
->ipsec_slot_size
) {
3835 ifnet_set_mtu(interface
, (uint32_t)((struct ifreq
*)data
)->ifr_mtu
);
3838 #endif // IPSEC_NEXUS
3840 ifnet_set_mtu(interface
, ((struct ifreq
*)data
)->ifr_mtu
);
3846 /* ifioctl() takes care of it */
3849 case SIOCSIFSUBFAMILY
: {
3852 subfamily
= ((struct ifreq
*)data
)->ifr_type
.ift_subfamily
;
3853 switch (subfamily
) {
3854 case IFRTYPE_SUBFAMILY_BLUETOOTH
:
3855 interface
->if_subfamily
= IFNET_SUBFAMILY_BLUETOOTH
;
3857 case IFRTYPE_SUBFAMILY_WIFI
:
3858 interface
->if_subfamily
= IFNET_SUBFAMILY_WIFI
;
3860 case IFRTYPE_SUBFAMILY_QUICKRELAY
:
3861 interface
->if_subfamily
= IFNET_SUBFAMILY_QUICKRELAY
;
3863 case IFRTYPE_SUBFAMILY_DEFAULT
:
3864 interface
->if_subfamily
= IFNET_SUBFAMILY_DEFAULT
;
3874 result
= EOPNOTSUPP
;
3881 ipsec_detached(ifnet_t interface
)
3883 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3885 (void)ifnet_release(interface
);
3886 ipsec_free_pcb(pcb
, true);
3889 /* Protocol Handlers */
3892 ipsec_proto_input(ifnet_t interface
,
3893 protocol_family_t protocol
,
3895 __unused
char *frame_header
)
3897 mbuf_pkthdr_setrcvif(m
, interface
);
3900 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3901 if (!pcb
->ipsec_use_netif
)
3902 #endif // IPSEC_NEXUS
3905 struct ip
*ip
= mtod(m
, struct ip
*);
3906 if (ip
->ip_v
== 4) {
3908 } else if (ip
->ip_v
== 6) {
3911 bpf_tap_in(interface
, DLT_NULL
, m
, &af
, sizeof(af
));
3912 pktap_input(interface
, protocol
, m
, NULL
);
3915 int32_t pktlen
= m
->m_pkthdr
.len
;
3916 if (proto_input(protocol
, m
) != 0) {
3917 ifnet_stat_increment_in(interface
, 0, 0, 1);
3920 ifnet_stat_increment_in(interface
, 1, pktlen
, 0);
3927 ipsec_proto_pre_output(__unused ifnet_t interface
,
3928 protocol_family_t protocol
,
3929 __unused mbuf_t
*packet
,
3930 __unused
const struct sockaddr
*dest
,
3931 __unused
void *route
,
3932 __unused
char *frame_type
,
3933 __unused
char *link_layer_dest
)
3935 *(protocol_family_t
*)(void *)frame_type
= protocol
;
3940 ipsec_attach_proto(ifnet_t interface
,
3941 protocol_family_t protocol
)
3943 struct ifnet_attach_proto_param proto
;
3946 bzero(&proto
, sizeof(proto
));
3947 proto
.input
= ipsec_proto_input
;
3948 proto
.pre_output
= ipsec_proto_pre_output
;
3950 result
= ifnet_attach_protocol(interface
, protocol
, &proto
);
3951 if (result
!= 0 && result
!= EEXIST
) {
3952 os_log_error(OS_LOG_DEFAULT
, "ipsec_attach_inet - ifnet_attach_protocol %d failed: %d\n",
3960 ipsec_inject_inbound_packet(ifnet_t interface
,
3964 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3966 if (pcb
->ipsec_use_netif
) {
3967 if (!ipsec_data_move_begin(pcb
)) {
3968 os_log_info(OS_LOG_DEFAULT
, "%s: data path stopped for %s\n", __func__
,
3969 if_name(pcb
->ipsec_ifp
));
3973 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
3975 lck_mtx_lock(&pcb
->ipsec_input_chain_lock
);
3977 if (pcb
->ipsec_input_chain_count
> (u_int32_t
)if_ipsec_max_pending_input
) {
3978 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
3979 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
3980 ipsec_data_move_end(pcb
);
3984 if (pcb
->ipsec_input_chain
!= NULL
) {
3985 pcb
->ipsec_input_chain_last
->m_nextpkt
= packet
;
3987 pcb
->ipsec_input_chain
= packet
;
3989 pcb
->ipsec_input_chain_count
++;
3990 while (packet
->m_nextpkt
) {
3991 VERIFY(packet
!= packet
->m_nextpkt
);
3992 packet
= packet
->m_nextpkt
;
3993 pcb
->ipsec_input_chain_count
++;
3995 pcb
->ipsec_input_chain_last
= packet
;
3996 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
3998 kern_channel_ring_t rx_ring
= pcb
->ipsec_netif_rxring
[0];
3999 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
4001 if (rx_ring
!= NULL
) {
4002 kern_channel_notify(rx_ring
, 0);
4005 ipsec_data_move_end(pcb
);
4008 #endif // IPSEC_NEXUS
4011 protocol_family_t protocol
;
4012 if ((error
= ipsec_demux(interface
, packet
, NULL
, &protocol
)) != 0) {
4016 return ipsec_proto_input(interface
, protocol
, packet
, NULL
);
4021 ipsec_set_pkthdr_for_interface(ifnet_t interface
, mbuf_t packet
, int family
)
4023 if (packet
!= NULL
&& interface
!= NULL
) {
4024 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
4026 /* Set traffic class, set flow */
4027 m_set_service_class(packet
, pcb
->ipsec_output_service_class
);
4028 packet
->m_pkthdr
.pkt_flowsrc
= FLOWSRC_IFNET
;
4029 packet
->m_pkthdr
.pkt_flowid
= interface
->if_flowhash
;
4030 if (family
== AF_INET
) {
4031 struct ip
*ip
= mtod(packet
, struct ip
*);
4032 packet
->m_pkthdr
.pkt_proto
= ip
->ip_p
;
4033 } else if (family
== AF_INET6
) {
4034 struct ip6_hdr
*ip6
= mtod(packet
, struct ip6_hdr
*);
4035 packet
->m_pkthdr
.pkt_proto
= ip6
->ip6_nxt
;
4037 packet
->m_pkthdr
.pkt_flags
= (PKTF_FLOW_ID
| PKTF_FLOW_ADV
| PKTF_FLOW_LOCALSRC
);
4043 ipsec_set_ipoa_for_interface(ifnet_t interface
, struct ip_out_args
*ipoa
)
4045 struct ipsec_pcb
*pcb
;
4047 if (interface
== NULL
|| ipoa
== NULL
) {
4050 pcb
= ifnet_softc(interface
);
4052 if (net_qos_policy_restricted
== 0) {
4053 ipoa
->ipoa_flags
|= IPOAF_QOSMARKING_ALLOWED
;
4054 ipoa
->ipoa_sotc
= so_svc2tc(pcb
->ipsec_output_service_class
);
4055 } else if (pcb
->ipsec_output_service_class
!= MBUF_SC_VO
||
4056 net_qos_policy_restrict_avapps
!= 0) {
4057 ipoa
->ipoa_flags
&= ~IPOAF_QOSMARKING_ALLOWED
;
4059 ipoa
->ipoa_flags
|= IP6OAF_QOSMARKING_ALLOWED
;
4060 ipoa
->ipoa_sotc
= SO_TC_VO
;
4065 ipsec_set_ip6oa_for_interface(ifnet_t interface
, struct ip6_out_args
*ip6oa
)
4067 struct ipsec_pcb
*pcb
;
4069 if (interface
== NULL
|| ip6oa
== NULL
) {
4072 pcb
= ifnet_softc(interface
);
4074 if (net_qos_policy_restricted
== 0) {
4075 ip6oa
->ip6oa_flags
|= IPOAF_QOSMARKING_ALLOWED
;
4076 ip6oa
->ip6oa_sotc
= so_svc2tc(pcb
->ipsec_output_service_class
);
4077 } else if (pcb
->ipsec_output_service_class
!= MBUF_SC_VO
||
4078 net_qos_policy_restrict_avapps
!= 0) {
4079 ip6oa
->ip6oa_flags
&= ~IPOAF_QOSMARKING_ALLOWED
;
4081 ip6oa
->ip6oa_flags
|= IP6OAF_QOSMARKING_ALLOWED
;
4082 ip6oa
->ip6oa_sotc
= SO_TC_VO
;
4087 ipsec_data_move_begin(struct ipsec_pcb
*pcb
)
4091 lck_mtx_lock_spin(&pcb
->ipsec_pcb_data_move_lock
);
4092 if ((ret
= IPSEC_IS_DATA_PATH_READY(pcb
))) {
4093 pcb
->ipsec_pcb_data_move
++;
4095 lck_mtx_unlock(&pcb
->ipsec_pcb_data_move_lock
);
4101 ipsec_data_move_end(struct ipsec_pcb
*pcb
)
4103 lck_mtx_lock_spin(&pcb
->ipsec_pcb_data_move_lock
);
4104 VERIFY(pcb
->ipsec_pcb_data_move
> 0);
4106 * if there's no more thread moving data, wakeup any
4107 * drainers that's blocked waiting for this.
4109 if (--pcb
->ipsec_pcb_data_move
== 0 && pcb
->ipsec_pcb_drainers
> 0) {
4110 wakeup(&(pcb
->ipsec_pcb_data_move
));
4112 lck_mtx_unlock(&pcb
->ipsec_pcb_data_move_lock
);
4116 ipsec_data_move_drain(struct ipsec_pcb
*pcb
)
4118 lck_mtx_lock(&pcb
->ipsec_pcb_data_move_lock
);
4119 /* data path must already be marked as not ready */
4120 VERIFY(!IPSEC_IS_DATA_PATH_READY(pcb
));
4121 pcb
->ipsec_pcb_drainers
++;
4122 while (pcb
->ipsec_pcb_data_move
!= 0) {
4123 (void)msleep(&(pcb
->ipsec_pcb_data_move
), &pcb
->ipsec_pcb_data_move_lock
,
4124 (PZERO
- 1), __func__
, NULL
);
4126 VERIFY(!IPSEC_IS_DATA_PATH_READY(pcb
));
4127 VERIFY(pcb
->ipsec_pcb_drainers
> 0);
4128 pcb
->ipsec_pcb_drainers
--;
4129 lck_mtx_unlock(&pcb
->ipsec_pcb_data_move_lock
);
4133 ipsec_wait_data_move_drain(struct ipsec_pcb
*pcb
)
4136 * Mark the data path as not usable.
4138 lck_mtx_lock(&pcb
->ipsec_pcb_data_move_lock
);
4139 IPSEC_CLR_DATA_PATH_READY(pcb
);
4140 lck_mtx_unlock(&pcb
->ipsec_pcb_data_move_lock
);
4142 /* Wait until all threads in the data paths are done. */
4143 ipsec_data_move_drain(pcb
);