2 * Copyright (c) 2012-2018 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@
29 #include <sys/systm.h>
30 #include <sys/kern_control.h>
31 #include <net/kpi_protocol.h>
32 #include <net/kpi_interface.h>
33 #include <sys/socket.h>
34 #include <sys/socketvar.h>
36 #include <net/if_types.h>
38 #include <net/if_ipsec.h>
40 #include <sys/sockio.h>
41 #include <netinet/in.h>
42 #include <netinet/ip6.h>
43 #include <netinet6/in6_var.h>
44 #include <netinet6/ip6_var.h>
45 #include <sys/kauth.h>
46 #include <netinet6/ipsec.h>
47 #include <netinet6/ipsec6.h>
48 #include <netinet6/esp.h>
49 #include <netinet6/esp6.h>
50 #include <netinet/ip.h>
51 #include <net/flowadv.h>
53 #include <netkey/key.h>
54 #include <net/pktap.h>
55 #include <kern/zalloc.h>
59 extern int net_qos_policy_restricted
;
60 extern int net_qos_policy_restrict_avapps
;
62 /* Kernel Control functions */
63 static errno_t
ipsec_ctl_bind(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
65 static errno_t
ipsec_ctl_connect(kern_ctl_ref kctlref
, struct sockaddr_ctl
*sac
,
67 static errno_t
ipsec_ctl_disconnect(kern_ctl_ref kctlref
, u_int32_t unit
,
69 static errno_t
ipsec_ctl_send(kern_ctl_ref kctlref
, u_int32_t unit
,
70 void *unitinfo
, mbuf_t m
, int flags
);
71 static errno_t
ipsec_ctl_getopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
72 int opt
, void *data
, size_t *len
);
73 static errno_t
ipsec_ctl_setopt(kern_ctl_ref kctlref
, u_int32_t unit
, void *unitinfo
,
74 int opt
, void *data
, size_t len
);
76 /* Network Interface functions */
77 static void ipsec_start(ifnet_t interface
);
78 static errno_t
ipsec_output(ifnet_t interface
, mbuf_t data
);
79 static errno_t
ipsec_demux(ifnet_t interface
, mbuf_t data
, char *frame_header
,
80 protocol_family_t
*protocol
);
81 static errno_t
ipsec_add_proto(ifnet_t interface
, protocol_family_t protocol
,
82 const struct ifnet_demux_desc
*demux_array
,
83 u_int32_t demux_count
);
84 static errno_t
ipsec_del_proto(ifnet_t interface
, protocol_family_t protocol
);
85 static errno_t
ipsec_ioctl(ifnet_t interface
, u_long cmd
, void *data
);
86 static void ipsec_detached(ifnet_t interface
);
88 /* Protocol handlers */
89 static errno_t
ipsec_attach_proto(ifnet_t interface
, protocol_family_t proto
);
90 static errno_t
ipsec_proto_input(ifnet_t interface
, protocol_family_t protocol
,
91 mbuf_t m
, char *frame_header
);
92 static errno_t
ipsec_proto_pre_output(ifnet_t interface
, protocol_family_t protocol
,
93 mbuf_t
*packet
, const struct sockaddr
*dest
, void *route
,
94 char *frame_type
, char *link_layer_dest
);
96 static kern_ctl_ref ipsec_kctlref
;
97 static u_int32_t ipsec_family
;
98 static lck_attr_t
*ipsec_lck_attr
;
99 static lck_grp_attr_t
*ipsec_lck_grp_attr
;
100 static lck_grp_t
*ipsec_lck_grp
;
101 static lck_mtx_t ipsec_lock
;
105 SYSCTL_DECL(_net_ipsec
);
106 SYSCTL_NODE(_net
, OID_AUTO
, ipsec
, CTLFLAG_RW
| CTLFLAG_LOCKED
, 0, "IPsec");
107 static int if_ipsec_verify_interface_creation
= 0;
108 SYSCTL_INT(_net_ipsec
, OID_AUTO
, verify_interface_creation
, CTLFLAG_RW
| CTLFLAG_LOCKED
, &if_ipsec_verify_interface_creation
, 0, "");
110 #define IPSEC_IF_VERIFY(_e) if (__improbable(if_ipsec_verify_interface_creation)) { VERIFY(_e); }
112 #define IPSEC_IF_DEFAULT_SLOT_SIZE 2048
113 #define IPSEC_IF_DEFAULT_RING_SIZE 64
114 #define IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE 64
115 #define IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE 128
116 #define IPSEC_IF_DEFAULT_BUF_SEG_SIZE skmem_usr_buf_seg_size
118 #define IPSEC_IF_MIN_RING_SIZE 16
119 #define IPSEC_IF_MAX_RING_SIZE 1024
121 #define IPSEC_IF_MIN_SLOT_SIZE 1024
122 #define IPSEC_IF_MAX_SLOT_SIZE 4096
124 static int sysctl_if_ipsec_ring_size SYSCTL_HANDLER_ARGS
;
125 static int sysctl_if_ipsec_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
126 static int sysctl_if_ipsec_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
;
128 static int if_ipsec_ring_size
= IPSEC_IF_DEFAULT_RING_SIZE
;
129 static int if_ipsec_tx_fsw_ring_size
= IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE
;
130 static int if_ipsec_rx_fsw_ring_size
= IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE
;
132 SYSCTL_PROC(_net_ipsec
, OID_AUTO
, ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
133 &if_ipsec_ring_size
, IPSEC_IF_DEFAULT_RING_SIZE
, &sysctl_if_ipsec_ring_size
, "I", "");
134 SYSCTL_PROC(_net_ipsec
, OID_AUTO
, tx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
135 &if_ipsec_tx_fsw_ring_size
, IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE
, &sysctl_if_ipsec_tx_fsw_ring_size
, "I", "");
136 SYSCTL_PROC(_net_ipsec
, OID_AUTO
, rx_fsw_ring_size
, CTLTYPE_INT
| CTLFLAG_LOCKED
| CTLFLAG_RW
,
137 &if_ipsec_rx_fsw_ring_size
, IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE
, &sysctl_if_ipsec_rx_fsw_ring_size
, "I", "");
140 ipsec_register_nexus(void);
142 typedef struct ipsec_nx
{
152 static nexus_controller_t ipsec_ncd
;
153 static int ipsec_ncd_refcount
;
154 static uuid_t ipsec_kpipe_uuid
;
156 #endif // IPSEC_NEXUS
158 /* Control block allocated for each kernel control connection */
160 TAILQ_ENTRY(ipsec_pcb
) ipsec_chain
;
161 kern_ctl_ref ipsec_ctlref
;
163 u_int32_t ipsec_unit
;
164 u_int32_t ipsec_unique_id
;
165 u_int32_t ipsec_flags
;
166 u_int32_t ipsec_input_frag_size
;
167 bool ipsec_frag_size_set
;
168 int ipsec_ext_ifdata_stats
;
169 mbuf_svc_class_t ipsec_output_service_class
;
170 char ipsec_if_xname
[IFXNAMSIZ
];
171 char ipsec_unique_name
[IFXNAMSIZ
];
172 // PCB lock protects state fields, like ipsec_kpipe_enabled
173 decl_lck_rw_data(, ipsec_pcb_lock
);
176 lck_mtx_t ipsec_input_chain_lock
;
177 struct mbuf
* ipsec_input_chain
;
178 struct mbuf
* ipsec_input_chain_last
;
179 // Input chain lock protects the list of input mbufs
180 // The input chain lock must be taken AFTER the PCB lock if both are held
181 struct ipsec_nx ipsec_nx
;
182 int ipsec_kpipe_enabled
;
183 uuid_t ipsec_kpipe_uuid
;
184 void * ipsec_kpipe_rxring
;
185 void * ipsec_kpipe_txring
;
186 kern_pbufpool_t ipsec_kpipe_pp
;
188 kern_nexus_t ipsec_netif_nexus
;
189 kern_pbufpool_t ipsec_netif_pp
;
190 void * ipsec_netif_rxring
;
191 void * ipsec_netif_txring
;
192 uint64_t ipsec_netif_txring_size
;
194 u_int32_t ipsec_slot_size
;
195 u_int32_t ipsec_netif_ring_size
;
196 u_int32_t ipsec_tx_fsw_ring_size
;
197 u_int32_t ipsec_rx_fsw_ring_size
;
198 bool ipsec_use_netif
;
199 bool ipsec_needs_netagent
;
200 #endif // IPSEC_NEXUS
203 TAILQ_HEAD(ipsec_list
, ipsec_pcb
) ipsec_head
;
205 #define IPSEC_PCB_ZONE_MAX 32
206 #define IPSEC_PCB_ZONE_NAME "net.if_ipsec"
208 static unsigned int ipsec_pcb_size
; /* size of zone element */
209 static struct zone
*ipsec_pcb_zone
; /* zone for ipsec_pcb */
211 #define IPSECQ_MAXLEN 256
215 sysctl_if_ipsec_ring_size SYSCTL_HANDLER_ARGS
217 #pragma unused(arg1, arg2)
218 int value
= if_ipsec_ring_size
;
220 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
221 if (error
|| !req
->newptr
) {
225 if (value
< IPSEC_IF_MIN_RING_SIZE
||
226 value
> IPSEC_IF_MAX_RING_SIZE
) {
230 if_ipsec_ring_size
= value
;
236 sysctl_if_ipsec_tx_fsw_ring_size SYSCTL_HANDLER_ARGS
238 #pragma unused(arg1, arg2)
239 int value
= if_ipsec_tx_fsw_ring_size
;
241 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
242 if (error
|| !req
->newptr
) {
246 if (value
< IPSEC_IF_MIN_RING_SIZE
||
247 value
> IPSEC_IF_MAX_RING_SIZE
) {
251 if_ipsec_tx_fsw_ring_size
= value
;
257 sysctl_if_ipsec_rx_fsw_ring_size SYSCTL_HANDLER_ARGS
259 #pragma unused(arg1, arg2)
260 int value
= if_ipsec_rx_fsw_ring_size
;
262 int error
= sysctl_handle_int(oidp
, &value
, 0, req
);
263 if (error
|| !req
->newptr
) {
267 if (value
< IPSEC_IF_MIN_RING_SIZE
||
268 value
> IPSEC_IF_MAX_RING_SIZE
) {
272 if_ipsec_rx_fsw_ring_size
= value
;
276 #endif // IPSEC_NEXUS
279 ipsec_register_control(void)
281 struct kern_ctl_reg kern_ctl
;
284 /* Find a unique value for our interface family */
285 result
= mbuf_tag_id_find(IPSEC_CONTROL_NAME
, &ipsec_family
);
287 printf("ipsec_register_control - mbuf_tag_id_find_internal failed: %d\n", result
);
291 ipsec_pcb_size
= sizeof(struct ipsec_pcb
);
292 ipsec_pcb_zone
= zinit(ipsec_pcb_size
,
293 IPSEC_PCB_ZONE_MAX
* ipsec_pcb_size
,
294 0, IPSEC_PCB_ZONE_NAME
);
295 if (ipsec_pcb_zone
== NULL
) {
296 printf("ipsec_register_control - zinit(ipsec_pcb) failed");
301 ipsec_register_nexus();
302 #endif // IPSEC_NEXUS
304 TAILQ_INIT(&ipsec_head
);
306 bzero(&kern_ctl
, sizeof(kern_ctl
));
307 strlcpy(kern_ctl
.ctl_name
, IPSEC_CONTROL_NAME
, sizeof(kern_ctl
.ctl_name
));
308 kern_ctl
.ctl_name
[sizeof(kern_ctl
.ctl_name
) - 1] = 0;
309 kern_ctl
.ctl_flags
= CTL_FLAG_PRIVILEGED
; /* Require root */
310 kern_ctl
.ctl_sendsize
= 64 * 1024;
311 kern_ctl
.ctl_recvsize
= 64 * 1024;
312 kern_ctl
.ctl_bind
= ipsec_ctl_bind
;
313 kern_ctl
.ctl_connect
= ipsec_ctl_connect
;
314 kern_ctl
.ctl_disconnect
= ipsec_ctl_disconnect
;
315 kern_ctl
.ctl_send
= ipsec_ctl_send
;
316 kern_ctl
.ctl_setopt
= ipsec_ctl_setopt
;
317 kern_ctl
.ctl_getopt
= ipsec_ctl_getopt
;
319 result
= ctl_register(&kern_ctl
, &ipsec_kctlref
);
321 printf("ipsec_register_control - ctl_register failed: %d\n", result
);
325 /* Register the protocol plumbers */
326 if ((result
= proto_register_plumber(PF_INET
, ipsec_family
,
327 ipsec_attach_proto
, NULL
)) != 0) {
328 printf("ipsec_register_control - proto_register_plumber(PF_INET, %d) failed: %d\n",
329 ipsec_family
, result
);
330 ctl_deregister(ipsec_kctlref
);
334 /* Register the protocol plumbers */
335 if ((result
= proto_register_plumber(PF_INET6
, ipsec_family
,
336 ipsec_attach_proto
, NULL
)) != 0) {
337 proto_unregister_plumber(PF_INET
, ipsec_family
);
338 ctl_deregister(ipsec_kctlref
);
339 printf("ipsec_register_control - proto_register_plumber(PF_INET6, %d) failed: %d\n",
340 ipsec_family
, result
);
344 ipsec_lck_attr
= lck_attr_alloc_init();
345 ipsec_lck_grp_attr
= lck_grp_attr_alloc_init();
346 ipsec_lck_grp
= lck_grp_alloc_init("ipsec", ipsec_lck_grp_attr
);
347 lck_mtx_init(&ipsec_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
354 ipsec_interface_isvalid (ifnet_t interface
)
356 struct ipsec_pcb
*pcb
= NULL
;
358 if (interface
== NULL
)
361 pcb
= ifnet_softc(interface
);
366 /* When ctl disconnects, ipsec_unit is set to 0 */
367 if (pcb
->ipsec_unit
== 0)
374 ipsec_interface_needs_netagent(ifnet_t interface
)
376 struct ipsec_pcb
*pcb
= NULL
;
378 if (interface
== NULL
) {
382 pcb
= ifnet_softc(interface
);
388 return (pcb
->ipsec_needs_netagent
== true);
392 ipsec_ifnet_set_attrs(ifnet_t ifp
)
394 /* Set flags and additional information. */
395 ifnet_set_mtu(ifp
, 1500);
396 ifnet_set_flags(ifp
, IFF_UP
| IFF_MULTICAST
| IFF_POINTOPOINT
, 0xffff);
398 /* The interface must generate its own IPv6 LinkLocal address,
399 * if possible following the recommendation of RFC2472 to the 64bit interface ID
401 ifnet_set_eflags(ifp
, IFEF_NOAUTOIPV6LL
, IFEF_NOAUTOIPV6LL
);
404 /* Reset the stats in case as the interface may have been recycled */
405 struct ifnet_stats_param stats
;
406 bzero(&stats
, sizeof(struct ifnet_stats_param
));
407 ifnet_set_stat(ifp
, &stats
);
408 #endif // !IPSEC_NEXUS
415 static uuid_t ipsec_nx_dom_prov
;
418 ipsec_nxdp_init(__unused kern_nexus_domain_provider_t domprov
)
424 ipsec_nxdp_fini(__unused kern_nexus_domain_provider_t domprov
)
430 ipsec_register_nexus(void)
432 const struct kern_nexus_domain_provider_init dp_init
= {
433 .nxdpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
435 .nxdpi_init
= ipsec_nxdp_init
,
436 .nxdpi_fini
= ipsec_nxdp_fini
440 /* ipsec_nxdp_init() is called before this function returns */
441 err
= kern_nexus_register_domain_provider(NEXUS_TYPE_NET_IF
,
442 (const uint8_t *) "com.apple.ipsec",
443 &dp_init
, sizeof(dp_init
),
446 printf("%s: failed to register domain provider\n", __func__
);
453 ipsec_netif_prepare(kern_nexus_t nexus
, ifnet_t ifp
)
455 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
456 pcb
->ipsec_netif_nexus
= nexus
;
457 return (ipsec_ifnet_set_attrs(ifp
));
461 ipsec_nexus_pre_connect(kern_nexus_provider_t nxprov
,
462 proc_t p
, kern_nexus_t nexus
,
463 nexus_port_t nexus_port
, kern_channel_t channel
, void **ch_ctx
)
465 #pragma unused(nxprov, p)
466 #pragma unused(nexus, nexus_port, channel, ch_ctx)
471 ipsec_nexus_connected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
472 kern_channel_t channel
)
474 #pragma unused(nxprov, channel)
475 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
476 boolean_t ok
= ifnet_is_attached(pcb
->ipsec_ifp
, 1);
477 return (ok
? 0 : ENXIO
);
481 ipsec_nexus_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
482 kern_channel_t channel
)
484 #pragma unused(nxprov, nexus, channel)
488 ipsec_netif_pre_disconnect(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
489 kern_channel_t channel
)
491 #pragma unused(nxprov, nexus, channel)
495 ipsec_nexus_disconnected(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
496 kern_channel_t channel
)
498 #pragma unused(nxprov, channel)
499 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
500 if (pcb
->ipsec_netif_nexus
== nexus
) {
501 pcb
->ipsec_netif_nexus
= NULL
;
503 ifnet_decr_iorefcnt(pcb
->ipsec_ifp
);
507 ipsec_kpipe_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
508 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
511 #pragma unused(nxprov)
512 #pragma unused(channel)
513 #pragma unused(ring_ctx)
514 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
516 VERIFY(pcb
->ipsec_kpipe_rxring
== NULL
);
517 pcb
->ipsec_kpipe_rxring
= ring
;
519 VERIFY(pcb
->ipsec_kpipe_txring
== NULL
);
520 pcb
->ipsec_kpipe_txring
= ring
;
526 ipsec_kpipe_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
527 kern_channel_ring_t ring
)
529 #pragma unused(nxprov)
530 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
531 if (pcb
->ipsec_kpipe_rxring
== ring
) {
532 pcb
->ipsec_kpipe_rxring
= NULL
;
533 } else if (pcb
->ipsec_kpipe_txring
== ring
) {
534 pcb
->ipsec_kpipe_txring
= NULL
;
539 ipsec_kpipe_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
540 kern_channel_ring_t tx_ring
, uint32_t flags
)
542 #pragma unused(nxprov)
543 #pragma unused(flags)
544 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
546 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
547 int channel_enabled
= pcb
->ipsec_kpipe_enabled
;
548 if (!channel_enabled
) {
549 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
553 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
554 if (tx_slot
== NULL
) {
555 // Nothing to write, bail
556 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
560 // Signal the netif ring to read
561 kern_channel_ring_t rx_ring
= pcb
->ipsec_netif_rxring
;
562 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
564 if (rx_ring
!= NULL
) {
565 kern_channel_notify(rx_ring
, 0);
571 ipsec_encrypt_mbuf(ifnet_t interface
,
574 struct ipsec_output_state ipsec_state
;
578 // Make sure this packet isn't looping through the interface
579 if (necp_get_last_interface_index_from_packet(data
) == interface
->if_index
) {
581 goto ipsec_output_err
;
584 // Mark the interface so NECP can evaluate tunnel policy
585 necp_mark_packet_from_interface(data
, interface
);
587 struct ip
*ip
= mtod(data
, struct ip
*);
588 u_int ip_version
= ip
->ip_v
;
590 switch (ip_version
) {
594 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
595 ipsec_state
.m
= data
;
596 ipsec_state
.dst
= (struct sockaddr
*)&ip
->ip_dst
;
597 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
599 error
= ipsec4_interface_output(&ipsec_state
, interface
);
600 if (error
== 0 && ipsec_state
.tunneled
== 6) {
601 // Tunneled in IPv6 - packet is gone
602 // TODO: Don't lose mbuf
607 data
= ipsec_state
.m
;
608 if (error
|| data
== NULL
) {
610 printf("ipsec_encrypt_mbuf: ipsec4_output error %d\n", error
);
612 goto ipsec_output_err
;
619 data
= ipsec6_splithdr(data
);
621 printf("ipsec_encrypt_mbuf: ipsec6_splithdr returned NULL\n");
622 goto ipsec_output_err
;
625 struct ip6_hdr
*ip6
= mtod(data
, struct ip6_hdr
*);
627 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
628 ipsec_state
.m
= data
;
629 ipsec_state
.dst
= (struct sockaddr
*)&ip6
->ip6_dst
;
630 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
632 error
= ipsec6_interface_output(&ipsec_state
, interface
, &ip6
->ip6_nxt
, ipsec_state
.m
);
633 if (error
== 0 && ipsec_state
.tunneled
== 4) {
634 // Tunneled in IPv4 - packet is gone
635 // TODO: Don't lose mbuf
639 data
= ipsec_state
.m
;
640 if (error
|| data
== NULL
) {
642 printf("ipsec_encrypt_mbuf: ipsec6_output error %d\n", error
);
644 goto ipsec_output_err
;
649 printf("ipsec_encrypt_mbuf: Received unknown packet version %d\n", ip_version
);
651 goto ipsec_output_err
;
666 ipsec_kpipe_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
667 kern_channel_ring_t rx_ring
, uint32_t flags
)
669 #pragma unused(nxprov)
670 #pragma unused(flags)
671 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
672 struct kern_channel_ring_stat_increment rx_ring_stats
;
674 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
676 int channel_enabled
= pcb
->ipsec_kpipe_enabled
;
677 if (!channel_enabled
) {
678 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
682 // Reclaim user-released slots
683 (void) kern_channel_reclaim(rx_ring
);
685 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
687 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
691 kern_channel_ring_t tx_ring
= pcb
->ipsec_netif_txring
;
692 if (tx_ring
== NULL
) {
693 // Net-If TX ring not set up yet, nothing to read
694 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
698 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(pcb
->ipsec_netif_nexus
)->nif_stats
;
700 // Unlock ipsec before entering ring
701 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
703 (void)kr_enter(tx_ring
, TRUE
);
705 // Lock again after entering and validate
706 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
707 if (tx_ring
!= pcb
->ipsec_netif_txring
) {
708 // Ring no longer valid
709 // Unlock first, then exit ring
710 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
716 struct kern_channel_ring_stat_increment tx_ring_stats
;
717 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
718 kern_channel_slot_t tx_pslot
= NULL
;
719 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
720 if (tx_slot
== NULL
) {
721 // Nothing to read, don't bother signalling
722 // Unlock first, then exit ring
723 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
728 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
729 VERIFY(rx_pp
!= NULL
);
730 bzero(&rx_ring_stats
, sizeof(rx_ring_stats
));
731 kern_channel_slot_t rx_pslot
= NULL
;
732 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
734 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
739 // Allocate rx packet
740 kern_packet_t rx_ph
= 0;
741 error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
742 if (__improbable(error
!= 0)) {
743 printf("ipsec_kpipe_sync_rx %s: failed to allocate packet\n",
744 pcb
->ipsec_ifp
->if_xname
);
748 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
752 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
755 kern_pbufpool_free(rx_pp
, rx_ph
);
759 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
760 VERIFY(tx_buf
!= NULL
);
761 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
762 VERIFY(tx_baddr
!= NULL
);
763 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
765 bpf_tap_packet_out(pcb
->ipsec_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
767 length
= MIN(kern_packet_get_data_length(tx_ph
),
768 pcb
->ipsec_slot_size
);
770 // Increment TX stats
771 tx_ring_stats
.kcrsi_slots_transferred
++;
772 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
775 error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
777 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
779 // Encrypt and send packet
780 data
= ipsec_encrypt_mbuf(pcb
->ipsec_ifp
, data
);
782 printf("ipsec_kpipe_sync_rx %s - mbuf_copyback(%zu) error %d\n", pcb
->ipsec_ifp
->if_xname
, length
, error
);
783 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
784 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
789 printf("ipsec_kpipe_sync_rx %s - mbuf_gethdr error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
790 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
791 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
794 printf("ipsec_kpipe_sync_rx %s - 0 length packet\n", pcb
->ipsec_ifp
->if_xname
);
795 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
796 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
800 printf("ipsec_kpipe_sync_rx %s: no encrypted packet to send\n", pcb
->ipsec_ifp
->if_xname
);
801 kern_pbufpool_free(rx_pp
, rx_ph
);
805 length
= mbuf_pkthdr_len(data
);
806 if (length
> rx_pp
->pp_buflet_size
) {
809 kern_pbufpool_free(rx_pp
, rx_ph
);
810 printf("ipsec_kpipe_sync_rx %s: encrypted packet length %zu > %u\n",
811 pcb
->ipsec_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
816 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
817 VERIFY(rx_buf
!= NULL
);
818 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
819 VERIFY(rx_baddr
!= NULL
);
821 // Copy-in data from mbuf to buflet
822 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
823 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
825 // Finalize and attach the packet
826 error
= kern_buflet_set_data_offset(rx_buf
, 0);
828 error
= kern_buflet_set_data_length(rx_buf
, length
);
830 error
= kern_packet_finalize(rx_ph
);
832 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
835 STATS_INC(nifs
, NETIF_STATS_TXPKTS
);
836 STATS_INC(nifs
, NETIF_STATS_TXCOPY_DIRECT
);
838 rx_ring_stats
.kcrsi_slots_transferred
++;
839 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
841 if (!pcb
->ipsec_ext_ifdata_stats
) {
842 ifnet_stat_increment_out(pcb
->ipsec_ifp
, 1, length
, 0);
848 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
852 kern_channel_advance_slot(rx_ring
, rx_pslot
);
853 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->ipsec_ifp
, &rx_ring_stats
);
857 kern_channel_advance_slot(tx_ring
, tx_pslot
);
858 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->ipsec_ifp
, &tx_ring_stats
);
859 (void)kern_channel_reclaim(tx_ring
);
862 /* always reenable output */
863 errno_t error
= ifnet_enable_output(pcb
->ipsec_ifp
);
865 printf("ipsec_kpipe_sync_rx: ifnet_enable_output returned error %d\n", error
);
868 // Unlock first, then exit ring
869 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
871 if (tx_pslot
!= NULL
) {
872 kern_channel_notify(tx_ring
, 0);
880 ipsec_netif_ring_init(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
881 kern_channel_t channel
, kern_channel_ring_t ring
, boolean_t is_tx_ring
,
884 #pragma unused(nxprov)
885 #pragma unused(channel)
886 #pragma unused(ring_ctx)
887 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
889 VERIFY(pcb
->ipsec_netif_rxring
== NULL
);
890 pcb
->ipsec_netif_rxring
= ring
;
892 VERIFY(pcb
->ipsec_netif_txring
== NULL
);
893 pcb
->ipsec_netif_txring
= ring
;
899 ipsec_netif_ring_fini(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
900 kern_channel_ring_t ring
)
902 #pragma unused(nxprov)
903 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
904 if (pcb
->ipsec_netif_rxring
== ring
) {
905 pcb
->ipsec_netif_rxring
= NULL
;
906 } else if (pcb
->ipsec_netif_txring
== ring
) {
907 pcb
->ipsec_netif_txring
= NULL
;
912 ipsec_netif_check_policy(mbuf_t data
)
914 necp_kernel_policy_result necp_result
= 0;
915 necp_kernel_policy_result_parameter necp_result_parameter
= {};
916 uint32_t necp_matched_policy_id
= 0;
918 // This packet has been marked with IP level policy, do not mark again.
919 if (data
&& data
->m_pkthdr
.necp_mtag
.necp_policy_id
>= NECP_KERNEL_POLICY_ID_FIRST_VALID_IP
) {
923 size_t length
= mbuf_pkthdr_len(data
);
924 if (length
< sizeof(struct ip
)) {
928 struct ip
*ip
= mtod(data
, struct ip
*);
929 u_int ip_version
= ip
->ip_v
;
930 switch (ip_version
) {
932 necp_matched_policy_id
= necp_ip_output_find_policy_match(data
, 0, NULL
,
933 &necp_result
, &necp_result_parameter
);
937 necp_matched_policy_id
= necp_ip6_output_find_policy_match(data
, 0, NULL
,
938 &necp_result
, &necp_result_parameter
);
946 if (necp_result
== NECP_KERNEL_POLICY_RESULT_DROP
||
947 necp_result
== NECP_KERNEL_POLICY_RESULT_SOCKET_DIVERT
) {
948 /* Drop and flow divert packets should be blocked at the IP layer */
952 necp_mark_packet_from_ip(data
, necp_matched_policy_id
);
957 ipsec_netif_sync_tx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
958 kern_channel_ring_t tx_ring
, uint32_t flags
)
960 #pragma unused(nxprov)
961 #pragma unused(flags)
962 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
964 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
966 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
968 struct kern_channel_ring_stat_increment tx_ring_stats
;
969 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
970 kern_channel_slot_t tx_pslot
= NULL
;
971 kern_channel_slot_t tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
973 STATS_INC(nifs
, NETIF_STATS_TXSYNC
);
975 if (tx_slot
== NULL
) {
976 // Nothing to write, don't bother signalling
977 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
981 if (pcb
->ipsec_kpipe_enabled
) {
982 kern_channel_ring_t rx_ring
= pcb
->ipsec_kpipe_rxring
;
983 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
985 // Signal the kernel pipe ring to read
986 if (rx_ring
!= NULL
) {
987 kern_channel_notify(rx_ring
, 0);
992 // If we're here, we're injecting into the BSD stack
993 while (tx_slot
!= NULL
) {
997 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
1001 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
1007 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
1008 VERIFY(tx_buf
!= NULL
);
1009 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
1010 VERIFY(tx_baddr
!= 0);
1011 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
1013 bpf_tap_packet_out(pcb
->ipsec_ifp
, DLT_RAW
, tx_ph
, NULL
, 0);
1015 length
= MIN(kern_packet_get_data_length(tx_ph
),
1016 pcb
->ipsec_slot_size
);
1019 errno_t error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
1021 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
1023 // Mark packet from policy
1024 uint32_t policy_id
= kern_packet_get_policy_id(tx_ph
);
1025 necp_mark_packet_from_ip(data
, policy_id
);
1027 // Check policy with NECP
1028 if (!ipsec_netif_check_policy(data
)) {
1029 printf("ipsec_netif_sync_tx %s - failed policy check\n", pcb
->ipsec_ifp
->if_xname
);
1030 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1034 // Send through encryption
1035 error
= ipsec_output(pcb
->ipsec_ifp
, data
);
1037 printf("ipsec_netif_sync_tx %s - ipsec_output error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
1041 printf("ipsec_netif_sync_tx %s - mbuf_copyback(%zu) error %d\n", pcb
->ipsec_ifp
->if_xname
, length
, error
);
1042 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
1043 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1048 printf("ipsec_netif_sync_tx %s - mbuf_gethdr error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
1049 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
1050 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1053 printf("ipsec_netif_sync_tx %s - 0 length packet\n", pcb
->ipsec_ifp
->if_xname
);
1054 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1055 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1059 printf("ipsec_netif_sync_tx %s: no encrypted packet to send\n", pcb
->ipsec_ifp
->if_xname
);
1063 STATS_INC(nifs
, NETIF_STATS_TXPKTS
);
1064 STATS_INC(nifs
, NETIF_STATS_TXCOPY_MBUF
);
1066 tx_ring_stats
.kcrsi_slots_transferred
++;
1067 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1071 kern_channel_advance_slot(tx_ring
, tx_pslot
);
1072 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->ipsec_ifp
, &tx_ring_stats
);
1073 (void)kern_channel_reclaim(tx_ring
);
1076 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1082 ipsec_netif_tx_doorbell(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1083 kern_channel_ring_t ring
, __unused
uint32_t flags
)
1085 #pragma unused(nxprov)
1086 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1087 boolean_t more
= false;
1091 * Refill and sync the ring; we may be racing against another thread doing
1092 * an RX sync that also wants to do kr_enter(), and so use the blocking
1095 rc
= kern_channel_tx_refill_canblock(ring
, UINT32_MAX
, UINT32_MAX
, true, &more
);
1096 if (rc
!= 0 && rc
!= EAGAIN
&& rc
!= EBUSY
) {
1097 printf("%s, tx refill failed %d\n", __func__
, rc
);
1100 (void) kr_enter(ring
, TRUE
);
1101 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1103 if (pcb
->ipsec_kpipe_enabled
) {
1104 uint32_t tx_available
= kern_channel_available_slot_count(ring
);
1105 if (pcb
->ipsec_netif_txring_size
> 0 &&
1106 tx_available
>= pcb
->ipsec_netif_txring_size
- 1) {
1107 // No room left in tx ring, disable output for now
1108 errno_t error
= ifnet_disable_output(pcb
->ipsec_ifp
);
1110 printf("ipsec_netif_tx_doorbell: ifnet_disable_output returned error %d\n", error
);
1115 if (pcb
->ipsec_kpipe_enabled
) {
1116 kern_channel_ring_t rx_ring
= pcb
->ipsec_kpipe_rxring
;
1118 // Unlock while calling notify
1119 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1120 // Signal the kernel pipe ring to read
1121 if (rx_ring
!= NULL
) {
1122 kern_channel_notify(rx_ring
, 0);
1125 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1134 ipsec_netif_sync_rx(kern_nexus_provider_t nxprov
, kern_nexus_t nexus
,
1135 kern_channel_ring_t rx_ring
, uint32_t flags
)
1137 #pragma unused(nxprov)
1138 #pragma unused(flags)
1139 struct ipsec_pcb
*pcb
= kern_nexus_get_context(nexus
);
1140 struct kern_channel_ring_stat_increment rx_ring_stats
;
1142 struct netif_stats
*nifs
= &NX_NETIF_PRIVATE(nexus
)->nif_stats
;
1144 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1146 // Reclaim user-released slots
1147 (void) kern_channel_reclaim(rx_ring
);
1149 STATS_INC(nifs
, NETIF_STATS_RXSYNC
);
1151 uint32_t avail
= kern_channel_available_slot_count(rx_ring
);
1153 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1157 struct kern_pbufpool
*rx_pp
= rx_ring
->ckr_pp
;
1158 VERIFY(rx_pp
!= NULL
);
1159 bzero(&rx_ring_stats
, sizeof(rx_ring_stats
));
1160 kern_channel_slot_t rx_pslot
= NULL
;
1161 kern_channel_slot_t rx_slot
= kern_channel_get_next_slot(rx_ring
, NULL
, NULL
);
1163 while (rx_slot
!= NULL
) {
1164 // Check for a waiting packet
1165 lck_mtx_lock(&pcb
->ipsec_input_chain_lock
);
1166 mbuf_t data
= pcb
->ipsec_input_chain
;
1168 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1172 // Allocate rx packet
1173 kern_packet_t rx_ph
= 0;
1174 errno_t error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
1175 if (__improbable(error
!= 0)) {
1176 STATS_INC(nifs
, NETIF_STATS_NOMEM_PKT
);
1177 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1178 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1182 // Advance waiting packets
1183 pcb
->ipsec_input_chain
= data
->m_nextpkt
;
1184 data
->m_nextpkt
= NULL
;
1185 if (pcb
->ipsec_input_chain
== NULL
) {
1186 pcb
->ipsec_input_chain_last
= NULL
;
1188 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1190 size_t length
= mbuf_pkthdr_len(data
);
1192 if (length
< sizeof(struct ip
)) {
1195 kern_pbufpool_free(rx_pp
, rx_ph
);
1196 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1197 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1198 printf("ipsec_netif_sync_rx %s: legacy decrypted packet length cannot hold IP %zu < %zu\n",
1199 pcb
->ipsec_ifp
->if_xname
, length
, sizeof(struct ip
));
1204 struct ip
*ip
= mtod(data
, struct ip
*);
1205 u_int ip_version
= ip
->ip_v
;
1206 switch (ip_version
) {
1216 printf("ipsec_netif_sync_rx %s: legacy unknown ip version %u\n",
1217 pcb
->ipsec_ifp
->if_xname
, ip_version
);
1222 if (length
> rx_pp
->pp_buflet_size
||
1223 (pcb
->ipsec_frag_size_set
&& length
> pcb
->ipsec_input_frag_size
)) {
1225 // We need to fragment to send up into the netif
1227 u_int32_t fragment_mtu
= rx_pp
->pp_buflet_size
;
1228 if (pcb
->ipsec_frag_size_set
&&
1229 pcb
->ipsec_input_frag_size
< rx_pp
->pp_buflet_size
) {
1230 fragment_mtu
= pcb
->ipsec_input_frag_size
;
1233 mbuf_t fragment_chain
= NULL
;
1236 // ip_fragment expects the length in host order
1237 ip
->ip_len
= ntohs(ip
->ip_len
);
1239 // ip_fragment will modify the original data, don't free
1240 int fragment_error
= ip_fragment(data
, pcb
->ipsec_ifp
, fragment_mtu
, TRUE
);
1241 if (fragment_error
== 0 && data
!= NULL
) {
1242 fragment_chain
= data
;
1244 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1245 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1246 printf("ipsec_netif_sync_rx %s: failed to fragment IPv4 packet of length %zu (%d)\n",
1247 pcb
->ipsec_ifp
->if_xname
, length
, fragment_error
);
1252 if (length
< sizeof(struct ip6_hdr
)) {
1254 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1255 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1256 printf("ipsec_netif_sync_rx %s: failed to fragment IPv6 packet of length %zu < %zu\n",
1257 pcb
->ipsec_ifp
->if_xname
, length
, sizeof(struct ip6_hdr
));
1260 // ip6_do_fragmentation will free the original data on success only
1261 struct ip6_hdr
*ip6
= mtod(data
, struct ip6_hdr
*);
1262 struct ip6_exthdrs exthdrs
;
1263 memset(&exthdrs
, 0, sizeof(exthdrs
));
1265 int fragment_error
= ip6_do_fragmentation(&data
, 0, pcb
->ipsec_ifp
, sizeof(struct ip6_hdr
),
1266 ip6
, &exthdrs
, fragment_mtu
, ip6
->ip6_nxt
);
1267 if (fragment_error
== 0 && data
!= NULL
) {
1268 fragment_chain
= data
;
1271 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1272 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1273 printf("ipsec_netif_sync_rx %s: failed to fragment IPv6 packet of length %zu (%d)\n",
1274 pcb
->ipsec_ifp
->if_xname
, length
, fragment_error
);
1280 // Cannot fragment unknown families
1282 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1283 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1284 printf("ipsec_netif_sync_rx %s: uknown legacy decrypted packet length %zu > %u\n",
1285 pcb
->ipsec_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
1290 if (fragment_chain
!= NULL
) {
1291 // Add fragments to chain before continuing
1292 lck_mtx_lock(&pcb
->ipsec_input_chain_lock
);
1293 if (pcb
->ipsec_input_chain
!= NULL
) {
1294 pcb
->ipsec_input_chain_last
->m_nextpkt
= fragment_chain
;
1296 pcb
->ipsec_input_chain
= fragment_chain
;
1298 while (fragment_chain
->m_nextpkt
) {
1299 VERIFY(fragment_chain
!= fragment_chain
->m_nextpkt
);
1300 fragment_chain
= fragment_chain
->m_nextpkt
;
1302 pcb
->ipsec_input_chain_last
= fragment_chain
;
1303 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
1306 // Make sure to free unused rx packet
1307 kern_pbufpool_free(rx_pp
, rx_ph
);
1312 mbuf_pkthdr_setrcvif(data
, pcb
->ipsec_ifp
);
1314 // Fillout rx packet
1315 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
1316 VERIFY(rx_buf
!= NULL
);
1317 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
1318 VERIFY(rx_baddr
!= NULL
);
1320 // Copy-in data from mbuf to buflet
1321 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
1322 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
1324 // Finalize and attach the packet
1325 error
= kern_buflet_set_data_offset(rx_buf
, 0);
1327 error
= kern_buflet_set_data_length(rx_buf
, length
);
1329 error
= kern_packet_set_link_header_offset(rx_ph
, 0);
1331 error
= kern_packet_set_network_header_offset(rx_ph
, 0);
1333 error
= kern_packet_finalize(rx_ph
);
1335 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
1338 STATS_INC(nifs
, NETIF_STATS_RXPKTS
);
1339 STATS_INC(nifs
, NETIF_STATS_RXCOPY_MBUF
);
1340 bpf_tap_packet_in(pcb
->ipsec_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
1342 rx_ring_stats
.kcrsi_slots_transferred
++;
1343 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1345 if (!pcb
->ipsec_ext_ifdata_stats
) {
1346 ifnet_stat_increment_in(pcb
->ipsec_ifp
, 1, length
, 0);
1353 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
1356 struct kern_channel_ring_stat_increment tx_ring_stats
;
1357 bzero(&tx_ring_stats
, sizeof(tx_ring_stats
));
1358 kern_channel_ring_t tx_ring
= pcb
->ipsec_kpipe_txring
;
1359 kern_channel_slot_t tx_pslot
= NULL
;
1360 kern_channel_slot_t tx_slot
= NULL
;
1361 if (tx_ring
== NULL
) {
1362 // Net-If TX ring not set up yet, nothing to read
1367 // Unlock ipsec before entering ring
1368 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1370 (void)kr_enter(tx_ring
, TRUE
);
1372 // Lock again after entering and validate
1373 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
1375 if (tx_ring
!= pcb
->ipsec_kpipe_txring
) {
1379 tx_slot
= kern_channel_get_next_slot(tx_ring
, NULL
, NULL
);
1380 if (tx_slot
== NULL
) {
1381 // Nothing to read, don't bother signalling
1385 while (rx_slot
!= NULL
&& tx_slot
!= NULL
) {
1391 // Allocate rx packet
1392 kern_packet_t rx_ph
= 0;
1393 error
= kern_pbufpool_alloc_nosleep(rx_pp
, 1, &rx_ph
);
1394 if (__improbable(error
!= 0)) {
1395 STATS_INC(nifs
, NETIF_STATS_NOMEM_PKT
);
1396 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1400 kern_packet_t tx_ph
= kern_channel_slot_get_packet(tx_ring
, tx_slot
);
1404 tx_slot
= kern_channel_get_next_slot(tx_ring
, tx_slot
, NULL
);
1407 kern_pbufpool_free(rx_pp
, rx_ph
);
1411 kern_buflet_t tx_buf
= kern_packet_get_next_buflet(tx_ph
, NULL
);
1412 VERIFY(tx_buf
!= NULL
);
1413 uint8_t *tx_baddr
= kern_buflet_get_object_address(tx_buf
);
1414 VERIFY(tx_baddr
!= 0);
1415 tx_baddr
+= kern_buflet_get_data_offset(tx_buf
);
1417 length
= MIN(kern_packet_get_data_length(tx_ph
),
1418 pcb
->ipsec_slot_size
);
1420 // Increment TX stats
1421 tx_ring_stats
.kcrsi_slots_transferred
++;
1422 tx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1424 if (length
>= sizeof(struct ip
)) {
1425 error
= mbuf_gethdr(MBUF_DONTWAIT
, MBUF_TYPE_HEADER
, &data
);
1427 error
= mbuf_copyback(data
, 0, length
, tx_baddr
, MBUF_DONTWAIT
);
1429 struct ip
*ip
= mtod(data
, struct ip
*);
1430 u_int ip_version
= ip
->ip_v
;
1431 switch (ip_version
) {
1434 ip
->ip_len
= ntohs(ip
->ip_len
) - sizeof(struct ip
);
1435 ip
->ip_off
= ntohs(ip
->ip_off
);
1437 if (length
< ip
->ip_len
) {
1438 printf("ipsec_netif_sync_rx %s: IPv4 packet length too short (%zu < %u)\n",
1439 pcb
->ipsec_ifp
->if_xname
, length
, ip
->ip_len
);
1440 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1441 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1445 data
= esp4_input_extended(data
, sizeof(struct ip
), pcb
->ipsec_ifp
);
1450 if (length
< sizeof(struct ip6_hdr
)) {
1451 printf("ipsec_netif_sync_rx %s: IPv6 packet length too short for header %zu\n",
1452 pcb
->ipsec_ifp
->if_xname
, length
);
1453 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1454 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1459 struct ip6_hdr
*ip6
= mtod(data
, struct ip6_hdr
*);
1460 const size_t ip6_len
= sizeof(*ip6
) + ntohs(ip6
->ip6_plen
);
1461 if (length
< ip6_len
) {
1462 printf("ipsec_netif_sync_rx %s: IPv6 packet length too short (%zu < %zu)\n",
1463 pcb
->ipsec_ifp
->if_xname
, length
, ip6_len
);
1464 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1465 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1469 int offset
= sizeof(struct ip6_hdr
);
1470 esp6_input_extended(&data
, &offset
, ip6
->ip6_nxt
, pcb
->ipsec_ifp
);
1476 printf("ipsec_netif_sync_rx %s: unknown ip version %u\n",
1477 pcb
->ipsec_ifp
->if_xname
, ip_version
);
1478 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1485 printf("ipsec_netif_sync_rx %s - mbuf_copyback(%zu) error %d\n", pcb
->ipsec_ifp
->if_xname
, length
, error
);
1486 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
1487 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1492 printf("ipsec_netif_sync_rx %s - mbuf_gethdr error %d\n", pcb
->ipsec_ifp
->if_xname
, error
);
1493 STATS_INC(nifs
, NETIF_STATS_NOMEM_MBUF
);
1494 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1497 printf("ipsec_netif_sync_rx %s - bad packet length %zu\n", pcb
->ipsec_ifp
->if_xname
, length
);
1498 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1499 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1503 // Failed to get decrypted data data
1504 kern_pbufpool_free(rx_pp
, rx_ph
);
1508 length
= mbuf_pkthdr_len(data
);
1509 if (length
> rx_pp
->pp_buflet_size
) {
1512 kern_pbufpool_free(rx_pp
, rx_ph
);
1513 STATS_INC(nifs
, NETIF_STATS_BADLEN
);
1514 STATS_INC(nifs
, NETIF_STATS_DROPPED
);
1515 printf("ipsec_netif_sync_rx %s: decrypted packet length %zu > %u\n",
1516 pcb
->ipsec_ifp
->if_xname
, length
, rx_pp
->pp_buflet_size
);
1520 mbuf_pkthdr_setrcvif(data
, pcb
->ipsec_ifp
);
1522 // Fillout rx packet
1523 kern_buflet_t rx_buf
= kern_packet_get_next_buflet(rx_ph
, NULL
);
1524 VERIFY(rx_buf
!= NULL
);
1525 void *rx_baddr
= kern_buflet_get_object_address(rx_buf
);
1526 VERIFY(rx_baddr
!= NULL
);
1528 // Copy-in data from mbuf to buflet
1529 mbuf_copydata(data
, 0, length
, (void *)rx_baddr
);
1530 kern_packet_clear_flow_uuid(rx_ph
); // Zero flow id
1532 // Finalize and attach the packet
1533 error
= kern_buflet_set_data_offset(rx_buf
, 0);
1535 error
= kern_buflet_set_data_length(rx_buf
, length
);
1537 error
= kern_packet_set_link_header_offset(rx_ph
, 0);
1539 error
= kern_packet_set_network_header_offset(rx_ph
, 0);
1541 error
= kern_packet_finalize(rx_ph
);
1543 error
= kern_channel_slot_attach_packet(rx_ring
, rx_slot
, rx_ph
);
1546 STATS_INC(nifs
, NETIF_STATS_RXPKTS
);
1547 STATS_INC(nifs
, NETIF_STATS_RXCOPY_DIRECT
);
1548 bpf_tap_packet_in(pcb
->ipsec_ifp
, DLT_RAW
, rx_ph
, NULL
, 0);
1550 rx_ring_stats
.kcrsi_slots_transferred
++;
1551 rx_ring_stats
.kcrsi_bytes_transferred
+= length
;
1553 if (!pcb
->ipsec_ext_ifdata_stats
) {
1554 ifnet_stat_increment_in(pcb
->ipsec_ifp
, 1, length
, 0);
1560 rx_slot
= kern_channel_get_next_slot(rx_ring
, rx_slot
, NULL
);
1565 kern_channel_advance_slot(rx_ring
, rx_pslot
);
1566 kern_channel_increment_ring_net_stats(rx_ring
, pcb
->ipsec_ifp
, &rx_ring_stats
);
1570 kern_channel_advance_slot(tx_ring
, tx_pslot
);
1571 kern_channel_increment_ring_net_stats(tx_ring
, pcb
->ipsec_ifp
, &tx_ring_stats
);
1572 (void)kern_channel_reclaim(tx_ring
);
1575 // Unlock first, then exit ring
1576 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
1577 if (tx_ring
!= NULL
) {
1578 if (tx_pslot
!= NULL
) {
1579 kern_channel_notify(tx_ring
, 0);
1588 ipsec_nexus_ifattach(struct ipsec_pcb
*pcb
,
1589 struct ifnet_init_eparams
*init_params
,
1593 nexus_controller_t controller
= kern_nexus_shared_controller();
1594 struct kern_nexus_net_init net_init
;
1595 struct kern_pbufpool_init pp_init
;
1597 nexus_name_t provider_name
;
1598 snprintf((char *)provider_name
, sizeof(provider_name
),
1599 "com.apple.netif.%s", pcb
->ipsec_if_xname
);
1601 struct kern_nexus_provider_init prov_init
= {
1602 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
1603 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
1604 .nxpi_pre_connect
= ipsec_nexus_pre_connect
,
1605 .nxpi_connected
= ipsec_nexus_connected
,
1606 .nxpi_pre_disconnect
= ipsec_netif_pre_disconnect
,
1607 .nxpi_disconnected
= ipsec_nexus_disconnected
,
1608 .nxpi_ring_init
= ipsec_netif_ring_init
,
1609 .nxpi_ring_fini
= ipsec_netif_ring_fini
,
1610 .nxpi_slot_init
= NULL
,
1611 .nxpi_slot_fini
= NULL
,
1612 .nxpi_sync_tx
= ipsec_netif_sync_tx
,
1613 .nxpi_sync_rx
= ipsec_netif_sync_rx
,
1614 .nxpi_tx_doorbell
= ipsec_netif_tx_doorbell
,
1617 nexus_attr_t nxa
= NULL
;
1618 err
= kern_nexus_attr_create(&nxa
);
1619 IPSEC_IF_VERIFY(err
== 0);
1621 printf("%s: kern_nexus_attr_create failed: %d\n",
1626 uint64_t slot_buffer_size
= pcb
->ipsec_slot_size
;
1627 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1630 // Reset ring size for netif nexus to limit memory usage
1631 uint64_t ring_size
= pcb
->ipsec_netif_ring_size
;
1632 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
1634 err
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
1637 pcb
->ipsec_netif_txring_size
= ring_size
;
1639 bzero(&pp_init
, sizeof (pp_init
));
1640 pp_init
.kbi_version
= KERN_PBUFPOOL_CURRENT_VERSION
;
1641 pp_init
.kbi_packets
= pcb
->ipsec_netif_ring_size
* 2;
1642 pp_init
.kbi_bufsize
= pcb
->ipsec_slot_size
;
1643 pp_init
.kbi_buf_seg_size
= IPSEC_IF_DEFAULT_BUF_SEG_SIZE
;
1644 pp_init
.kbi_max_frags
= 1;
1645 (void) snprintf((char *)pp_init
.kbi_name
, sizeof (pp_init
.kbi_name
),
1646 "%s", provider_name
);
1648 err
= kern_pbufpool_create(&pp_init
, &pp_init
, &pcb
->ipsec_netif_pp
, NULL
);
1650 printf("%s pbufbool create failed, error %d\n", __func__
, err
);
1654 err
= kern_nexus_controller_register_provider(controller
,
1660 &pcb
->ipsec_nx
.if_provider
);
1661 IPSEC_IF_VERIFY(err
== 0);
1663 printf("%s register provider failed, error %d\n",
1668 bzero(&net_init
, sizeof(net_init
));
1669 net_init
.nxneti_version
= KERN_NEXUS_NET_CURRENT_VERSION
;
1670 net_init
.nxneti_flags
= 0;
1671 net_init
.nxneti_eparams
= init_params
;
1672 net_init
.nxneti_lladdr
= NULL
;
1673 net_init
.nxneti_prepare
= ipsec_netif_prepare
;
1674 net_init
.nxneti_tx_pbufpool
= pcb
->ipsec_netif_pp
;
1675 err
= kern_nexus_controller_alloc_net_provider_instance(controller
,
1676 pcb
->ipsec_nx
.if_provider
,
1678 &pcb
->ipsec_nx
.if_instance
,
1681 IPSEC_IF_VERIFY(err
== 0);
1683 printf("%s alloc_net_provider_instance failed, %d\n",
1685 kern_nexus_controller_deregister_provider(controller
,
1686 pcb
->ipsec_nx
.if_provider
);
1687 uuid_clear(pcb
->ipsec_nx
.if_provider
);
1693 kern_nexus_attr_destroy(nxa
);
1695 if (err
&& pcb
->ipsec_netif_pp
!= NULL
) {
1696 kern_pbufpool_destroy(pcb
->ipsec_netif_pp
);
1697 pcb
->ipsec_netif_pp
= NULL
;
1703 ipsec_detach_provider_and_instance(uuid_t provider
, uuid_t instance
)
1705 nexus_controller_t controller
= kern_nexus_shared_controller();
1708 if (!uuid_is_null(instance
)) {
1709 err
= kern_nexus_controller_free_provider_instance(controller
,
1712 printf("%s free_provider_instance failed %d\n",
1715 uuid_clear(instance
);
1717 if (!uuid_is_null(provider
)) {
1718 err
= kern_nexus_controller_deregister_provider(controller
,
1721 printf("%s deregister_provider %d\n", __func__
, err
);
1723 uuid_clear(provider
);
1729 ipsec_nexus_detach(struct ipsec_pcb
*pcb
)
1731 ipsec_nx_t nx
= &pcb
->ipsec_nx
;
1732 nexus_controller_t controller
= kern_nexus_shared_controller();
1735 if (!uuid_is_null(nx
->ms_host
)) {
1736 err
= kern_nexus_ifdetach(controller
,
1740 printf("%s: kern_nexus_ifdetach ms host failed %d\n",
1745 if (!uuid_is_null(nx
->ms_device
)) {
1746 err
= kern_nexus_ifdetach(controller
,
1750 printf("%s: kern_nexus_ifdetach ms device failed %d\n",
1755 ipsec_detach_provider_and_instance(nx
->if_provider
,
1757 ipsec_detach_provider_and_instance(nx
->ms_provider
,
1760 if (pcb
->ipsec_netif_pp
!= NULL
) {
1761 kern_pbufpool_destroy(pcb
->ipsec_netif_pp
);
1762 pcb
->ipsec_netif_pp
= NULL
;
1765 memset(nx
, 0, sizeof(*nx
));
1769 ipsec_create_fs_provider_and_instance(struct ipsec_pcb
*pcb
,
1770 uint32_t subtype
, const char *type_name
,
1772 uuid_t
*provider
, uuid_t
*instance
)
1774 nexus_attr_t attr
= NULL
;
1775 nexus_controller_t controller
= kern_nexus_shared_controller();
1778 struct kern_nexus_init init
;
1779 nexus_name_t provider_name
;
1781 err
= kern_nexus_get_builtin_domain_provider(NEXUS_TYPE_FLOW_SWITCH
,
1783 IPSEC_IF_VERIFY(err
== 0);
1785 printf("%s can't get %s provider, error %d\n",
1786 __func__
, type_name
, err
);
1790 err
= kern_nexus_attr_create(&attr
);
1791 IPSEC_IF_VERIFY(err
== 0);
1793 printf("%s: kern_nexus_attr_create failed: %d\n",
1798 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_EXTENSIONS
, subtype
);
1801 uint64_t slot_buffer_size
= pcb
->ipsec_slot_size
;
1802 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1805 // Reset ring size for flowswitch nexus to limit memory usage. Larger RX than netif.
1806 uint64_t tx_ring_size
= pcb
->ipsec_tx_fsw_ring_size
;
1807 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_TX_SLOTS
, tx_ring_size
);
1809 uint64_t rx_ring_size
= pcb
->ipsec_rx_fsw_ring_size
;
1810 err
= kern_nexus_attr_set(attr
, NEXUS_ATTR_RX_SLOTS
, rx_ring_size
);
1813 snprintf((char *)provider_name
, sizeof(provider_name
),
1814 "com.apple.%s.%s", type_name
, ifname
);
1815 err
= kern_nexus_controller_register_provider(controller
,
1822 kern_nexus_attr_destroy(attr
);
1824 IPSEC_IF_VERIFY(err
== 0);
1826 printf("%s register %s provider failed, error %d\n",
1827 __func__
, type_name
, err
);
1830 bzero(&init
, sizeof (init
));
1831 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
1832 err
= kern_nexus_controller_alloc_provider_instance(controller
,
1836 IPSEC_IF_VERIFY(err
== 0);
1838 printf("%s alloc_provider_instance %s failed, %d\n",
1839 __func__
, type_name
, err
);
1840 kern_nexus_controller_deregister_provider(controller
,
1842 uuid_clear(*provider
);
1849 ipsec_multistack_attach(struct ipsec_pcb
*pcb
)
1851 nexus_controller_t controller
= kern_nexus_shared_controller();
1853 ipsec_nx_t nx
= &pcb
->ipsec_nx
;
1855 // Allocate multistack flowswitch
1856 err
= ipsec_create_fs_provider_and_instance(pcb
,
1857 NEXUS_EXTENSION_FSW_TYPE_MULTISTACK
,
1859 pcb
->ipsec_ifp
->if_xname
,
1863 printf("%s: failed to create bridge provider and instance\n",
1868 // Attach multistack to device port
1869 err
= kern_nexus_ifattach(controller
, nx
->ms_instance
,
1870 NULL
, nx
->if_instance
,
1871 FALSE
, &nx
->ms_device
);
1873 printf("%s kern_nexus_ifattach ms device %d\n", __func__
, err
);
1877 // Attach multistack to host port
1878 err
= kern_nexus_ifattach(controller
, nx
->ms_instance
,
1879 NULL
, nx
->if_instance
,
1880 TRUE
, &nx
->ms_host
);
1882 printf("%s kern_nexus_ifattach ms host %d\n", __func__
, err
);
1886 // Extract the agent UUID and save for later
1887 struct kern_nexus
*multistack_nx
= nx_find(nx
->ms_instance
, false);
1888 if (multistack_nx
!= NULL
) {
1889 struct nx_flowswitch
*flowswitch
= NX_FSW_PRIVATE(multistack_nx
);
1890 if (flowswitch
!= NULL
) {
1891 FSW_RLOCK(flowswitch
);
1892 struct fsw_ms_context
*ms_context
= (struct fsw_ms_context
*)flowswitch
->fsw_ops_private
;
1893 if (ms_context
!= NULL
) {
1894 uuid_copy(nx
->ms_agent
, ms_context
->mc_agent_uuid
);
1896 printf("ipsec_multistack_attach - fsw_ms_context is NULL\n");
1898 FSW_UNLOCK(flowswitch
);
1900 printf("ipsec_multistack_attach - flowswitch is NULL\n");
1902 nx_release(multistack_nx
);
1904 printf("ipsec_multistack_attach - unable to find multistack nexus\n");
1910 ipsec_nexus_detach(pcb
);
1912 errno_t detach_error
= 0;
1913 if ((detach_error
= ifnet_detach(pcb
->ipsec_ifp
)) != 0) {
1914 panic("ipsec_multistack_attach - ifnet_detach failed: %d\n", detach_error
);
1921 #pragma mark Kernel Pipe Nexus
1924 ipsec_register_kernel_pipe_nexus(void)
1926 nexus_attr_t nxa
= NULL
;
1929 lck_mtx_lock(&ipsec_lock
);
1930 if (ipsec_ncd_refcount
++) {
1931 lck_mtx_unlock(&ipsec_lock
);
1935 result
= kern_nexus_controller_create(&ipsec_ncd
);
1937 printf("%s: kern_nexus_controller_create failed: %d\n",
1938 __FUNCTION__
, result
);
1943 result
= kern_nexus_get_builtin_domain_provider(
1944 NEXUS_TYPE_KERNEL_PIPE
, &dom_prov
);
1946 printf("%s: kern_nexus_get_builtin_domain_provider failed: %d\n",
1947 __FUNCTION__
, result
);
1951 struct kern_nexus_provider_init prov_init
= {
1952 .nxpi_version
= KERN_NEXUS_DOMAIN_PROVIDER_CURRENT_VERSION
,
1953 .nxpi_flags
= NXPIF_VIRTUAL_DEVICE
,
1954 .nxpi_pre_connect
= ipsec_nexus_pre_connect
,
1955 .nxpi_connected
= ipsec_nexus_connected
,
1956 .nxpi_pre_disconnect
= ipsec_nexus_pre_disconnect
,
1957 .nxpi_disconnected
= ipsec_nexus_disconnected
,
1958 .nxpi_ring_init
= ipsec_kpipe_ring_init
,
1959 .nxpi_ring_fini
= ipsec_kpipe_ring_fini
,
1960 .nxpi_slot_init
= NULL
,
1961 .nxpi_slot_fini
= NULL
,
1962 .nxpi_sync_tx
= ipsec_kpipe_sync_tx
,
1963 .nxpi_sync_rx
= ipsec_kpipe_sync_rx
,
1964 .nxpi_tx_doorbell
= NULL
,
1967 result
= kern_nexus_attr_create(&nxa
);
1969 printf("%s: kern_nexus_attr_create failed: %d\n",
1970 __FUNCTION__
, result
);
1974 uint64_t slot_buffer_size
= IPSEC_IF_DEFAULT_SLOT_SIZE
;
1975 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_SLOT_BUF_SIZE
, slot_buffer_size
);
1976 VERIFY(result
== 0);
1978 // Reset ring size for kernel pipe nexus to limit memory usage
1979 uint64_t ring_size
= if_ipsec_ring_size
;
1980 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_TX_SLOTS
, ring_size
);
1981 VERIFY(result
== 0);
1982 result
= kern_nexus_attr_set(nxa
, NEXUS_ATTR_RX_SLOTS
, ring_size
);
1983 VERIFY(result
== 0);
1985 result
= kern_nexus_controller_register_provider(ipsec_ncd
,
1987 (const uint8_t *)"com.apple.nexus.ipsec.kpipe",
1993 printf("%s: kern_nexus_controller_register_provider failed: %d\n",
1994 __FUNCTION__
, result
);
2000 kern_nexus_attr_destroy(nxa
);
2005 kern_nexus_controller_destroy(ipsec_ncd
);
2008 ipsec_ncd_refcount
= 0;
2011 lck_mtx_unlock(&ipsec_lock
);
2017 ipsec_unregister_kernel_pipe_nexus(void)
2019 lck_mtx_lock(&ipsec_lock
);
2021 VERIFY(ipsec_ncd_refcount
> 0);
2023 if (--ipsec_ncd_refcount
== 0) {
2024 kern_nexus_controller_destroy(ipsec_ncd
);
2028 lck_mtx_unlock(&ipsec_lock
);
2031 // For use by socket option, not internally
2033 ipsec_disable_channel(struct ipsec_pcb
*pcb
)
2039 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
2041 enabled
= pcb
->ipsec_kpipe_enabled
;
2042 uuid_copy(uuid
, pcb
->ipsec_kpipe_uuid
);
2044 VERIFY(uuid_is_null(pcb
->ipsec_kpipe_uuid
) == !enabled
);
2046 pcb
->ipsec_kpipe_enabled
= 0;
2047 uuid_clear(pcb
->ipsec_kpipe_uuid
);
2049 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2052 result
= kern_nexus_controller_free_provider_instance(ipsec_ncd
, uuid
);
2058 if (pcb
->ipsec_kpipe_pp
!= NULL
) {
2059 kern_pbufpool_destroy(pcb
->ipsec_kpipe_pp
);
2060 pcb
->ipsec_kpipe_pp
= NULL
;
2062 ipsec_unregister_kernel_pipe_nexus();
2069 ipsec_enable_channel(struct ipsec_pcb
*pcb
, struct proc
*proc
)
2071 struct kern_nexus_init init
;
2072 struct kern_pbufpool_init pp_init
;
2075 result
= ipsec_register_kernel_pipe_nexus();
2082 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
2084 /* ipsec driver doesn't support channels without a netif */
2085 if (!pcb
->ipsec_use_netif
) {
2086 result
= EOPNOTSUPP
;
2090 if (pcb
->ipsec_kpipe_enabled
) {
2091 result
= EEXIST
; // return success instead?
2095 bzero(&pp_init
, sizeof (pp_init
));
2096 pp_init
.kbi_version
= KERN_PBUFPOOL_CURRENT_VERSION
;
2097 pp_init
.kbi_packets
= pcb
->ipsec_netif_ring_size
* 2;
2098 pp_init
.kbi_bufsize
= pcb
->ipsec_slot_size
;
2099 pp_init
.kbi_buf_seg_size
= IPSEC_IF_DEFAULT_BUF_SEG_SIZE
;
2100 pp_init
.kbi_max_frags
= 1;
2101 pp_init
.kbi_flags
|= KBIF_QUANTUM
;
2102 (void) snprintf((char *)pp_init
.kbi_name
, sizeof (pp_init
.kbi_name
),
2103 "com.apple.kpipe.%s", pcb
->ipsec_if_xname
);
2105 result
= kern_pbufpool_create(&pp_init
, &pp_init
, &pcb
->ipsec_kpipe_pp
,
2108 printf("%s pbufbool create failed, error %d\n", __func__
, result
);
2112 VERIFY(uuid_is_null(pcb
->ipsec_kpipe_uuid
));
2113 bzero(&init
, sizeof (init
));
2114 init
.nxi_version
= KERN_NEXUS_CURRENT_VERSION
;
2115 init
.nxi_tx_pbufpool
= pcb
->ipsec_kpipe_pp
;
2116 result
= kern_nexus_controller_alloc_provider_instance(ipsec_ncd
,
2117 ipsec_kpipe_uuid
, pcb
, &pcb
->ipsec_kpipe_uuid
, &init
);
2122 nexus_port_t port
= NEXUS_PORT_KERNEL_PIPE_CLIENT
;
2123 result
= kern_nexus_controller_bind_provider_instance(ipsec_ncd
,
2124 pcb
->ipsec_kpipe_uuid
, &port
,
2125 proc_pid(proc
), NULL
, NULL
, 0, NEXUS_BIND_PID
);
2127 kern_nexus_controller_free_provider_instance(ipsec_ncd
,
2128 pcb
->ipsec_kpipe_uuid
);
2129 uuid_clear(pcb
->ipsec_kpipe_uuid
);
2133 pcb
->ipsec_kpipe_enabled
= 1;
2136 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2139 if (pcb
->ipsec_kpipe_pp
!= NULL
) {
2140 kern_pbufpool_destroy(pcb
->ipsec_kpipe_pp
);
2141 pcb
->ipsec_kpipe_pp
= NULL
;
2143 ipsec_unregister_kernel_pipe_nexus();
2149 #endif // IPSEC_NEXUS
2152 /* Kernel control functions */
2155 ipsec_free_pcb(struct ipsec_pcb
*pcb
, bool in_list
)
2158 mbuf_freem_list(pcb
->ipsec_input_chain
);
2159 lck_mtx_destroy(&pcb
->ipsec_input_chain_lock
, ipsec_lck_grp
);
2160 #endif // IPSEC_NEXUS
2161 lck_rw_destroy(&pcb
->ipsec_pcb_lock
, ipsec_lck_grp
);
2163 lck_mtx_lock(&ipsec_lock
);
2164 TAILQ_REMOVE(&ipsec_head
, pcb
, ipsec_chain
);
2165 lck_mtx_unlock(&ipsec_lock
);
2167 zfree(ipsec_pcb_zone
, pcb
);
2171 ipsec_ctl_bind(kern_ctl_ref kctlref
,
2172 struct sockaddr_ctl
*sac
,
2175 struct ipsec_pcb
*pcb
= zalloc(ipsec_pcb_zone
);
2176 memset(pcb
, 0, sizeof(*pcb
));
2178 /* Setup the protocol control block */
2180 pcb
->ipsec_ctlref
= kctlref
;
2181 pcb
->ipsec_unit
= sac
->sc_unit
;
2182 pcb
->ipsec_output_service_class
= MBUF_SC_OAM
;
2185 pcb
->ipsec_use_netif
= false;
2186 pcb
->ipsec_slot_size
= IPSEC_IF_DEFAULT_SLOT_SIZE
;
2187 pcb
->ipsec_netif_ring_size
= IPSEC_IF_DEFAULT_RING_SIZE
;
2188 pcb
->ipsec_tx_fsw_ring_size
= IPSEC_IF_DEFAULT_TX_FSW_RING_SIZE
;
2189 pcb
->ipsec_rx_fsw_ring_size
= IPSEC_IF_DEFAULT_RX_FSW_RING_SIZE
;
2190 #endif // IPSEC_NEXUS
2192 lck_rw_init(&pcb
->ipsec_pcb_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2194 lck_mtx_init(&pcb
->ipsec_input_chain_lock
, ipsec_lck_grp
, ipsec_lck_attr
);
2195 #endif // IPSEC_NEXUS
2201 ipsec_ctl_connect(kern_ctl_ref kctlref
,
2202 struct sockaddr_ctl
*sac
,
2205 struct ifnet_init_eparams ipsec_init
= {};
2208 if (*unitinfo
== NULL
) {
2209 (void)ipsec_ctl_bind(kctlref
, sac
, unitinfo
);
2212 struct ipsec_pcb
*pcb
= *unitinfo
;
2214 lck_mtx_lock(&ipsec_lock
);
2216 /* Find some open interface id */
2217 u_int32_t chosen_unique_id
= 1;
2218 struct ipsec_pcb
*next_pcb
= TAILQ_LAST(&ipsec_head
, ipsec_list
);
2219 if (next_pcb
!= NULL
) {
2220 /* List was not empty, add one to the last item */
2221 chosen_unique_id
= next_pcb
->ipsec_unique_id
+ 1;
2225 * If this wrapped the id number, start looking at
2226 * the front of the list for an unused id.
2228 if (chosen_unique_id
== 0) {
2229 /* Find the next unused ID */
2230 chosen_unique_id
= 1;
2231 TAILQ_FOREACH(next_pcb
, &ipsec_head
, ipsec_chain
) {
2232 if (next_pcb
->ipsec_unique_id
> chosen_unique_id
) {
2233 /* We found a gap */
2237 chosen_unique_id
= next_pcb
->ipsec_unique_id
+ 1;
2242 pcb
->ipsec_unique_id
= chosen_unique_id
;
2244 if (next_pcb
!= NULL
) {
2245 TAILQ_INSERT_BEFORE(next_pcb
, pcb
, ipsec_chain
);
2247 TAILQ_INSERT_TAIL(&ipsec_head
, pcb
, ipsec_chain
);
2249 lck_mtx_unlock(&ipsec_lock
);
2251 snprintf(pcb
->ipsec_if_xname
, sizeof(pcb
->ipsec_if_xname
), "ipsec%d", pcb
->ipsec_unit
- 1);
2252 snprintf(pcb
->ipsec_unique_name
, sizeof(pcb
->ipsec_unique_name
), "ipsecid%d", pcb
->ipsec_unique_id
- 1);
2253 printf("ipsec_ctl_connect: creating interface %s (id %s)\n", pcb
->ipsec_if_xname
, pcb
->ipsec_unique_name
);
2255 /* Create the interface */
2256 bzero(&ipsec_init
, sizeof(ipsec_init
));
2257 ipsec_init
.ver
= IFNET_INIT_CURRENT_VERSION
;
2258 ipsec_init
.len
= sizeof (ipsec_init
);
2261 if (pcb
->ipsec_use_netif
) {
2262 ipsec_init
.flags
= (IFNET_INIT_SKYWALK_NATIVE
| IFNET_INIT_NX_NOAUTO
);
2264 #endif // IPSEC_NEXUS
2266 ipsec_init
.flags
= IFNET_INIT_NX_NOAUTO
;
2267 ipsec_init
.start
= ipsec_start
;
2269 ipsec_init
.name
= "ipsec";
2270 ipsec_init
.unit
= pcb
->ipsec_unit
- 1;
2271 ipsec_init
.uniqueid
= pcb
->ipsec_unique_name
;
2272 ipsec_init
.uniqueid_len
= strlen(pcb
->ipsec_unique_name
);
2273 ipsec_init
.family
= ipsec_family
;
2274 ipsec_init
.subfamily
= IFNET_SUBFAMILY_IPSEC
;
2275 ipsec_init
.type
= IFT_OTHER
;
2276 ipsec_init
.demux
= ipsec_demux
;
2277 ipsec_init
.add_proto
= ipsec_add_proto
;
2278 ipsec_init
.del_proto
= ipsec_del_proto
;
2279 ipsec_init
.softc
= pcb
;
2280 ipsec_init
.ioctl
= ipsec_ioctl
;
2281 ipsec_init
.detach
= ipsec_detached
;
2284 if (pcb
->ipsec_use_netif
) {
2285 result
= ipsec_nexus_ifattach(pcb
, &ipsec_init
, &pcb
->ipsec_ifp
);
2287 printf("ipsec_ctl_connect - ipsec_nexus_ifattach failed: %d\n", result
);
2288 ipsec_free_pcb(pcb
, true);
2293 result
= ipsec_multistack_attach(pcb
);
2295 printf("ipsec_ctl_connect - ipsec_multistack_attach failed: %d\n", result
);
2301 bpfattach(pcb
->ipsec_ifp
, DLT_RAW
, 0);
2303 #endif // IPSEC_NEXUS
2305 result
= ifnet_allocate_extended(&ipsec_init
, &pcb
->ipsec_ifp
);
2307 printf("ipsec_ctl_connect - ifnet_allocate failed: %d\n", result
);
2308 ipsec_free_pcb(pcb
, true);
2312 ipsec_ifnet_set_attrs(pcb
->ipsec_ifp
);
2314 /* Attach the interface */
2315 result
= ifnet_attach(pcb
->ipsec_ifp
, NULL
);
2317 printf("ipsec_ctl_connect - ifnet_attach failed: %d\n", result
);
2318 ifnet_release(pcb
->ipsec_ifp
);
2319 ipsec_free_pcb(pcb
, true);
2325 bpfattach(pcb
->ipsec_ifp
, DLT_NULL
, 0);
2328 /* The interfaces resoures allocated, mark it as running */
2329 ifnet_set_flags(pcb
->ipsec_ifp
, IFF_RUNNING
, IFF_RUNNING
);
2335 ipsec_detach_ip(ifnet_t interface
,
2336 protocol_family_t protocol
,
2339 errno_t result
= EPROTONOSUPPORT
;
2341 /* Attempt a detach */
2342 if (protocol
== PF_INET
) {
2345 bzero(&ifr
, sizeof(ifr
));
2346 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
2347 ifnet_name(interface
), ifnet_unit(interface
));
2349 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH
, &ifr
);
2351 else if (protocol
== PF_INET6
) {
2352 struct in6_ifreq ifr6
;
2354 bzero(&ifr6
, sizeof(ifr6
));
2355 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
2356 ifnet_name(interface
), ifnet_unit(interface
));
2358 result
= sock_ioctl(pf_socket
, SIOCPROTODETACH_IN6
, &ifr6
);
2365 ipsec_remove_address(ifnet_t interface
,
2366 protocol_family_t protocol
,
2372 /* Attempt a detach */
2373 if (protocol
== PF_INET
) {
2376 bzero(&ifr
, sizeof(ifr
));
2377 snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
), "%s%d",
2378 ifnet_name(interface
), ifnet_unit(interface
));
2379 result
= ifaddr_address(address
, &ifr
.ifr_addr
, sizeof(ifr
.ifr_addr
));
2381 printf("ipsec_remove_address - ifaddr_address failed: %d", result
);
2384 result
= sock_ioctl(pf_socket
, SIOCDIFADDR
, &ifr
);
2386 printf("ipsec_remove_address - SIOCDIFADDR failed: %d", result
);
2390 else if (protocol
== PF_INET6
) {
2391 struct in6_ifreq ifr6
;
2393 bzero(&ifr6
, sizeof(ifr6
));
2394 snprintf(ifr6
.ifr_name
, sizeof(ifr6
.ifr_name
), "%s%d",
2395 ifnet_name(interface
), ifnet_unit(interface
));
2396 result
= ifaddr_address(address
, (struct sockaddr
*)&ifr6
.ifr_addr
,
2397 sizeof(ifr6
.ifr_addr
));
2399 printf("ipsec_remove_address - ifaddr_address failed (v6): %d",
2403 result
= sock_ioctl(pf_socket
, SIOCDIFADDR_IN6
, &ifr6
);
2405 printf("ipsec_remove_address - SIOCDIFADDR_IN6 failed: %d",
2413 ipsec_cleanup_family(ifnet_t interface
,
2414 protocol_family_t protocol
)
2417 socket_t pf_socket
= NULL
;
2418 ifaddr_t
*addresses
= NULL
;
2421 if (protocol
!= PF_INET
&& protocol
!= PF_INET6
) {
2422 printf("ipsec_cleanup_family - invalid protocol family %d\n", protocol
);
2426 /* Create a socket for removing addresses and detaching the protocol */
2427 result
= sock_socket(protocol
, SOCK_DGRAM
, 0, NULL
, NULL
, &pf_socket
);
2429 if (result
!= EAFNOSUPPORT
)
2430 printf("ipsec_cleanup_family - failed to create %s socket: %d\n",
2431 protocol
== PF_INET
? "IP" : "IPv6", result
);
2435 /* always set SS_PRIV, we want to close and detach regardless */
2436 sock_setpriv(pf_socket
, 1);
2438 result
= ipsec_detach_ip(interface
, protocol
, pf_socket
);
2439 if (result
== 0 || result
== ENXIO
) {
2440 /* We are done! We either detached or weren't attached. */
2443 else if (result
!= EBUSY
) {
2444 /* Uh, not really sure what happened here... */
2445 printf("ipsec_cleanup_family - ipsec_detach_ip failed: %d\n", result
);
2450 * At this point, we received an EBUSY error. This means there are
2451 * addresses attached. We should detach them and then try again.
2453 result
= ifnet_get_address_list_family(interface
, &addresses
, protocol
);
2455 printf("fnet_get_address_list_family(%s%d, 0xblah, %s) - failed: %d\n",
2456 ifnet_name(interface
), ifnet_unit(interface
),
2457 protocol
== PF_INET
? "PF_INET" : "PF_INET6", result
);
2461 for (i
= 0; addresses
[i
] != 0; i
++) {
2462 ipsec_remove_address(interface
, protocol
, addresses
[i
], pf_socket
);
2464 ifnet_free_address_list(addresses
);
2468 * The addresses should be gone, we should try the remove again.
2470 result
= ipsec_detach_ip(interface
, protocol
, pf_socket
);
2471 if (result
!= 0 && result
!= ENXIO
) {
2472 printf("ipsec_cleanup_family - ipsec_detach_ip failed: %d\n", result
);
2476 if (pf_socket
!= NULL
)
2477 sock_close(pf_socket
);
2479 if (addresses
!= NULL
)
2480 ifnet_free_address_list(addresses
);
2484 ipsec_ctl_disconnect(__unused kern_ctl_ref kctlref
,
2485 __unused u_int32_t unit
,
2488 struct ipsec_pcb
*pcb
= unitinfo
;
2497 // Tell the nexus to stop all rings
2498 if (pcb
->ipsec_netif_nexus
!= NULL
) {
2499 kern_nexus_stop(pcb
->ipsec_netif_nexus
);
2501 #endif // IPSEC_NEXUS
2503 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
2507 uuid_copy(kpipe_uuid
, pcb
->ipsec_kpipe_uuid
);
2508 uuid_clear(pcb
->ipsec_kpipe_uuid
);
2509 pcb
->ipsec_kpipe_enabled
= FALSE
;
2510 #endif // IPSEC_NEXUS
2512 pcb
->ipsec_ctlref
= NULL
;
2514 ifp
= pcb
->ipsec_ifp
;
2517 if (pcb
->ipsec_netif_nexus
!= NULL
) {
2519 * Quiesce the interface and flush any pending outbound packets.
2523 /* Increment refcnt, but detach interface */
2524 ifnet_incr_iorefcnt(ifp
);
2525 if ((result
= ifnet_detach(ifp
)) != 0) {
2526 panic("ipsec_ctl_disconnect - ifnet_detach failed: %d\n", result
);
2531 * We want to do everything in our power to ensure that the interface
2532 * really goes away when the socket is closed. We must remove IP/IPv6
2533 * addresses and detach the protocols. Finally, we can remove and
2534 * release the interface.
2536 key_delsp_for_ipsec_if(ifp
);
2538 ipsec_cleanup_family(ifp
, AF_INET
);
2539 ipsec_cleanup_family(ifp
, AF_INET6
);
2541 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2543 if (!uuid_is_null(kpipe_uuid
)) {
2544 if (kern_nexus_controller_free_provider_instance(ipsec_ncd
, kpipe_uuid
) == 0) {
2545 if (pcb
->ipsec_kpipe_pp
!= NULL
) {
2546 kern_pbufpool_destroy(pcb
->ipsec_kpipe_pp
);
2547 pcb
->ipsec_kpipe_pp
= NULL
;
2549 ipsec_unregister_kernel_pipe_nexus();
2552 ipsec_nexus_detach(pcb
);
2554 /* Decrement refcnt to finish detaching and freeing */
2555 ifnet_decr_iorefcnt(ifp
);
2557 #endif // IPSEC_NEXUS
2559 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2562 if (!uuid_is_null(kpipe_uuid
)) {
2563 if (kern_nexus_controller_free_provider_instance(ipsec_ncd
, kpipe_uuid
) == 0) {
2564 if (pcb
->ipsec_kpipe_pp
!= NULL
) {
2565 kern_pbufpool_destroy(pcb
->ipsec_kpipe_pp
);
2566 pcb
->ipsec_kpipe_pp
= NULL
;
2568 ipsec_unregister_kernel_pipe_nexus();
2571 #endif // IPSEC_NEXUS
2574 * We want to do everything in our power to ensure that the interface
2575 * really goes away when the socket is closed. We must remove IP/IPv6
2576 * addresses and detach the protocols. Finally, we can remove and
2577 * release the interface.
2579 key_delsp_for_ipsec_if(ifp
);
2581 ipsec_cleanup_family(ifp
, AF_INET
);
2582 ipsec_cleanup_family(ifp
, AF_INET6
);
2585 * Detach now; ipsec_detach() will be called asynchronously once
2586 * the I/O reference count drops to 0. There we will invoke
2589 if ((result
= ifnet_detach(ifp
)) != 0) {
2590 printf("ipsec_ctl_disconnect - ifnet_detach failed: %d\n", result
);
2594 // Bound, but not connected
2595 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2596 ipsec_free_pcb(pcb
, false);
2603 ipsec_ctl_send(__unused kern_ctl_ref kctlref
,
2604 __unused u_int32_t unit
,
2605 __unused
void *unitinfo
,
2609 /* Receive messages from the control socket. Currently unused. */
2615 ipsec_ctl_setopt(__unused kern_ctl_ref kctlref
,
2616 __unused u_int32_t unit
,
2622 struct ipsec_pcb
*pcb
= unitinfo
;
2625 /* check for privileges for privileged options */
2627 case IPSEC_OPT_FLAGS
:
2628 case IPSEC_OPT_EXT_IFDATA_STATS
:
2629 case IPSEC_OPT_SET_DELEGATE_INTERFACE
:
2630 case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS
:
2631 if (kauth_cred_issuser(kauth_cred_get()) == 0) {
2638 case IPSEC_OPT_FLAGS
:
2639 if (len
!= sizeof(u_int32_t
)) {
2642 pcb
->ipsec_flags
= *(u_int32_t
*)data
;
2646 case IPSEC_OPT_EXT_IFDATA_STATS
:
2647 if (len
!= sizeof(int)) {
2651 if (pcb
->ipsec_ifp
== NULL
) {
2652 // Only can set after connecting
2656 pcb
->ipsec_ext_ifdata_stats
= (*(int *)data
) ? 1 : 0;
2659 case IPSEC_OPT_INC_IFDATA_STATS_IN
:
2660 case IPSEC_OPT_INC_IFDATA_STATS_OUT
: {
2661 struct ipsec_stats_param
*utsp
= (struct ipsec_stats_param
*)data
;
2663 if (utsp
== NULL
|| len
< sizeof(struct ipsec_stats_param
)) {
2667 if (pcb
->ipsec_ifp
== NULL
) {
2668 // Only can set after connecting
2672 if (!pcb
->ipsec_ext_ifdata_stats
) {
2676 if (opt
== IPSEC_OPT_INC_IFDATA_STATS_IN
)
2677 ifnet_stat_increment_in(pcb
->ipsec_ifp
, utsp
->utsp_packets
,
2678 utsp
->utsp_bytes
, utsp
->utsp_errors
);
2680 ifnet_stat_increment_out(pcb
->ipsec_ifp
, utsp
->utsp_packets
,
2681 utsp
->utsp_bytes
, utsp
->utsp_errors
);
2685 case IPSEC_OPT_SET_DELEGATE_INTERFACE
: {
2686 ifnet_t del_ifp
= NULL
;
2687 char name
[IFNAMSIZ
];
2689 if (len
> IFNAMSIZ
- 1) {
2693 if (pcb
->ipsec_ifp
== NULL
) {
2694 // Only can set after connecting
2698 if (len
!= 0) { /* if len==0, del_ifp will be NULL causing the delegate to be removed */
2699 bcopy(data
, name
, len
);
2701 result
= ifnet_find_by_name(name
, &del_ifp
);
2704 printf("%s IPSEC_OPT_SET_DELEGATE_INTERFACE %s to %s\n",
2705 __func__
, pcb
->ipsec_ifp
->if_xname
,
2708 result
= ifnet_set_delegate(pcb
->ipsec_ifp
, del_ifp
);
2710 ifnet_release(del_ifp
);
2715 case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS
: {
2716 if (len
!= sizeof(int)) {
2720 if (pcb
->ipsec_ifp
== NULL
) {
2721 // Only can set after connecting
2725 mbuf_svc_class_t output_service_class
= so_tc2msc(*(int *)data
);
2726 if (output_service_class
== MBUF_SC_UNSPEC
) {
2727 pcb
->ipsec_output_service_class
= MBUF_SC_OAM
;
2729 pcb
->ipsec_output_service_class
= output_service_class
;
2731 printf("%s IPSEC_OPT_OUTPUT_TRAFFIC_CLASS %s svc %d\n",
2732 __func__
, pcb
->ipsec_ifp
->if_xname
,
2733 pcb
->ipsec_output_service_class
);
2738 case IPSEC_OPT_ENABLE_CHANNEL
: {
2739 if (len
!= sizeof(int)) {
2743 if (pcb
->ipsec_ifp
== NULL
) {
2744 // Only can set after connecting
2749 result
= ipsec_enable_channel(pcb
, current_proc());
2751 result
= ipsec_disable_channel(pcb
);
2756 case IPSEC_OPT_ENABLE_FLOWSWITCH
: {
2757 if (len
!= sizeof(int)) {
2761 if (pcb
->ipsec_ifp
== NULL
) {
2762 // Only can set after connecting
2766 if (!if_is_netagent_enabled()) {
2770 if (uuid_is_null(pcb
->ipsec_nx
.ms_agent
)) {
2776 if_add_netagent(pcb
->ipsec_ifp
, pcb
->ipsec_nx
.ms_agent
);
2777 pcb
->ipsec_needs_netagent
= true;
2779 pcb
->ipsec_needs_netagent
= false;
2780 if_delete_netagent(pcb
->ipsec_ifp
, pcb
->ipsec_nx
.ms_agent
);
2785 case IPSEC_OPT_INPUT_FRAG_SIZE
: {
2786 if (len
!= sizeof(u_int32_t
)) {
2790 u_int32_t input_frag_size
= *(u_int32_t
*)data
;
2791 if (input_frag_size
<= sizeof(struct ip6_hdr
)) {
2792 pcb
->ipsec_frag_size_set
= FALSE
;
2793 pcb
->ipsec_input_frag_size
= 0;
2795 printf("SET FRAG SIZE TO %u\n", input_frag_size
);
2796 pcb
->ipsec_frag_size_set
= TRUE
;
2797 pcb
->ipsec_input_frag_size
= input_frag_size
;
2801 case IPSEC_OPT_ENABLE_NETIF
: {
2802 if (len
!= sizeof(int)) {
2806 if (pcb
->ipsec_ifp
!= NULL
) {
2807 // Only can set before connecting
2811 lck_rw_lock_exclusive(&pcb
->ipsec_pcb_lock
);
2812 pcb
->ipsec_use_netif
= !!(*(int *)data
);
2813 lck_rw_unlock_exclusive(&pcb
->ipsec_pcb_lock
);
2816 case IPSEC_OPT_SLOT_SIZE
: {
2817 if (len
!= sizeof(u_int32_t
)) {
2821 if (pcb
->ipsec_ifp
!= NULL
) {
2822 // Only can set before connecting
2826 u_int32_t slot_size
= *(u_int32_t
*)data
;
2827 if (slot_size
< IPSEC_IF_MIN_SLOT_SIZE
||
2828 slot_size
> IPSEC_IF_MAX_SLOT_SIZE
) {
2831 pcb
->ipsec_slot_size
= slot_size
;
2834 case IPSEC_OPT_NETIF_RING_SIZE
: {
2835 if (len
!= sizeof(u_int32_t
)) {
2839 if (pcb
->ipsec_ifp
!= NULL
) {
2840 // Only can set before connecting
2844 u_int32_t ring_size
= *(u_int32_t
*)data
;
2845 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
2846 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
2849 pcb
->ipsec_netif_ring_size
= ring_size
;
2852 case IPSEC_OPT_TX_FSW_RING_SIZE
: {
2853 if (len
!= sizeof(u_int32_t
)) {
2857 if (pcb
->ipsec_ifp
!= NULL
) {
2858 // Only can set before connecting
2862 u_int32_t ring_size
= *(u_int32_t
*)data
;
2863 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
2864 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
2867 pcb
->ipsec_tx_fsw_ring_size
= ring_size
;
2870 case IPSEC_OPT_RX_FSW_RING_SIZE
: {
2871 if (len
!= sizeof(u_int32_t
)) {
2875 if (pcb
->ipsec_ifp
!= NULL
) {
2876 // Only can set before connecting
2880 u_int32_t ring_size
= *(u_int32_t
*)data
;
2881 if (ring_size
< IPSEC_IF_MIN_RING_SIZE
||
2882 ring_size
> IPSEC_IF_MAX_RING_SIZE
) {
2885 pcb
->ipsec_rx_fsw_ring_size
= ring_size
;
2889 #endif // IPSEC_NEXUS
2892 result
= ENOPROTOOPT
;
2900 ipsec_ctl_getopt(__unused kern_ctl_ref kctlref
,
2901 __unused u_int32_t unit
,
2907 struct ipsec_pcb
*pcb
= unitinfo
;
2911 case IPSEC_OPT_FLAGS
: {
2912 if (*len
!= sizeof(u_int32_t
)) {
2915 *(u_int32_t
*)data
= pcb
->ipsec_flags
;
2920 case IPSEC_OPT_EXT_IFDATA_STATS
: {
2921 if (*len
!= sizeof(int)) {
2924 *(int *)data
= (pcb
->ipsec_ext_ifdata_stats
) ? 1 : 0;
2929 case IPSEC_OPT_IFNAME
: {
2930 if (*len
< MIN(strlen(pcb
->ipsec_if_xname
) + 1, sizeof(pcb
->ipsec_if_xname
))) {
2933 if (pcb
->ipsec_ifp
== NULL
) {
2934 // Only can get after connecting
2938 *len
= snprintf(data
, *len
, "%s", pcb
->ipsec_if_xname
) + 1;
2943 case IPSEC_OPT_OUTPUT_TRAFFIC_CLASS
: {
2944 if (*len
!= sizeof(int)) {
2947 *(int *)data
= so_svc2tc(pcb
->ipsec_output_service_class
);
2954 case IPSEC_OPT_ENABLE_CHANNEL
: {
2955 if (*len
!= sizeof(int)) {
2958 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
2959 *(int *)data
= pcb
->ipsec_kpipe_enabled
;
2960 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
2965 case IPSEC_OPT_ENABLE_FLOWSWITCH
: {
2966 if (*len
!= sizeof(int)) {
2969 *(int *)data
= if_check_netagent(pcb
->ipsec_ifp
, pcb
->ipsec_nx
.ms_agent
);
2974 case IPSEC_OPT_ENABLE_NETIF
: {
2975 if (*len
!= sizeof(int)) {
2978 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
2979 *(int *)data
= !!pcb
->ipsec_use_netif
;
2980 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
2985 case IPSEC_OPT_GET_CHANNEL_UUID
: {
2986 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
2987 if (uuid_is_null(pcb
->ipsec_kpipe_uuid
)) {
2989 } else if (*len
!= sizeof(uuid_t
)) {
2992 uuid_copy(data
, pcb
->ipsec_kpipe_uuid
);
2994 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
2998 case IPSEC_OPT_INPUT_FRAG_SIZE
: {
2999 if (*len
!= sizeof(u_int32_t
)) {
3002 *(u_int32_t
*)data
= pcb
->ipsec_input_frag_size
;
3006 case IPSEC_OPT_SLOT_SIZE
: {
3007 if (*len
!= sizeof(u_int32_t
)) {
3010 *(u_int32_t
*)data
= pcb
->ipsec_slot_size
;
3014 case IPSEC_OPT_NETIF_RING_SIZE
: {
3015 if (*len
!= sizeof(u_int32_t
)) {
3018 *(u_int32_t
*)data
= pcb
->ipsec_netif_ring_size
;
3022 case IPSEC_OPT_TX_FSW_RING_SIZE
: {
3023 if (*len
!= sizeof(u_int32_t
)) {
3026 *(u_int32_t
*)data
= pcb
->ipsec_tx_fsw_ring_size
;
3030 case IPSEC_OPT_RX_FSW_RING_SIZE
: {
3031 if (*len
!= sizeof(u_int32_t
)) {
3034 *(u_int32_t
*)data
= pcb
->ipsec_rx_fsw_ring_size
;
3039 #endif // IPSEC_NEXUS
3042 result
= ENOPROTOOPT
;
3050 /* Network Interface functions */
3052 ipsec_output(ifnet_t interface
,
3055 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3056 struct ipsec_output_state ipsec_state
;
3058 struct route_in6 ro6
;
3061 struct ip6_hdr
*ip6
;
3062 struct ip_out_args ipoa
;
3063 struct ip6_out_args ip6oa
;
3065 u_int ip_version
= 0;
3067 struct flowadv
*adv
= NULL
;
3069 // Make sure this packet isn't looping through the interface
3070 if (necp_get_last_interface_index_from_packet(data
) == interface
->if_index
) {
3072 goto ipsec_output_err
;
3075 // Mark the interface so NECP can evaluate tunnel policy
3076 necp_mark_packet_from_interface(data
, interface
);
3078 ip
= mtod(data
, struct ip
*);
3079 ip_version
= ip
->ip_v
;
3081 switch (ip_version
) {
3084 if (!pcb
->ipsec_use_netif
)
3085 #endif // IPSEC_NEXUS
3088 bpf_tap_out(pcb
->ipsec_ifp
, DLT_NULL
, data
, &af
, sizeof(af
));
3091 /* Apply encryption */
3092 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
3093 ipsec_state
.m
= data
;
3094 ipsec_state
.dst
= (struct sockaddr
*)&ip
->ip_dst
;
3095 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
3097 error
= ipsec4_interface_output(&ipsec_state
, interface
);
3098 /* Tunneled in IPv6 - packet is gone */
3099 if (error
== 0 && ipsec_state
.tunneled
== 6) {
3103 data
= ipsec_state
.m
;
3104 if (error
|| data
== NULL
) {
3106 printf("ipsec_output: ipsec4_output error %d.\n", error
);
3108 goto ipsec_output_err
;
3111 /* Set traffic class, set flow */
3112 m_set_service_class(data
, pcb
->ipsec_output_service_class
);
3113 data
->m_pkthdr
.pkt_flowsrc
= FLOWSRC_IFNET
;
3114 data
->m_pkthdr
.pkt_flowid
= interface
->if_flowhash
;
3115 data
->m_pkthdr
.pkt_proto
= ip
->ip_p
;
3116 data
->m_pkthdr
.pkt_flags
= (PKTF_FLOW_ID
| PKTF_FLOW_ADV
| PKTF_FLOW_LOCALSRC
);
3118 /* Flip endian-ness for ip_output */
3119 ip
= mtod(data
, struct ip
*);
3123 /* Increment statistics */
3124 length
= mbuf_pkthdr_len(data
);
3125 ifnet_stat_increment_out(interface
, 1, length
, 0);
3127 /* Send to ip_output */
3128 memset(&ro
, 0, sizeof(ro
));
3130 flags
= (IP_OUTARGS
| /* Passing out args to specify interface */
3131 IP_NOIPSEC
); /* To ensure the packet doesn't go through ipsec twice */
3133 memset(&ipoa
, 0, sizeof(ipoa
));
3134 ipoa
.ipoa_flowadv
.code
= 0;
3135 ipoa
.ipoa_flags
= IPOAF_SELECT_SRCIF
| IPOAF_BOUND_SRCADDR
;
3136 if (ipsec_state
.outgoing_if
) {
3137 ipoa
.ipoa_boundif
= ipsec_state
.outgoing_if
;
3138 ipoa
.ipoa_flags
|= IPOAF_BOUND_IF
;
3140 ipsec_set_ipoa_for_interface(pcb
->ipsec_ifp
, &ipoa
);
3142 adv
= &ipoa
.ipoa_flowadv
;
3144 (void)ip_output(data
, NULL
, &ro
, flags
, NULL
, &ipoa
);
3147 if (adv
->code
== FADV_FLOW_CONTROLLED
|| adv
->code
== FADV_SUSPENDED
) {
3149 ifnet_disable_output(interface
);
3156 if (!pcb
->ipsec_use_netif
)
3157 #endif // IPSEC_NEXUS
3160 bpf_tap_out(pcb
->ipsec_ifp
, DLT_NULL
, data
, &af
, sizeof(af
));
3163 data
= ipsec6_splithdr(data
);
3165 printf("ipsec_output: ipsec6_splithdr returned NULL\n");
3166 goto ipsec_output_err
;
3169 ip6
= mtod(data
, struct ip6_hdr
*);
3171 memset(&ipsec_state
, 0, sizeof(ipsec_state
));
3172 ipsec_state
.m
= data
;
3173 ipsec_state
.dst
= (struct sockaddr
*)&ip6
->ip6_dst
;
3174 memset(&ipsec_state
.ro
, 0, sizeof(ipsec_state
.ro
));
3176 error
= ipsec6_interface_output(&ipsec_state
, interface
, &ip6
->ip6_nxt
, ipsec_state
.m
);
3177 if (error
== 0 && ipsec_state
.tunneled
== 4) { /* tunneled in IPv4 - packet is gone */
3180 data
= ipsec_state
.m
;
3181 if (error
|| data
== NULL
) {
3183 printf("ipsec_output: ipsec6_output error %d\n", error
);
3185 goto ipsec_output_err
;
3188 /* Set traffic class, set flow */
3189 m_set_service_class(data
, pcb
->ipsec_output_service_class
);
3190 data
->m_pkthdr
.pkt_flowsrc
= FLOWSRC_IFNET
;
3191 data
->m_pkthdr
.pkt_flowid
= interface
->if_flowhash
;
3192 data
->m_pkthdr
.pkt_proto
= ip6
->ip6_nxt
;
3193 data
->m_pkthdr
.pkt_flags
= (PKTF_FLOW_ID
| PKTF_FLOW_ADV
| PKTF_FLOW_LOCALSRC
);
3195 /* Increment statistics */
3196 length
= mbuf_pkthdr_len(data
);
3197 ifnet_stat_increment_out(interface
, 1, length
, 0);
3199 /* Send to ip6_output */
3200 memset(&ro6
, 0, sizeof(ro6
));
3202 flags
= IPV6_OUTARGS
;
3204 memset(&ip6oa
, 0, sizeof(ip6oa
));
3205 ip6oa
.ip6oa_flowadv
.code
= 0;
3206 ip6oa
.ip6oa_flags
= IP6OAF_SELECT_SRCIF
| IP6OAF_BOUND_SRCADDR
;
3207 if (ipsec_state
.outgoing_if
) {
3208 ip6oa
.ip6oa_boundif
= ipsec_state
.outgoing_if
;
3209 ip6oa
.ip6oa_flags
|= IP6OAF_BOUND_IF
;
3211 ipsec_set_ip6oa_for_interface(pcb
->ipsec_ifp
, &ip6oa
);
3213 adv
= &ip6oa
.ip6oa_flowadv
;
3215 (void) ip6_output(data
, NULL
, &ro6
, flags
, NULL
, NULL
, &ip6oa
);
3218 if (adv
->code
== FADV_FLOW_CONTROLLED
|| adv
->code
== FADV_SUSPENDED
) {
3220 ifnet_disable_output(interface
);
3226 printf("ipsec_output: Received unknown packet version %d.\n", ip_version
);
3228 goto ipsec_output_err
;
3242 ipsec_start(ifnet_t interface
)
3245 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3247 VERIFY(pcb
!= NULL
);
3249 if (ifnet_dequeue(interface
, &data
) != 0)
3251 if (ipsec_output(interface
, data
) != 0)
3256 /* Network Interface functions */
3258 ipsec_demux(__unused ifnet_t interface
,
3260 __unused
char *frame_header
,
3261 protocol_family_t
*protocol
)
3266 while (data
!= NULL
&& mbuf_len(data
) < 1) {
3267 data
= mbuf_next(data
);
3273 ip
= mtod(data
, struct ip
*);
3274 ip_version
= ip
->ip_v
;
3276 switch(ip_version
) {
3278 *protocol
= PF_INET
;
3281 *protocol
= PF_INET6
;
3291 ipsec_add_proto(__unused ifnet_t interface
,
3292 protocol_family_t protocol
,
3293 __unused
const struct ifnet_demux_desc
*demux_array
,
3294 __unused u_int32_t demux_count
)
3309 ipsec_del_proto(__unused ifnet_t interface
,
3310 __unused protocol_family_t protocol
)
3316 ipsec_ioctl(ifnet_t interface
,
3325 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3326 if (pcb
->ipsec_use_netif
) {
3327 // Make sure we can fit packets in the channel buffers
3328 if (((uint64_t)((struct ifreq
*)data
)->ifr_mtu
) > pcb
->ipsec_slot_size
) {
3331 ifnet_set_mtu(interface
, (uint32_t)((struct ifreq
*)data
)->ifr_mtu
);
3334 #endif // IPSEC_NEXUS
3336 ifnet_set_mtu(interface
, ((struct ifreq
*)data
)->ifr_mtu
);
3342 /* ifioctl() takes care of it */
3346 result
= EOPNOTSUPP
;
3353 ipsec_detached(ifnet_t interface
)
3355 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3356 (void)ifnet_release(interface
);
3357 ipsec_free_pcb(pcb
, true);
3360 /* Protocol Handlers */
3363 ipsec_proto_input(ifnet_t interface
,
3364 protocol_family_t protocol
,
3366 __unused
char *frame_header
)
3368 mbuf_pkthdr_setrcvif(m
, interface
);
3371 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3372 if (!pcb
->ipsec_use_netif
)
3373 #endif // IPSEC_NEXUS
3376 struct ip
*ip
= mtod(m
, struct ip
*);
3377 if (ip
->ip_v
== 4) {
3379 } else if (ip
->ip_v
== 6) {
3382 bpf_tap_in(interface
, DLT_NULL
, m
, &af
, sizeof(af
));
3383 pktap_input(interface
, protocol
, m
, NULL
);
3386 int32_t pktlen
= m
->m_pkthdr
.len
;
3387 if (proto_input(protocol
, m
) != 0) {
3388 ifnet_stat_increment_in(interface
, 0, 0, 1);
3391 ifnet_stat_increment_in(interface
, 1, pktlen
, 0);
3398 ipsec_proto_pre_output(__unused ifnet_t interface
,
3399 protocol_family_t protocol
,
3400 __unused mbuf_t
*packet
,
3401 __unused
const struct sockaddr
*dest
,
3402 __unused
void *route
,
3403 __unused
char *frame_type
,
3404 __unused
char *link_layer_dest
)
3407 *(protocol_family_t
*)(void *)frame_type
= protocol
;
3412 ipsec_attach_proto(ifnet_t interface
,
3413 protocol_family_t protocol
)
3415 struct ifnet_attach_proto_param proto
;
3418 bzero(&proto
, sizeof(proto
));
3419 proto
.input
= ipsec_proto_input
;
3420 proto
.pre_output
= ipsec_proto_pre_output
;
3422 result
= ifnet_attach_protocol(interface
, protocol
, &proto
);
3423 if (result
!= 0 && result
!= EEXIST
) {
3424 printf("ipsec_attach_inet - ifnet_attach_protocol %d failed: %d\n",
3432 ipsec_inject_inbound_packet(ifnet_t interface
,
3436 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3438 if (pcb
->ipsec_use_netif
) {
3439 lck_rw_lock_shared(&pcb
->ipsec_pcb_lock
);
3441 lck_mtx_lock(&pcb
->ipsec_input_chain_lock
);
3442 if (pcb
->ipsec_input_chain
!= NULL
) {
3443 pcb
->ipsec_input_chain_last
->m_nextpkt
= packet
;
3445 pcb
->ipsec_input_chain
= packet
;
3447 while (packet
->m_nextpkt
) {
3448 VERIFY(packet
!= packet
->m_nextpkt
);
3449 packet
= packet
->m_nextpkt
;
3451 pcb
->ipsec_input_chain_last
= packet
;
3452 lck_mtx_unlock(&pcb
->ipsec_input_chain_lock
);
3454 kern_channel_ring_t rx_ring
= pcb
->ipsec_netif_rxring
;
3455 lck_rw_unlock_shared(&pcb
->ipsec_pcb_lock
);
3457 if (rx_ring
!= NULL
) {
3458 kern_channel_notify(rx_ring
, 0);
3463 #endif // IPSEC_NEXUS
3466 protocol_family_t protocol
;
3467 if ((error
= ipsec_demux(interface
, packet
, NULL
, &protocol
)) != 0) {
3471 return ipsec_proto_input(interface
, protocol
, packet
, NULL
);
3476 ipsec_set_pkthdr_for_interface(ifnet_t interface
, mbuf_t packet
, int family
)
3478 if (packet
!= NULL
&& interface
!= NULL
) {
3479 struct ipsec_pcb
*pcb
= ifnet_softc(interface
);
3481 /* Set traffic class, set flow */
3482 m_set_service_class(packet
, pcb
->ipsec_output_service_class
);
3483 packet
->m_pkthdr
.pkt_flowsrc
= FLOWSRC_IFNET
;
3484 packet
->m_pkthdr
.pkt_flowid
= interface
->if_flowhash
;
3485 if (family
== AF_INET
) {
3486 struct ip
*ip
= mtod(packet
, struct ip
*);
3487 packet
->m_pkthdr
.pkt_proto
= ip
->ip_p
;
3488 } else if (family
== AF_INET6
) {
3489 struct ip6_hdr
*ip6
= mtod(packet
, struct ip6_hdr
*);
3490 packet
->m_pkthdr
.pkt_proto
= ip6
->ip6_nxt
;
3492 packet
->m_pkthdr
.pkt_flags
= (PKTF_FLOW_ID
| PKTF_FLOW_ADV
| PKTF_FLOW_LOCALSRC
);
3498 ipsec_set_ipoa_for_interface(ifnet_t interface
, struct ip_out_args
*ipoa
)
3500 struct ipsec_pcb
*pcb
;
3502 if (interface
== NULL
|| ipoa
== NULL
)
3504 pcb
= ifnet_softc(interface
);
3506 if (net_qos_policy_restricted
== 0) {
3507 ipoa
->ipoa_flags
|= IPOAF_QOSMARKING_ALLOWED
;
3508 ipoa
->ipoa_sotc
= so_svc2tc(pcb
->ipsec_output_service_class
);
3509 } else if (pcb
->ipsec_output_service_class
!= MBUF_SC_VO
||
3510 net_qos_policy_restrict_avapps
!= 0) {
3511 ipoa
->ipoa_flags
&= ~IPOAF_QOSMARKING_ALLOWED
;
3513 ipoa
->ipoa_flags
|= IP6OAF_QOSMARKING_ALLOWED
;
3514 ipoa
->ipoa_sotc
= SO_TC_VO
;
3519 ipsec_set_ip6oa_for_interface(ifnet_t interface
, struct ip6_out_args
*ip6oa
)
3521 struct ipsec_pcb
*pcb
;
3523 if (interface
== NULL
|| ip6oa
== NULL
)
3525 pcb
= ifnet_softc(interface
);
3527 if (net_qos_policy_restricted
== 0) {
3528 ip6oa
->ip6oa_flags
|= IPOAF_QOSMARKING_ALLOWED
;
3529 ip6oa
->ip6oa_sotc
= so_svc2tc(pcb
->ipsec_output_service_class
);
3530 } else if (pcb
->ipsec_output_service_class
!= MBUF_SC_VO
||
3531 net_qos_policy_restrict_avapps
!= 0) {
3532 ip6oa
->ip6oa_flags
&= ~IPOAF_QOSMARKING_ALLOWED
;
3534 ip6oa
->ip6oa_flags
|= IP6OAF_QOSMARKING_ALLOWED
;
3535 ip6oa
->ip6oa_sotc
= SO_TC_VO
;