2 * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include "kpi_interface.h"
31 #include <sys/queue.h>
32 #include <sys/param.h> /* for definition of NULL */
33 #include <kern/debug.h> /* for panic */
34 #include <sys/errno.h>
35 #include <sys/socket.h>
36 #include <sys/kern_event.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/kpi_mbuf.h>
40 #include <sys/mcache.h>
41 #include <sys/protosw.h>
42 #include <sys/syslog.h>
43 #include <net/if_var.h>
44 #include <net/if_dl.h>
46 #include <net/if_types.h>
47 #include <net/if_dl.h>
48 #include <net/if_arp.h>
49 #include <net/if_llreach.h>
50 #include <net/if_ether.h>
51 #include <net/net_api_stats.h>
52 #include <net/route.h>
53 #include <libkern/libkern.h>
54 #include <libkern/OSAtomic.h>
55 #include <kern/locks.h>
56 #include <kern/clock.h>
57 #include <sys/sockio.h>
59 #include <sys/sysctl.h>
61 #include <netinet/ip_var.h>
62 #include <netinet/udp.h>
63 #include <netinet/udp_var.h>
64 #include <netinet/tcp.h>
65 #include <netinet/tcp_var.h>
66 #include <netinet/in_pcb.h>
68 #include <netinet/igmp_var.h>
71 #include <netinet6/mld6_var.h>
73 #include <netkey/key.h>
76 #include "net/net_str_id.h"
79 #include <sys/kauth.h>
80 #include <security/mac_framework.h>
85 errno_t
ifnet_allocate(const struct ifnet_init_params
*init
,
88 static errno_t
ifnet_allocate_common(const struct ifnet_init_params
*init
,
89 ifnet_t
*ifp
, bool is_internal
);
92 #define TOUCHLASTCHANGE(__if_lastchange) { \
93 (__if_lastchange)->tv_sec = net_uptime(); \
94 (__if_lastchange)->tv_usec = 0; \
97 static errno_t
ifnet_defrouter_llreachinfo(ifnet_t
, int,
98 struct ifnet_llreach_info
*);
99 static void ifnet_kpi_free(ifnet_t
);
100 static errno_t
ifnet_list_get_common(ifnet_family_t
, boolean_t
, ifnet_t
**,
102 static errno_t
ifnet_set_lladdr_internal(ifnet_t
, const void *, size_t,
104 static errno_t
ifnet_awdl_check_eflags(ifnet_t
, u_int32_t
*, u_int32_t
*);
107 * Temporary work around until we have real reference counting
109 * We keep the bits about calling dlil_if_release (which should be
110 * called recycle) transparent by calling it from our if_free function
111 * pointer. We have to keep the client's original detach function
112 * somewhere so we can call it.
115 ifnet_kpi_free(ifnet_t ifp
)
117 ifnet_detached_func detach_func
= ifp
->if_kpi_storage
;
119 if (detach_func
!= NULL
)
122 if (ifp
->if_broadcast
.length
> sizeof (ifp
->if_broadcast
.u
.buffer
)) {
123 FREE(ifp
->if_broadcast
.u
.ptr
, M_IFADDR
);
124 ifp
->if_broadcast
.u
.ptr
= NULL
;
127 dlil_if_release(ifp
);
131 ifnet_allocate_common(const struct ifnet_init_params
*init
,
132 ifnet_t
*ifp
, bool is_internal
)
134 struct ifnet_init_eparams einit
;
136 bzero(&einit
, sizeof (einit
));
138 einit
.ver
= IFNET_INIT_CURRENT_VERSION
;
139 einit
.len
= sizeof (einit
);
140 einit
.flags
= IFNET_INIT_LEGACY
| IFNET_INIT_NX_NOAUTO
;
142 einit
.flags
|= IFNET_INIT_ALLOC_KPI
;
144 einit
.uniqueid
= init
->uniqueid
;
145 einit
.uniqueid_len
= init
->uniqueid_len
;
146 einit
.name
= init
->name
;
147 einit
.unit
= init
->unit
;
148 einit
.family
= init
->family
;
149 einit
.type
= init
->type
;
150 einit
.output
= init
->output
;
151 einit
.demux
= init
->demux
;
152 einit
.add_proto
= init
->add_proto
;
153 einit
.del_proto
= init
->del_proto
;
154 einit
.check_multi
= init
->check_multi
;
155 einit
.framer
= init
->framer
;
156 einit
.softc
= init
->softc
;
157 einit
.ioctl
= init
->ioctl
;
158 einit
.set_bpf_tap
= init
->set_bpf_tap
;
159 einit
.detach
= init
->detach
;
160 einit
.event
= init
->event
;
161 einit
.broadcast_addr
= init
->broadcast_addr
;
162 einit
.broadcast_len
= init
->broadcast_len
;
164 return (ifnet_allocate_extended(&einit
, ifp
));
168 ifnet_allocate_internal(const struct ifnet_init_params
*init
, ifnet_t
*ifp
)
170 return (ifnet_allocate_common(init
, ifp
, true));
174 ifnet_allocate(const struct ifnet_init_params
*init
, ifnet_t
*ifp
)
176 return (ifnet_allocate_common(init
, ifp
, false));
180 ifnet_allocate_extended(const struct ifnet_init_eparams
*einit0
,
183 struct ifnet_init_eparams einit
;
184 struct ifnet
*ifp
= NULL
;
185 char if_xname
[IFXNAMSIZ
] = {0};
190 if (einit
.ver
!= IFNET_INIT_CURRENT_VERSION
||
191 einit
.len
< sizeof (einit
))
194 if (einit
.family
== 0 || einit
.name
== NULL
||
195 strlen(einit
.name
) >= IFNAMSIZ
||
196 (einit
.type
& 0xFFFFFF00) != 0 || einit
.type
== 0)
200 if (einit
.flags
& IFNET_INIT_LEGACY
) {
201 if (einit
.output
== NULL
||
202 (einit
.flags
& IFNET_INIT_INPUT_POLL
))
205 einit
.pre_enqueue
= NULL
;
207 einit
.output_ctl
= NULL
;
208 einit
.output_sched_model
= IFNET_SCHED_MODEL_NORMAL
;
209 einit
.input_poll
= NULL
;
210 einit
.input_ctl
= NULL
;
212 if (einit
.start
== NULL
)
216 if (einit
.output_sched_model
>= IFNET_SCHED_MODEL_MAX
)
219 if (einit
.flags
& IFNET_INIT_INPUT_POLL
) {
220 if (einit
.input_poll
== NULL
|| einit
.input_ctl
== NULL
)
223 einit
.input_poll
= NULL
;
224 einit
.input_ctl
= NULL
;
228 if (einit
.uniqueid
== NULL
) {
229 /* Initialize external name (name + unit) */
230 (void) snprintf(if_xname
, sizeof (if_xname
), "%s%d",
231 einit
.name
, einit
.unit
);
232 einit
.uniqueid
= if_xname
;
233 einit
.uniqueid_len
= strlen(if_xname
);
236 error
= dlil_if_acquire(einit
.family
, einit
.uniqueid
,
237 einit
.uniqueid_len
, &ifp
);
243 * Cast ifp->if_name as non const. dlil_if_acquire sets it up
244 * to point to storage of at least IFNAMSIZ bytes. It is safe
247 strlcpy(__DECONST(char *, ifp
->if_name
), einit
.name
, IFNAMSIZ
);
248 ifp
->if_type
= einit
.type
;
249 ifp
->if_family
= einit
.family
;
250 ifp
->if_subfamily
= einit
.subfamily
;
251 ifp
->if_unit
= einit
.unit
;
252 ifp
->if_output
= einit
.output
;
253 ifp
->if_pre_enqueue
= einit
.pre_enqueue
;
254 ifp
->if_start
= einit
.start
;
255 ifp
->if_output_ctl
= einit
.output_ctl
;
256 ifp
->if_output_sched_model
= einit
.output_sched_model
;
257 ifp
->if_output_bw
.eff_bw
= einit
.output_bw
;
258 ifp
->if_output_bw
.max_bw
= einit
.output_bw_max
;
259 ifp
->if_output_lt
.eff_lt
= einit
.output_lt
;
260 ifp
->if_output_lt
.max_lt
= einit
.output_lt_max
;
261 ifp
->if_input_poll
= einit
.input_poll
;
262 ifp
->if_input_ctl
= einit
.input_ctl
;
263 ifp
->if_input_bw
.eff_bw
= einit
.input_bw
;
264 ifp
->if_input_bw
.max_bw
= einit
.input_bw_max
;
265 ifp
->if_input_lt
.eff_lt
= einit
.input_lt
;
266 ifp
->if_input_lt
.max_lt
= einit
.input_lt_max
;
267 ifp
->if_demux
= einit
.demux
;
268 ifp
->if_add_proto
= einit
.add_proto
;
269 ifp
->if_del_proto
= einit
.del_proto
;
270 ifp
->if_check_multi
= einit
.check_multi
;
271 ifp
->if_framer_legacy
= einit
.framer
;
272 ifp
->if_framer
= einit
.framer_extended
;
273 ifp
->if_softc
= einit
.softc
;
274 ifp
->if_ioctl
= einit
.ioctl
;
275 ifp
->if_set_bpf_tap
= einit
.set_bpf_tap
;
276 ifp
->if_free
= ifnet_kpi_free
;
277 ifp
->if_event
= einit
.event
;
278 ifp
->if_kpi_storage
= einit
.detach
;
280 /* Initialize external name (name + unit) */
281 snprintf(__DECONST(char *, ifp
->if_xname
), IFXNAMSIZ
,
282 "%s%d", ifp
->if_name
, ifp
->if_unit
);
285 * On embedded, framer() is already in the extended form;
286 * we simply use it as is, unless the caller specifies
287 * framer_extended() which will then override it.
289 * On non-embedded, framer() has long been exposed as part
290 * of the public KPI, and therefore its signature must
291 * remain the same (without the pre- and postpend length
292 * parameters.) We special case ether_frameout, such that
293 * it gets mapped to its extended variant. All other cases
294 * utilize the stub routine which will simply return zeroes
295 * for those new parameters.
297 * Internally, DLIL will only use the extended callback
298 * variant which is represented by if_framer.
301 if (ifp
->if_framer
== NULL
&& ifp
->if_framer_legacy
!= NULL
)
302 ifp
->if_framer
= ifp
->if_framer_legacy
;
303 #else /* !CONFIG_EMBEDDED */
304 if (ifp
->if_framer
== NULL
&& ifp
->if_framer_legacy
!= NULL
) {
305 if (ifp
->if_framer_legacy
== ether_frameout
)
306 ifp
->if_framer
= ether_frameout_extended
;
308 ifp
->if_framer
= ifnet_framer_stub
;
310 #endif /* !CONFIG_EMBEDDED */
312 if (ifp
->if_output_bw
.eff_bw
> ifp
->if_output_bw
.max_bw
)
313 ifp
->if_output_bw
.max_bw
= ifp
->if_output_bw
.eff_bw
;
314 else if (ifp
->if_output_bw
.eff_bw
== 0)
315 ifp
->if_output_bw
.eff_bw
= ifp
->if_output_bw
.max_bw
;
317 if (ifp
->if_input_bw
.eff_bw
> ifp
->if_input_bw
.max_bw
)
318 ifp
->if_input_bw
.max_bw
= ifp
->if_input_bw
.eff_bw
;
319 else if (ifp
->if_input_bw
.eff_bw
== 0)
320 ifp
->if_input_bw
.eff_bw
= ifp
->if_input_bw
.max_bw
;
322 if (ifp
->if_output_bw
.max_bw
== 0)
323 ifp
->if_output_bw
= ifp
->if_input_bw
;
324 else if (ifp
->if_input_bw
.max_bw
== 0)
325 ifp
->if_input_bw
= ifp
->if_output_bw
;
327 /* Pin if_baudrate to 32 bits */
328 br
= MAX(ifp
->if_output_bw
.max_bw
, ifp
->if_input_bw
.max_bw
);
330 ifp
->if_baudrate
= (br
> 0xFFFFFFFF) ? 0xFFFFFFFF : br
;
332 if (ifp
->if_output_lt
.eff_lt
> ifp
->if_output_lt
.max_lt
)
333 ifp
->if_output_lt
.max_lt
= ifp
->if_output_lt
.eff_lt
;
334 else if (ifp
->if_output_lt
.eff_lt
== 0)
335 ifp
->if_output_lt
.eff_lt
= ifp
->if_output_lt
.max_lt
;
337 if (ifp
->if_input_lt
.eff_lt
> ifp
->if_input_lt
.max_lt
)
338 ifp
->if_input_lt
.max_lt
= ifp
->if_input_lt
.eff_lt
;
339 else if (ifp
->if_input_lt
.eff_lt
== 0)
340 ifp
->if_input_lt
.eff_lt
= ifp
->if_input_lt
.max_lt
;
342 if (ifp
->if_output_lt
.max_lt
== 0)
343 ifp
->if_output_lt
= ifp
->if_input_lt
;
344 else if (ifp
->if_input_lt
.max_lt
== 0)
345 ifp
->if_input_lt
= ifp
->if_output_lt
;
347 if (ifp
->if_ioctl
== NULL
)
348 ifp
->if_ioctl
= ifp_if_ioctl
;
351 if (ifp
->if_start
!= NULL
) {
352 ifp
->if_eflags
|= IFEF_TXSTART
;
353 if (ifp
->if_pre_enqueue
== NULL
)
354 ifp
->if_pre_enqueue
= ifnet_enqueue
;
355 ifp
->if_output
= ifp
->if_pre_enqueue
;
357 ifp
->if_eflags
&= ~IFEF_TXSTART
;
360 if (ifp
->if_input_poll
!= NULL
)
361 ifp
->if_eflags
|= IFEF_RXPOLL
;
363 ifp
->if_eflags
&= ~IFEF_RXPOLL
;
365 ifp
->if_output_dlil
= dlil_output_handler
;
366 ifp
->if_input_dlil
= dlil_input_handler
;
368 VERIFY(!(einit
.flags
& IFNET_INIT_LEGACY
) ||
369 (ifp
->if_pre_enqueue
== NULL
&& ifp
->if_start
== NULL
&&
370 ifp
->if_output_ctl
== NULL
&& ifp
->if_input_poll
== NULL
&&
371 ifp
->if_input_ctl
== NULL
));
372 VERIFY(!(einit
.flags
& IFNET_INIT_INPUT_POLL
) ||
373 (ifp
->if_input_poll
!= NULL
&& ifp
->if_input_ctl
!= NULL
));
375 if (einit
.broadcast_len
&& einit
.broadcast_addr
) {
376 if (einit
.broadcast_len
>
377 sizeof (ifp
->if_broadcast
.u
.buffer
)) {
378 MALLOC(ifp
->if_broadcast
.u
.ptr
, u_char
*,
379 einit
.broadcast_len
, M_IFADDR
, M_NOWAIT
);
380 if (ifp
->if_broadcast
.u
.ptr
== NULL
) {
383 bcopy(einit
.broadcast_addr
,
384 ifp
->if_broadcast
.u
.ptr
,
385 einit
.broadcast_len
);
388 bcopy(einit
.broadcast_addr
,
389 ifp
->if_broadcast
.u
.buffer
,
390 einit
.broadcast_len
);
392 ifp
->if_broadcast
.length
= einit
.broadcast_len
;
394 bzero(&ifp
->if_broadcast
, sizeof (ifp
->if_broadcast
));
400 * output target queue delay is specified in millisecond
401 * convert it to nanoseconds
403 IFCQ_TARGET_QDELAY(&ifp
->if_snd
) =
404 einit
.output_target_qdelay
* 1000 * 1000;
405 IFCQ_MAXLEN(&ifp
->if_snd
) = einit
.sndq_maxlen
;
407 ifnet_enqueue_multi_setup(ifp
, einit
.start_delay_qlen
,
408 einit
.start_delay_timeout
);
410 IFCQ_PKT_DROP_LIMIT(&ifp
->if_snd
) = IFCQ_DEFAULT_PKT_DROP_LIMIT
;
413 * Set embryonic flag; this will be cleared
414 * later when it is fully attached.
416 ifp
->if_refflags
= IFRF_EMBRYONIC
;
419 * Count the newly allocated ifnet
421 OSIncrementAtomic64(&net_api_stats
.nas_ifnet_alloc_count
);
422 INC_ATOMIC_INT64_LIM(net_api_stats
.nas_ifnet_alloc_total
);
423 if (einit
.flags
& IFNET_INIT_ALLOC_KPI
) {
424 ifp
->if_xflags
|= IFXF_ALLOC_KPI
;
427 &net_api_stats
.nas_ifnet_alloc_os_count
);
428 INC_ATOMIC_INT64_LIM(
429 net_api_stats
.nas_ifnet_alloc_os_total
);
434 // temporary - this should be done in dlil_if_acquire
435 ifnet_reference(ifp
);
437 dlil_if_release(ifp
);
445 ifnet_reference(ifnet_t ifp
)
447 return (dlil_if_ref(ifp
));
451 ifnet_release(ifnet_t ifp
)
453 return (dlil_if_free(ifp
));
457 ifnet_interface_family_find(const char *module_string
,
458 ifnet_family_t
*family_id
)
460 if (module_string
== NULL
|| family_id
== NULL
)
463 return (net_str_id_find_internal(module_string
, family_id
,
468 ifnet_softc(ifnet_t interface
)
470 return ((interface
== NULL
) ? NULL
: interface
->if_softc
);
474 ifnet_name(ifnet_t interface
)
476 return ((interface
== NULL
) ? NULL
: interface
->if_name
);
480 ifnet_family(ifnet_t interface
)
482 return ((interface
== NULL
) ? 0 : interface
->if_family
);
486 ifnet_subfamily(ifnet_t interface
)
488 return ((interface
== NULL
) ? 0 : interface
->if_subfamily
);
492 ifnet_unit(ifnet_t interface
)
494 return ((interface
== NULL
) ? (u_int32_t
)0xffffffff :
495 (u_int32_t
)interface
->if_unit
);
499 ifnet_index(ifnet_t interface
)
501 return ((interface
== NULL
) ? (u_int32_t
)0xffffffff :
502 interface
->if_index
);
506 ifnet_set_flags(ifnet_t interface
, u_int16_t new_flags
, u_int16_t mask
)
510 if (interface
== NULL
)
513 ifnet_lock_exclusive(interface
);
515 /* If we are modifying the up/down state, call if_updown */
516 if ((mask
& IFF_UP
) != 0) {
517 if_updown(interface
, (new_flags
& IFF_UP
) == IFF_UP
);
520 old_flags
= interface
->if_flags
;
521 interface
->if_flags
= (new_flags
& mask
) | (interface
->if_flags
& ~mask
);
522 /* If we are modifying the multicast flag, set/unset the silent flag */
523 if ((old_flags
& IFF_MULTICAST
) !=
524 (interface
->if_flags
& IFF_MULTICAST
)) {
526 if (IGMP_IFINFO(interface
) != NULL
)
527 igmp_initsilent(interface
, IGMP_IFINFO(interface
));
530 if (MLD_IFINFO(interface
) != NULL
)
531 mld6_initsilent(interface
, MLD_IFINFO(interface
));
535 ifnet_lock_done(interface
);
541 ifnet_flags(ifnet_t interface
)
543 return ((interface
== NULL
) ? 0 : interface
->if_flags
);
547 * This routine ensures the following:
549 * If IFEF_AWDL is set by the caller, also set the rest of flags as
550 * defined in IFEF_AWDL_MASK.
552 * If IFEF_AWDL has been set on the interface and the caller attempts
553 * to clear one or more of the associated flags in IFEF_AWDL_MASK,
556 * If IFEF_AWDL_RESTRICTED is set by the caller, make sure IFEF_AWDL is set
559 * All other flags not associated with AWDL are not affected.
561 * See <net/if.h> for current definition of IFEF_AWDL_MASK.
564 ifnet_awdl_check_eflags(ifnet_t ifp
, u_int32_t
*new_eflags
, u_int32_t
*mask
)
568 ifnet_lock_assert(ifp
, IFNET_LCK_ASSERT_EXCLUSIVE
);
570 eflags
= (*new_eflags
& *mask
) | (ifp
->if_eflags
& ~(*mask
));
572 if (ifp
->if_eflags
& IFEF_AWDL
) {
573 if (eflags
& IFEF_AWDL
) {
574 if ((eflags
& IFEF_AWDL_MASK
) != IFEF_AWDL_MASK
)
577 *new_eflags
&= ~IFEF_AWDL_MASK
;
578 *mask
|= IFEF_AWDL_MASK
;
580 } else if (eflags
& IFEF_AWDL
) {
581 *new_eflags
|= IFEF_AWDL_MASK
;
582 *mask
|= IFEF_AWDL_MASK
;
583 } else if (eflags
& IFEF_AWDL_RESTRICTED
&&
584 !(ifp
->if_eflags
& IFEF_AWDL
))
591 ifnet_set_eflags(ifnet_t interface
, u_int32_t new_flags
, u_int32_t mask
)
594 struct kev_msg ev_msg
;
595 struct net_event_data ev_data
;
597 if (interface
== NULL
)
600 bzero(&ev_msg
, sizeof(ev_msg
));
601 ifnet_lock_exclusive(interface
);
603 * Sanity checks for IFEF_AWDL and its related flags.
605 if (ifnet_awdl_check_eflags(interface
, &new_flags
, &mask
) != 0) {
606 ifnet_lock_done(interface
);
609 oeflags
= interface
->if_eflags
;
610 interface
->if_eflags
=
611 (new_flags
& mask
) | (interface
->if_eflags
& ~mask
);
612 ifnet_lock_done(interface
);
613 if (interface
->if_eflags
& IFEF_AWDL_RESTRICTED
&&
614 !(oeflags
& IFEF_AWDL_RESTRICTED
)) {
615 ev_msg
.event_code
= KEV_DL_AWDL_RESTRICTED
;
617 * The interface is now restricted to applications that have
619 * The check for the entitlement will be done in the data
620 * path, so we don't have to do anything here.
622 } else if (oeflags
& IFEF_AWDL_RESTRICTED
&&
623 !(interface
->if_eflags
& IFEF_AWDL_RESTRICTED
))
624 ev_msg
.event_code
= KEV_DL_AWDL_UNRESTRICTED
;
626 * Notify configd so that it has a chance to perform better
627 * reachability detection.
629 if (ev_msg
.event_code
) {
630 bzero(&ev_data
, sizeof(ev_data
));
631 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
632 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
633 ev_msg
.kev_subclass
= KEV_DL_SUBCLASS
;
634 strlcpy(ev_data
.if_name
, interface
->if_name
, IFNAMSIZ
);
635 ev_data
.if_family
= interface
->if_family
;
636 ev_data
.if_unit
= interface
->if_unit
;
637 ev_msg
.dv
[0].data_length
= sizeof(struct net_event_data
);
638 ev_msg
.dv
[0].data_ptr
= &ev_data
;
639 ev_msg
.dv
[1].data_length
= 0;
640 dlil_post_complete_msg(interface
, &ev_msg
);
647 ifnet_eflags(ifnet_t interface
)
649 return ((interface
== NULL
) ? 0 : interface
->if_eflags
);
653 ifnet_set_idle_flags_locked(ifnet_t ifp
, u_int32_t new_flags
, u_int32_t mask
)
660 LCK_MTX_ASSERT(rnh_lock
, LCK_MTX_ASSERT_OWNED
);
661 ifnet_lock_assert(ifp
, IFNET_LCK_ASSERT_EXCLUSIVE
);
664 * If this is called prior to ifnet attach, the actual work will
665 * be done at attach time. Otherwise, if it is called after
666 * ifnet detach, then it is a no-op.
668 if (!ifnet_is_attached(ifp
, 0)) {
669 ifp
->if_idle_new_flags
= new_flags
;
670 ifp
->if_idle_new_flags_mask
= mask
;
673 ifp
->if_idle_new_flags
= ifp
->if_idle_new_flags_mask
= 0;
676 before
= ifp
->if_idle_flags
;
677 ifp
->if_idle_flags
= (new_flags
& mask
) | (ifp
->if_idle_flags
& ~mask
);
678 after
= ifp
->if_idle_flags
;
680 if ((after
- before
) < 0 && ifp
->if_idle_flags
== 0 &&
681 ifp
->if_want_aggressive_drain
!= 0) {
682 ifp
->if_want_aggressive_drain
= 0;
683 } else if ((after
- before
) > 0 && ifp
->if_want_aggressive_drain
== 0) {
684 ifp
->if_want_aggressive_drain
++;
691 ifnet_set_idle_flags(ifnet_t ifp
, u_int32_t new_flags
, u_int32_t mask
)
695 lck_mtx_lock(rnh_lock
);
696 ifnet_lock_exclusive(ifp
);
697 err
= ifnet_set_idle_flags_locked(ifp
, new_flags
, mask
);
698 ifnet_lock_done(ifp
);
699 lck_mtx_unlock(rnh_lock
);
705 ifnet_idle_flags(ifnet_t ifp
)
707 return ((ifp
== NULL
) ? 0 : ifp
->if_idle_flags
);
711 ifnet_set_link_quality(ifnet_t ifp
, int quality
)
715 if (ifp
== NULL
|| quality
< IFNET_LQM_MIN
|| quality
> IFNET_LQM_MAX
) {
720 if (!ifnet_is_attached(ifp
, 0)) {
725 if_lqm_update(ifp
, quality
, 0);
732 ifnet_link_quality(ifnet_t ifp
)
737 return (IFNET_LQM_THRESH_OFF
);
739 ifnet_lock_shared(ifp
);
740 lqm
= ifp
->if_interface_state
.lqm_state
;
741 ifnet_lock_done(ifp
);
747 ifnet_set_interface_state(ifnet_t ifp
,
748 struct if_interface_state
*if_interface_state
)
752 if (ifp
== NULL
|| if_interface_state
== NULL
) {
757 if (!ifnet_is_attached(ifp
, 0)) {
762 if_state_update(ifp
, if_interface_state
);
769 ifnet_get_interface_state(ifnet_t ifp
,
770 struct if_interface_state
*if_interface_state
)
774 if (ifp
== NULL
|| if_interface_state
== NULL
) {
779 if (!ifnet_is_attached(ifp
, 0)) {
784 if_get_state(ifp
, if_interface_state
);
792 ifnet_defrouter_llreachinfo(ifnet_t ifp
, int af
,
793 struct ifnet_llreach_info
*iflri
)
795 if (ifp
== NULL
|| iflri
== NULL
)
798 VERIFY(af
== AF_INET
|| af
== AF_INET6
);
800 return (ifnet_llreach_get_defrouter(ifp
, af
, iflri
));
804 ifnet_inet_defrouter_llreachinfo(ifnet_t ifp
, struct ifnet_llreach_info
*iflri
)
806 return (ifnet_defrouter_llreachinfo(ifp
, AF_INET
, iflri
));
810 ifnet_inet6_defrouter_llreachinfo(ifnet_t ifp
, struct ifnet_llreach_info
*iflri
)
812 return (ifnet_defrouter_llreachinfo(ifp
, AF_INET6
, iflri
));
816 ifnet_set_capabilities_supported(ifnet_t ifp
, u_int32_t new_caps
,
825 ifnet_lock_exclusive(ifp
);
826 tmp
= (new_caps
& mask
) | (ifp
->if_capabilities
& ~mask
);
827 if ((tmp
& ~IFCAP_VALID
))
830 ifp
->if_capabilities
= tmp
;
831 ifnet_lock_done(ifp
);
837 ifnet_capabilities_supported(ifnet_t ifp
)
839 return ((ifp
== NULL
) ? 0 : ifp
->if_capabilities
);
844 ifnet_set_capabilities_enabled(ifnet_t ifp
, u_int32_t new_caps
,
849 struct kev_msg ev_msg
;
850 struct net_event_data ev_data
;
855 ifnet_lock_exclusive(ifp
);
856 tmp
= (new_caps
& mask
) | (ifp
->if_capenable
& ~mask
);
857 if ((tmp
& ~IFCAP_VALID
) || (tmp
& ~ifp
->if_capabilities
))
860 ifp
->if_capenable
= tmp
;
861 ifnet_lock_done(ifp
);
863 /* Notify application of the change */
864 bzero(&ev_data
, sizeof (struct net_event_data
));
865 bzero(&ev_msg
, sizeof (struct kev_msg
));
866 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
867 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
868 ev_msg
.kev_subclass
= KEV_DL_SUBCLASS
;
870 ev_msg
.event_code
= KEV_DL_IFCAP_CHANGED
;
871 strlcpy(&ev_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
872 ev_data
.if_family
= ifp
->if_family
;
873 ev_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
874 ev_msg
.dv
[0].data_length
= sizeof (struct net_event_data
);
875 ev_msg
.dv
[0].data_ptr
= &ev_data
;
876 ev_msg
.dv
[1].data_length
= 0;
877 dlil_post_complete_msg(ifp
, &ev_msg
);
883 ifnet_capabilities_enabled(ifnet_t ifp
)
885 return ((ifp
== NULL
) ? 0 : ifp
->if_capenable
);
888 static const ifnet_offload_t offload_mask
=
889 (IFNET_CSUM_IP
| IFNET_CSUM_TCP
| IFNET_CSUM_UDP
| IFNET_CSUM_FRAGMENT
|
890 IFNET_IP_FRAGMENT
| IFNET_CSUM_TCPIPV6
| IFNET_CSUM_UDPIPV6
|
891 IFNET_IPV6_FRAGMENT
| IFNET_CSUM_PARTIAL
| IFNET_CSUM_ZERO_INVERT
|
892 IFNET_VLAN_TAGGING
| IFNET_VLAN_MTU
| IFNET_MULTIPAGES
|
893 IFNET_TSO_IPV4
| IFNET_TSO_IPV6
| IFNET_TX_STATUS
| IFNET_HW_TIMESTAMP
|
896 static const ifnet_offload_t any_offload_csum
= IFNET_CHECKSUMF
;
899 ifnet_set_offload(ifnet_t interface
, ifnet_offload_t offload
)
901 u_int32_t ifcaps
= 0;
903 if (interface
== NULL
)
906 ifnet_lock_exclusive(interface
);
907 interface
->if_hwassist
= (offload
& offload_mask
);
910 * Hardware capable of partial checksum offload is
911 * flexible enough to handle any transports utilizing
912 * Internet Checksumming. Include those transports
913 * here, and leave the final decision to IP.
915 if (interface
->if_hwassist
& IFNET_CSUM_PARTIAL
) {
916 interface
->if_hwassist
|= (IFNET_CSUM_TCP
| IFNET_CSUM_UDP
|
917 IFNET_CSUM_TCPIPV6
| IFNET_CSUM_UDPIPV6
);
920 log(LOG_DEBUG
, "%s: set offload flags=%b\n",
922 interface
->if_hwassist
, IFNET_OFFLOADF_BITS
);
924 ifnet_lock_done(interface
);
926 if ((offload
& any_offload_csum
))
927 ifcaps
|= IFCAP_HWCSUM
;
928 if ((offload
& IFNET_TSO_IPV4
))
929 ifcaps
|= IFCAP_TSO4
;
930 if ((offload
& IFNET_TSO_IPV6
))
931 ifcaps
|= IFCAP_TSO6
;
932 if ((offload
& IFNET_VLAN_MTU
))
933 ifcaps
|= IFCAP_VLAN_MTU
;
934 if ((offload
& IFNET_VLAN_TAGGING
))
935 ifcaps
|= IFCAP_VLAN_HWTAGGING
;
936 if ((offload
& IFNET_TX_STATUS
))
937 ifcaps
|= IFCAP_TXSTATUS
;
938 if ((offload
& IFNET_HW_TIMESTAMP
))
939 ifcaps
|= IFCAP_HW_TIMESTAMP
;
940 if ((offload
& IFNET_SW_TIMESTAMP
))
941 ifcaps
|= IFCAP_SW_TIMESTAMP
;
942 if ((offload
& IFNET_CSUM_PARTIAL
))
943 ifcaps
|= IFCAP_CSUM_PARTIAL
;
944 if ((offload
& IFNET_CSUM_ZERO_INVERT
))
945 ifcaps
|= IFCAP_CSUM_ZERO_INVERT
;
947 (void) ifnet_set_capabilities_supported(interface
, ifcaps
,
949 (void) ifnet_set_capabilities_enabled(interface
, ifcaps
,
957 ifnet_offload(ifnet_t interface
)
959 return ((interface
== NULL
) ?
960 0 : (interface
->if_hwassist
& offload_mask
));
964 ifnet_set_tso_mtu(ifnet_t interface
, sa_family_t family
, u_int32_t mtuLen
)
968 if (interface
== NULL
|| mtuLen
< interface
->if_mtu
)
973 if (interface
->if_hwassist
& IFNET_TSO_IPV4
)
974 interface
->if_tso_v4_mtu
= mtuLen
;
980 if (interface
->if_hwassist
& IFNET_TSO_IPV6
)
981 interface
->if_tso_v6_mtu
= mtuLen
;
987 error
= EPROTONOSUPPORT
;
995 ifnet_get_tso_mtu(ifnet_t interface
, sa_family_t family
, u_int32_t
*mtuLen
)
999 if (interface
== NULL
|| mtuLen
== NULL
)
1004 if (interface
->if_hwassist
& IFNET_TSO_IPV4
)
1005 *mtuLen
= interface
->if_tso_v4_mtu
;
1011 if (interface
->if_hwassist
& IFNET_TSO_IPV6
)
1012 *mtuLen
= interface
->if_tso_v6_mtu
;
1018 error
= EPROTONOSUPPORT
;
1026 ifnet_set_wake_flags(ifnet_t interface
, u_int32_t properties
, u_int32_t mask
)
1028 struct kev_msg ev_msg
;
1029 struct net_event_data ev_data
;
1031 bzero(&ev_data
, sizeof (struct net_event_data
));
1032 bzero(&ev_msg
, sizeof (struct kev_msg
));
1034 if (interface
== NULL
)
1037 /* Do not accept wacky values */
1038 if ((properties
& mask
) & ~IF_WAKE_VALID_FLAGS
)
1041 ifnet_lock_exclusive(interface
);
1043 if (mask
& IF_WAKE_ON_MAGIC_PACKET
) {
1044 if (properties
& IF_WAKE_ON_MAGIC_PACKET
)
1045 interface
->if_xflags
|= IFXF_WAKE_ON_MAGIC_PACKET
;
1047 interface
->if_xflags
&= ~IFXF_WAKE_ON_MAGIC_PACKET
;
1050 ifnet_lock_done(interface
);
1052 (void) ifnet_touch_lastchange(interface
);
1054 /* Notify application of the change */
1055 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1056 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1057 ev_msg
.kev_subclass
= KEV_DL_SUBCLASS
;
1059 ev_msg
.event_code
= KEV_DL_WAKEFLAGS_CHANGED
;
1060 strlcpy(&ev_data
.if_name
[0], interface
->if_name
, IFNAMSIZ
);
1061 ev_data
.if_family
= interface
->if_family
;
1062 ev_data
.if_unit
= (u_int32_t
)interface
->if_unit
;
1063 ev_msg
.dv
[0].data_length
= sizeof (struct net_event_data
);
1064 ev_msg
.dv
[0].data_ptr
= &ev_data
;
1065 ev_msg
.dv
[1].data_length
= 0;
1066 dlil_post_complete_msg(interface
, &ev_msg
);
1072 ifnet_get_wake_flags(ifnet_t interface
)
1074 u_int32_t flags
= 0;
1076 if (interface
== NULL
)
1079 if (interface
->if_xflags
& IFXF_WAKE_ON_MAGIC_PACKET
)
1080 flags
|= IF_WAKE_ON_MAGIC_PACKET
;
1086 * Should MIB data store a copy?
1089 ifnet_set_link_mib_data(ifnet_t interface
, void *mibData
, u_int32_t mibLen
)
1091 if (interface
== NULL
)
1094 ifnet_lock_exclusive(interface
);
1095 interface
->if_linkmib
= (void*)mibData
;
1096 interface
->if_linkmiblen
= mibLen
;
1097 ifnet_lock_done(interface
);
1102 ifnet_get_link_mib_data(ifnet_t interface
, void *mibData
, u_int32_t
*mibLen
)
1106 if (interface
== NULL
)
1109 ifnet_lock_shared(interface
);
1110 if (*mibLen
< interface
->if_linkmiblen
)
1112 if (result
== 0 && interface
->if_linkmib
== NULL
)
1116 *mibLen
= interface
->if_linkmiblen
;
1117 bcopy(interface
->if_linkmib
, mibData
, *mibLen
);
1119 ifnet_lock_done(interface
);
1125 ifnet_get_link_mib_data_length(ifnet_t interface
)
1127 return ((interface
== NULL
) ? 0 : interface
->if_linkmiblen
);
1131 ifnet_output(ifnet_t interface
, protocol_family_t protocol_family
,
1132 mbuf_t m
, void *route
, const struct sockaddr
*dest
)
1134 if (interface
== NULL
|| protocol_family
== 0 || m
== NULL
) {
1139 return (dlil_output(interface
, protocol_family
, m
, route
, dest
, 0, NULL
));
1143 ifnet_output_raw(ifnet_t interface
, protocol_family_t protocol_family
, mbuf_t m
)
1145 if (interface
== NULL
|| m
== NULL
) {
1150 return (dlil_output(interface
, protocol_family
, m
, NULL
, NULL
, 1, NULL
));
1154 ifnet_set_mtu(ifnet_t interface
, u_int32_t mtu
)
1156 if (interface
== NULL
)
1159 interface
->if_mtu
= mtu
;
1164 ifnet_mtu(ifnet_t interface
)
1166 return ((interface
== NULL
) ? 0 : interface
->if_mtu
);
1170 ifnet_type(ifnet_t interface
)
1172 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_type
);
1176 ifnet_set_addrlen(ifnet_t interface
, u_char addrlen
)
1178 if (interface
== NULL
)
1181 interface
->if_data
.ifi_addrlen
= addrlen
;
1186 ifnet_addrlen(ifnet_t interface
)
1188 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_addrlen
);
1192 ifnet_set_hdrlen(ifnet_t interface
, u_char hdrlen
)
1194 if (interface
== NULL
)
1197 interface
->if_data
.ifi_hdrlen
= hdrlen
;
1202 ifnet_hdrlen(ifnet_t interface
)
1204 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_hdrlen
);
1208 ifnet_set_metric(ifnet_t interface
, u_int32_t metric
)
1210 if (interface
== NULL
)
1213 interface
->if_data
.ifi_metric
= metric
;
1218 ifnet_metric(ifnet_t interface
)
1220 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_metric
);
1224 ifnet_set_baudrate(struct ifnet
*ifp
, u_int64_t baudrate
)
1229 ifp
->if_output_bw
.max_bw
= ifp
->if_input_bw
.max_bw
=
1230 ifp
->if_output_bw
.eff_bw
= ifp
->if_input_bw
.eff_bw
= baudrate
;
1232 /* Pin if_baudrate to 32 bits until we can change the storage size */
1233 ifp
->if_baudrate
= (baudrate
> 0xFFFFFFFF) ? 0xFFFFFFFF : baudrate
;
1239 ifnet_baudrate(struct ifnet
*ifp
)
1241 return ((ifp
== NULL
) ? 0 : ifp
->if_baudrate
);
1245 ifnet_set_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*output_bw
,
1246 struct if_bandwidths
*input_bw
)
1251 /* set input values first (if any), as output values depend on them */
1252 if (input_bw
!= NULL
)
1253 (void) ifnet_set_input_bandwidths(ifp
, input_bw
);
1255 if (output_bw
!= NULL
)
1256 (void) ifnet_set_output_bandwidths(ifp
, output_bw
, FALSE
);
1262 ifnet_set_link_status_outbw(struct ifnet
*ifp
)
1264 struct if_wifi_status_v1
*sr
;
1265 sr
= &ifp
->if_link_status
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
1266 if (ifp
->if_output_bw
.eff_bw
!= 0) {
1267 sr
->valid_bitmask
|=
1268 IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID
;
1269 sr
->ul_effective_bandwidth
=
1270 ifp
->if_output_bw
.eff_bw
;
1272 if (ifp
->if_output_bw
.max_bw
!= 0) {
1273 sr
->valid_bitmask
|=
1274 IF_WIFI_UL_MAX_BANDWIDTH_VALID
;
1275 sr
->ul_max_bandwidth
=
1276 ifp
->if_output_bw
.max_bw
;
1281 ifnet_set_output_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*bw
,
1284 struct if_bandwidths old_bw
;
1285 struct ifclassq
*ifq
;
1288 VERIFY(ifp
!= NULL
&& bw
!= NULL
);
1293 IFCQ_LOCK_ASSERT_HELD(ifq
);
1295 old_bw
= ifp
->if_output_bw
;
1296 if (bw
->eff_bw
!= 0)
1297 ifp
->if_output_bw
.eff_bw
= bw
->eff_bw
;
1298 if (bw
->max_bw
!= 0)
1299 ifp
->if_output_bw
.max_bw
= bw
->max_bw
;
1300 if (ifp
->if_output_bw
.eff_bw
> ifp
->if_output_bw
.max_bw
)
1301 ifp
->if_output_bw
.max_bw
= ifp
->if_output_bw
.eff_bw
;
1302 else if (ifp
->if_output_bw
.eff_bw
== 0)
1303 ifp
->if_output_bw
.eff_bw
= ifp
->if_output_bw
.max_bw
;
1305 /* Pin if_baudrate to 32 bits */
1306 br
= MAX(ifp
->if_output_bw
.max_bw
, ifp
->if_input_bw
.max_bw
);
1308 ifp
->if_baudrate
= (br
> 0xFFFFFFFF) ? 0xFFFFFFFF : br
;
1310 /* Adjust queue parameters if needed */
1311 if (old_bw
.eff_bw
!= ifp
->if_output_bw
.eff_bw
||
1312 old_bw
.max_bw
!= ifp
->if_output_bw
.max_bw
)
1313 ifnet_update_sndq(ifq
, CLASSQ_EV_LINK_BANDWIDTH
);
1319 * If this is a Wifi interface, update the values in
1320 * if_link_status structure also.
1322 if (IFNET_IS_WIFI(ifp
) && ifp
->if_link_status
!= NULL
) {
1323 lck_rw_lock_exclusive(&ifp
->if_link_status_lock
);
1324 ifnet_set_link_status_outbw(ifp
);
1325 lck_rw_done(&ifp
->if_link_status_lock
);
1332 ifnet_set_link_status_inbw(struct ifnet
*ifp
)
1334 struct if_wifi_status_v1
*sr
;
1336 sr
= &ifp
->if_link_status
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
1337 if (ifp
->if_input_bw
.eff_bw
!= 0) {
1338 sr
->valid_bitmask
|=
1339 IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID
;
1340 sr
->dl_effective_bandwidth
=
1341 ifp
->if_input_bw
.eff_bw
;
1343 if (ifp
->if_input_bw
.max_bw
!= 0) {
1344 sr
->valid_bitmask
|=
1345 IF_WIFI_DL_MAX_BANDWIDTH_VALID
;
1346 sr
->dl_max_bandwidth
= ifp
->if_input_bw
.max_bw
;
1351 ifnet_set_input_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*bw
)
1353 struct if_bandwidths old_bw
;
1355 VERIFY(ifp
!= NULL
&& bw
!= NULL
);
1357 old_bw
= ifp
->if_input_bw
;
1358 if (bw
->eff_bw
!= 0)
1359 ifp
->if_input_bw
.eff_bw
= bw
->eff_bw
;
1360 if (bw
->max_bw
!= 0)
1361 ifp
->if_input_bw
.max_bw
= bw
->max_bw
;
1362 if (ifp
->if_input_bw
.eff_bw
> ifp
->if_input_bw
.max_bw
)
1363 ifp
->if_input_bw
.max_bw
= ifp
->if_input_bw
.eff_bw
;
1364 else if (ifp
->if_input_bw
.eff_bw
== 0)
1365 ifp
->if_input_bw
.eff_bw
= ifp
->if_input_bw
.max_bw
;
1367 if (IFNET_IS_WIFI(ifp
) && ifp
->if_link_status
!= NULL
) {
1368 lck_rw_lock_exclusive(&ifp
->if_link_status_lock
);
1369 ifnet_set_link_status_inbw(ifp
);
1370 lck_rw_done(&ifp
->if_link_status_lock
);
1373 if (old_bw
.eff_bw
!= ifp
->if_input_bw
.eff_bw
||
1374 old_bw
.max_bw
!= ifp
->if_input_bw
.max_bw
)
1375 ifnet_update_rcv(ifp
, CLASSQ_EV_LINK_BANDWIDTH
);
1381 ifnet_output_linkrate(struct ifnet
*ifp
)
1383 struct ifclassq
*ifq
= &ifp
->if_snd
;
1386 IFCQ_LOCK_ASSERT_HELD(ifq
);
1388 rate
= ifp
->if_output_bw
.eff_bw
;
1389 if (IFCQ_TBR_IS_ENABLED(ifq
)) {
1390 u_int64_t tbr_rate
= ifp
->if_snd
.ifcq_tbr
.tbr_rate_raw
;
1391 VERIFY(tbr_rate
> 0);
1392 rate
= MIN(rate
, ifp
->if_snd
.ifcq_tbr
.tbr_rate_raw
);
1399 ifnet_input_linkrate(struct ifnet
*ifp
)
1401 return (ifp
->if_input_bw
.eff_bw
);
1405 ifnet_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*output_bw
,
1406 struct if_bandwidths
*input_bw
)
1411 if (output_bw
!= NULL
)
1412 *output_bw
= ifp
->if_output_bw
;
1413 if (input_bw
!= NULL
)
1414 *input_bw
= ifp
->if_input_bw
;
1420 ifnet_set_latencies(struct ifnet
*ifp
, struct if_latencies
*output_lt
,
1421 struct if_latencies
*input_lt
)
1426 if (output_lt
!= NULL
)
1427 (void) ifnet_set_output_latencies(ifp
, output_lt
, FALSE
);
1429 if (input_lt
!= NULL
)
1430 (void) ifnet_set_input_latencies(ifp
, input_lt
);
1436 ifnet_set_output_latencies(struct ifnet
*ifp
, struct if_latencies
*lt
,
1439 struct if_latencies old_lt
;
1440 struct ifclassq
*ifq
;
1442 VERIFY(ifp
!= NULL
&& lt
!= NULL
);
1447 IFCQ_LOCK_ASSERT_HELD(ifq
);
1449 old_lt
= ifp
->if_output_lt
;
1450 if (lt
->eff_lt
!= 0)
1451 ifp
->if_output_lt
.eff_lt
= lt
->eff_lt
;
1452 if (lt
->max_lt
!= 0)
1453 ifp
->if_output_lt
.max_lt
= lt
->max_lt
;
1454 if (ifp
->if_output_lt
.eff_lt
> ifp
->if_output_lt
.max_lt
)
1455 ifp
->if_output_lt
.max_lt
= ifp
->if_output_lt
.eff_lt
;
1456 else if (ifp
->if_output_lt
.eff_lt
== 0)
1457 ifp
->if_output_lt
.eff_lt
= ifp
->if_output_lt
.max_lt
;
1459 /* Adjust queue parameters if needed */
1460 if (old_lt
.eff_lt
!= ifp
->if_output_lt
.eff_lt
||
1461 old_lt
.max_lt
!= ifp
->if_output_lt
.max_lt
)
1462 ifnet_update_sndq(ifq
, CLASSQ_EV_LINK_LATENCY
);
1471 ifnet_set_input_latencies(struct ifnet
*ifp
, struct if_latencies
*lt
)
1473 struct if_latencies old_lt
;
1475 VERIFY(ifp
!= NULL
&& lt
!= NULL
);
1477 old_lt
= ifp
->if_input_lt
;
1478 if (lt
->eff_lt
!= 0)
1479 ifp
->if_input_lt
.eff_lt
= lt
->eff_lt
;
1480 if (lt
->max_lt
!= 0)
1481 ifp
->if_input_lt
.max_lt
= lt
->max_lt
;
1482 if (ifp
->if_input_lt
.eff_lt
> ifp
->if_input_lt
.max_lt
)
1483 ifp
->if_input_lt
.max_lt
= ifp
->if_input_lt
.eff_lt
;
1484 else if (ifp
->if_input_lt
.eff_lt
== 0)
1485 ifp
->if_input_lt
.eff_lt
= ifp
->if_input_lt
.max_lt
;
1487 if (old_lt
.eff_lt
!= ifp
->if_input_lt
.eff_lt
||
1488 old_lt
.max_lt
!= ifp
->if_input_lt
.max_lt
)
1489 ifnet_update_rcv(ifp
, CLASSQ_EV_LINK_LATENCY
);
1495 ifnet_latencies(struct ifnet
*ifp
, struct if_latencies
*output_lt
,
1496 struct if_latencies
*input_lt
)
1501 if (output_lt
!= NULL
)
1502 *output_lt
= ifp
->if_output_lt
;
1503 if (input_lt
!= NULL
)
1504 *input_lt
= ifp
->if_input_lt
;
1510 ifnet_set_poll_params(struct ifnet
*ifp
, struct ifnet_poll_params
*p
)
1516 else if (!ifnet_is_attached(ifp
, 1))
1519 err
= dlil_rxpoll_set_params(ifp
, p
, FALSE
);
1521 /* Release the io ref count */
1522 ifnet_decr_iorefcnt(ifp
);
1528 ifnet_poll_params(struct ifnet
*ifp
, struct ifnet_poll_params
*p
)
1532 if (ifp
== NULL
|| p
== NULL
)
1534 else if (!ifnet_is_attached(ifp
, 1))
1537 err
= dlil_rxpoll_get_params(ifp
, p
);
1539 /* Release the io ref count */
1540 ifnet_decr_iorefcnt(ifp
);
1546 ifnet_stat_increment(struct ifnet
*ifp
,
1547 const struct ifnet_stat_increment_param
*s
)
1552 if (s
->packets_in
!= 0)
1553 atomic_add_64(&ifp
->if_data
.ifi_ipackets
, s
->packets_in
);
1554 if (s
->bytes_in
!= 0)
1555 atomic_add_64(&ifp
->if_data
.ifi_ibytes
, s
->bytes_in
);
1556 if (s
->errors_in
!= 0)
1557 atomic_add_64(&ifp
->if_data
.ifi_ierrors
, s
->errors_in
);
1559 if (s
->packets_out
!= 0)
1560 atomic_add_64(&ifp
->if_data
.ifi_opackets
, s
->packets_out
);
1561 if (s
->bytes_out
!= 0)
1562 atomic_add_64(&ifp
->if_data
.ifi_obytes
, s
->bytes_out
);
1563 if (s
->errors_out
!= 0)
1564 atomic_add_64(&ifp
->if_data
.ifi_oerrors
, s
->errors_out
);
1566 if (s
->collisions
!= 0)
1567 atomic_add_64(&ifp
->if_data
.ifi_collisions
, s
->collisions
);
1568 if (s
->dropped
!= 0)
1569 atomic_add_64(&ifp
->if_data
.ifi_iqdrops
, s
->dropped
);
1571 /* Touch the last change time. */
1572 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1574 if (ifp
->if_data_threshold
!= 0)
1575 ifnet_notify_data_threshold(ifp
);
1581 ifnet_stat_increment_in(struct ifnet
*ifp
, u_int32_t packets_in
,
1582 u_int32_t bytes_in
, u_int32_t errors_in
)
1587 if (packets_in
!= 0)
1588 atomic_add_64(&ifp
->if_data
.ifi_ipackets
, packets_in
);
1590 atomic_add_64(&ifp
->if_data
.ifi_ibytes
, bytes_in
);
1592 atomic_add_64(&ifp
->if_data
.ifi_ierrors
, errors_in
);
1594 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1596 if (ifp
->if_data_threshold
!= 0)
1597 ifnet_notify_data_threshold(ifp
);
1603 ifnet_stat_increment_out(struct ifnet
*ifp
, u_int32_t packets_out
,
1604 u_int32_t bytes_out
, u_int32_t errors_out
)
1609 if (packets_out
!= 0)
1610 atomic_add_64(&ifp
->if_data
.ifi_opackets
, packets_out
);
1612 atomic_add_64(&ifp
->if_data
.ifi_obytes
, bytes_out
);
1613 if (errors_out
!= 0)
1614 atomic_add_64(&ifp
->if_data
.ifi_oerrors
, errors_out
);
1616 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1618 if (ifp
->if_data_threshold
!= 0)
1619 ifnet_notify_data_threshold(ifp
);
1625 ifnet_set_stat(struct ifnet
*ifp
, const struct ifnet_stats_param
*s
)
1630 atomic_set_64(&ifp
->if_data
.ifi_ipackets
, s
->packets_in
);
1631 atomic_set_64(&ifp
->if_data
.ifi_ibytes
, s
->bytes_in
);
1632 atomic_set_64(&ifp
->if_data
.ifi_imcasts
, s
->multicasts_in
);
1633 atomic_set_64(&ifp
->if_data
.ifi_ierrors
, s
->errors_in
);
1635 atomic_set_64(&ifp
->if_data
.ifi_opackets
, s
->packets_out
);
1636 atomic_set_64(&ifp
->if_data
.ifi_obytes
, s
->bytes_out
);
1637 atomic_set_64(&ifp
->if_data
.ifi_omcasts
, s
->multicasts_out
);
1638 atomic_set_64(&ifp
->if_data
.ifi_oerrors
, s
->errors_out
);
1640 atomic_set_64(&ifp
->if_data
.ifi_collisions
, s
->collisions
);
1641 atomic_set_64(&ifp
->if_data
.ifi_iqdrops
, s
->dropped
);
1642 atomic_set_64(&ifp
->if_data
.ifi_noproto
, s
->no_protocol
);
1644 /* Touch the last change time. */
1645 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1647 if (ifp
->if_data_threshold
!= 0)
1648 ifnet_notify_data_threshold(ifp
);
1654 ifnet_stat(struct ifnet
*ifp
, struct ifnet_stats_param
*s
)
1659 atomic_get_64(s
->packets_in
, &ifp
->if_data
.ifi_ipackets
);
1660 atomic_get_64(s
->bytes_in
, &ifp
->if_data
.ifi_ibytes
);
1661 atomic_get_64(s
->multicasts_in
, &ifp
->if_data
.ifi_imcasts
);
1662 atomic_get_64(s
->errors_in
, &ifp
->if_data
.ifi_ierrors
);
1664 atomic_get_64(s
->packets_out
, &ifp
->if_data
.ifi_opackets
);
1665 atomic_get_64(s
->bytes_out
, &ifp
->if_data
.ifi_obytes
);
1666 atomic_get_64(s
->multicasts_out
, &ifp
->if_data
.ifi_omcasts
);
1667 atomic_get_64(s
->errors_out
, &ifp
->if_data
.ifi_oerrors
);
1669 atomic_get_64(s
->collisions
, &ifp
->if_data
.ifi_collisions
);
1670 atomic_get_64(s
->dropped
, &ifp
->if_data
.ifi_iqdrops
);
1671 atomic_get_64(s
->no_protocol
, &ifp
->if_data
.ifi_noproto
);
1673 if (ifp
->if_data_threshold
!= 0)
1674 ifnet_notify_data_threshold(ifp
);
1680 ifnet_touch_lastchange(ifnet_t interface
)
1682 if (interface
== NULL
)
1685 TOUCHLASTCHANGE(&interface
->if_lastchange
);
1691 ifnet_lastchange(ifnet_t interface
, struct timeval
*last_change
)
1693 if (interface
== NULL
)
1696 *last_change
= interface
->if_data
.ifi_lastchange
;
1697 /* Crude conversion from uptime to calendar time */
1698 last_change
->tv_sec
+= boottime_sec();
1704 ifnet_get_address_list(ifnet_t interface
, ifaddr_t
**addresses
)
1706 return (addresses
== NULL
? EINVAL
:
1707 ifnet_get_address_list_family(interface
, addresses
, 0));
1710 struct ifnet_addr_list
{
1711 SLIST_ENTRY(ifnet_addr_list
) ifal_le
;
1712 struct ifaddr
*ifal_ifa
;
1716 ifnet_get_address_list_family(ifnet_t interface
, ifaddr_t
**addresses
,
1719 return (ifnet_get_address_list_family_internal(interface
, addresses
,
1720 family
, 0, M_NOWAIT
, 0));
1724 ifnet_get_inuse_address_list(ifnet_t interface
, ifaddr_t
**addresses
)
1726 return (addresses
== NULL
? EINVAL
:
1727 ifnet_get_address_list_family_internal(interface
, addresses
,
1728 0, 0, M_NOWAIT
, 1));
1731 extern uint32_t tcp_find_anypcb_byaddr(struct ifaddr
*ifa
);
1733 extern uint32_t udp_find_anypcb_byaddr(struct ifaddr
*ifa
);
1735 __private_extern__ errno_t
1736 ifnet_get_address_list_family_internal(ifnet_t interface
, ifaddr_t
**addresses
,
1737 sa_family_t family
, int detached
, int how
, int return_inuse_addrs
)
1739 SLIST_HEAD(, ifnet_addr_list
) ifal_head
;
1740 struct ifnet_addr_list
*ifal
, *ifal_tmp
;
1747 SLIST_INIT(&ifal_head
);
1749 if (addresses
== NULL
) {
1757 * Interface has been detached, so skip the lookup
1758 * at ifnet_head and go directly to inner loop.
1768 ifnet_head_lock_shared();
1769 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
1770 if (interface
!= NULL
&& ifp
!= interface
)
1773 ifnet_lock_shared(ifp
);
1774 if (interface
== NULL
|| interface
== ifp
) {
1776 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1779 ifa
->ifa_addr
->sa_family
!= family
) {
1783 MALLOC(ifal
, struct ifnet_addr_list
*,
1784 sizeof (*ifal
), M_TEMP
, how
);
1787 ifnet_lock_done(ifp
);
1793 ifal
->ifal_ifa
= ifa
;
1794 IFA_ADDREF_LOCKED(ifa
);
1795 SLIST_INSERT_HEAD(&ifal_head
, ifal
, ifal_le
);
1800 ifnet_lock_done(ifp
);
1811 MALLOC(*addresses
, ifaddr_t
*, sizeof (ifaddr_t
) * (count
+ 1),
1813 if (*addresses
== NULL
) {
1817 bzero(*addresses
, sizeof (ifaddr_t
) * (count
+ 1));
1820 SLIST_FOREACH_SAFE(ifal
, &ifal_head
, ifal_le
, ifal_tmp
) {
1821 SLIST_REMOVE(&ifal_head
, ifal
, ifnet_addr_list
, ifal_le
);
1823 if (return_inuse_addrs
) {
1824 usecount
= tcp_find_anypcb_byaddr(ifal
->ifal_ifa
);
1825 usecount
+= udp_find_anypcb_byaddr(ifal
->ifal_ifa
);
1827 (*addresses
)[index
] = ifal
->ifal_ifa
;
1830 IFA_REMREF(ifal
->ifal_ifa
);
1833 (*addresses
)[--count
] = ifal
->ifal_ifa
;
1836 IFA_REMREF(ifal
->ifal_ifa
);
1841 VERIFY(err
== 0 || *addresses
== NULL
);
1842 if ((err
== 0) && (count
) && ((*addresses
)[0] == NULL
)) {
1843 VERIFY(return_inuse_addrs
== 1);
1844 FREE(*addresses
, M_TEMP
);
1851 ifnet_free_address_list(ifaddr_t
*addresses
)
1855 if (addresses
== NULL
)
1858 for (i
= 0; addresses
[i
] != NULL
; i
++)
1859 IFA_REMREF(addresses
[i
]);
1861 FREE(addresses
, M_TEMP
);
1865 ifnet_lladdr(ifnet_t interface
)
1870 if (interface
== NULL
)
1874 * if_lladdr points to the permanent link address of
1875 * the interface and it never gets deallocated; internal
1876 * code should simply use IF_LLADDR() for performance.
1878 ifa
= interface
->if_lladdr
;
1880 lladdr
= LLADDR(SDL((void *)ifa
->ifa_addr
));
1887 ifnet_llbroadcast_copy_bytes(ifnet_t interface
, void *addr
, size_t buffer_len
,
1890 if (interface
== NULL
|| addr
== NULL
|| out_len
== NULL
)
1893 *out_len
= interface
->if_broadcast
.length
;
1895 if (buffer_len
< interface
->if_broadcast
.length
)
1898 if (interface
->if_broadcast
.length
== 0)
1901 if (interface
->if_broadcast
.length
<=
1902 sizeof (interface
->if_broadcast
.u
.buffer
)) {
1903 bcopy(interface
->if_broadcast
.u
.buffer
, addr
,
1904 interface
->if_broadcast
.length
);
1906 bcopy(interface
->if_broadcast
.u
.ptr
, addr
,
1907 interface
->if_broadcast
.length
);
1914 ifnet_lladdr_copy_bytes_internal(ifnet_t interface
, void *lladdr
,
1915 size_t lladdr_len
, kauth_cred_t
*credp
)
1917 const u_int8_t
*bytes
;
1920 uint8_t sdlbuf
[SOCK_MAXADDRLEN
+ 1];
1924 * Make sure to accomodate the largest possible
1925 * size of SA(if_lladdr)->sa_len.
1927 _CASSERT(sizeof (sdlbuf
) == (SOCK_MAXADDRLEN
+ 1));
1929 if (interface
== NULL
|| lladdr
== NULL
)
1932 ifa
= interface
->if_lladdr
;
1934 bcopy(ifa
->ifa_addr
, &sdlbuf
, SDL(ifa
->ifa_addr
)->sdl_len
);
1937 bytes
= dlil_ifaddr_bytes(SDL(&sdlbuf
), &bytes_len
, credp
);
1938 if (bytes_len
!= lladdr_len
) {
1939 bzero(lladdr
, lladdr_len
);
1942 bcopy(bytes
, lladdr
, bytes_len
);
1949 ifnet_lladdr_copy_bytes(ifnet_t interface
, void *lladdr
, size_t length
)
1951 return (ifnet_lladdr_copy_bytes_internal(interface
, lladdr
, length
,
1956 ifnet_guarded_lladdr_copy_bytes(ifnet_t interface
, void *lladdr
, size_t length
)
1960 net_thread_marks_t marks
;
1962 kauth_cred_t
*credp
;
1967 marks
= net_thread_marks_push(NET_THREAD_CKREQ_LLADDR
);
1968 cred
= kauth_cred_proc_ref(current_proc());
1974 error
= ifnet_lladdr_copy_bytes_internal(interface
, lladdr
, length
,
1978 kauth_cred_unref(credp
);
1979 net_thread_marks_pop(marks
);
1986 ifnet_set_lladdr_internal(ifnet_t interface
, const void *lladdr
,
1987 size_t lladdr_len
, u_char new_type
, int apply_type
)
1992 if (interface
== NULL
)
1995 ifnet_head_lock_shared();
1996 ifnet_lock_exclusive(interface
);
1997 if (lladdr_len
!= 0 &&
1998 (lladdr_len
!= interface
->if_addrlen
|| lladdr
== 0)) {
1999 ifnet_lock_done(interface
);
2003 ifa
= ifnet_addrs
[interface
->if_index
- 1];
2005 struct sockaddr_dl
*sdl
;
2008 sdl
= (struct sockaddr_dl
*)(void *)ifa
->ifa_addr
;
2009 if (lladdr_len
!= 0) {
2010 bcopy(lladdr
, LLADDR(sdl
), lladdr_len
);
2012 bzero(LLADDR(sdl
), interface
->if_addrlen
);
2014 sdl
->sdl_alen
= lladdr_len
;
2017 sdl
->sdl_type
= new_type
;
2023 ifnet_lock_done(interface
);
2026 /* Generate a kernel event */
2028 intf_event_enqueue_nwk_wq_entry(interface
, NULL
,
2029 INTF_EVENT_CODE_LLADDR_UPDATE
);
2030 dlil_post_msg(interface
, KEV_DL_SUBCLASS
,
2031 KEV_DL_LINK_ADDRESS_CHANGED
, NULL
, 0);
2038 ifnet_set_lladdr(ifnet_t interface
, const void* lladdr
, size_t lladdr_len
)
2040 return (ifnet_set_lladdr_internal(interface
, lladdr
, lladdr_len
, 0, 0));
2044 ifnet_set_lladdr_and_type(ifnet_t interface
, const void* lladdr
,
2045 size_t lladdr_len
, u_char type
)
2047 return (ifnet_set_lladdr_internal(interface
, lladdr
,
2048 lladdr_len
, type
, 1));
2052 ifnet_add_multicast(ifnet_t interface
, const struct sockaddr
*maddr
,
2053 ifmultiaddr_t
*ifmap
)
2055 if (interface
== NULL
|| maddr
== NULL
)
2058 /* Don't let users screw up protocols' entries. */
2059 if (maddr
->sa_family
!= AF_UNSPEC
&& maddr
->sa_family
!= AF_LINK
)
2062 return (if_addmulti_anon(interface
, maddr
, ifmap
));
2066 ifnet_remove_multicast(ifmultiaddr_t ifma
)
2068 struct sockaddr
*maddr
;
2073 maddr
= ifma
->ifma_addr
;
2074 /* Don't let users screw up protocols' entries. */
2075 if (maddr
->sa_family
!= AF_UNSPEC
&& maddr
->sa_family
!= AF_LINK
)
2078 return (if_delmulti_anon(ifma
->ifma_ifp
, maddr
));
2082 ifnet_get_multicast_list(ifnet_t ifp
, ifmultiaddr_t
**addresses
)
2086 struct ifmultiaddr
*addr
;
2088 if (ifp
== NULL
|| addresses
== NULL
)
2091 ifnet_lock_shared(ifp
);
2092 LIST_FOREACH(addr
, &ifp
->if_multiaddrs
, ifma_link
) {
2096 MALLOC(*addresses
, ifmultiaddr_t
*, sizeof (ifmultiaddr_t
) * (cmax
+ 1),
2098 if (*addresses
== NULL
) {
2099 ifnet_lock_done(ifp
);
2103 LIST_FOREACH(addr
, &ifp
->if_multiaddrs
, ifma_link
) {
2104 if (count
+ 1 > cmax
)
2106 (*addresses
)[count
] = (ifmultiaddr_t
)addr
;
2107 ifmaddr_reference((*addresses
)[count
]);
2110 (*addresses
)[cmax
] = NULL
;
2111 ifnet_lock_done(ifp
);
2117 ifnet_free_multicast_list(ifmultiaddr_t
*addresses
)
2121 if (addresses
== NULL
)
2124 for (i
= 0; addresses
[i
] != NULL
; i
++)
2125 ifmaddr_release(addresses
[i
]);
2127 FREE(addresses
, M_TEMP
);
2131 ifnet_find_by_name(const char *ifname
, ifnet_t
*ifpp
)
2139 namelen
= strlen(ifname
);
2143 ifnet_head_lock_shared();
2144 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2146 struct sockaddr_dl
*ll_addr
;
2148 ifa
= ifnet_addrs
[ifp
->if_index
- 1];
2153 ll_addr
= (struct sockaddr_dl
*)(void *)ifa
->ifa_addr
;
2155 if (namelen
== ll_addr
->sdl_nlen
&& strncmp(ll_addr
->sdl_data
,
2156 ifname
, ll_addr
->sdl_nlen
) == 0) {
2159 ifnet_reference(*ifpp
);
2166 return ((ifp
== NULL
) ? ENXIO
: 0);
2170 ifnet_list_get(ifnet_family_t family
, ifnet_t
**list
, u_int32_t
*count
)
2172 return (ifnet_list_get_common(family
, FALSE
, list
, count
));
2175 __private_extern__ errno_t
2176 ifnet_list_get_all(ifnet_family_t family
, ifnet_t
**list
, u_int32_t
*count
)
2178 return (ifnet_list_get_common(family
, TRUE
, list
, count
));
2182 SLIST_ENTRY(ifnet_list
) ifl_le
;
2183 struct ifnet
*ifl_ifp
;
2187 ifnet_list_get_common(ifnet_family_t family
, boolean_t get_all
, ifnet_t
**list
,
2190 #pragma unused(get_all)
2191 SLIST_HEAD(, ifnet_list
) ifl_head
;
2192 struct ifnet_list
*ifl
, *ifl_tmp
;
2197 SLIST_INIT(&ifl_head
);
2199 if (list
== NULL
|| count
== NULL
) {
2206 ifnet_head_lock_shared();
2207 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2208 if (family
== IFNET_FAMILY_ANY
|| ifp
->if_family
== family
) {
2209 MALLOC(ifl
, struct ifnet_list
*, sizeof (*ifl
),
2217 ifnet_reference(ifp
);
2218 SLIST_INSERT_HEAD(&ifl_head
, ifl
, ifl_le
);
2229 MALLOC(*list
, ifnet_t
*, sizeof (ifnet_t
) * (cnt
+ 1),
2231 if (*list
== NULL
) {
2235 bzero(*list
, sizeof (ifnet_t
) * (cnt
+ 1));
2239 SLIST_FOREACH_SAFE(ifl
, &ifl_head
, ifl_le
, ifl_tmp
) {
2240 SLIST_REMOVE(&ifl_head
, ifl
, ifnet_list
, ifl_le
);
2242 (*list
)[--cnt
] = ifl
->ifl_ifp
;
2244 ifnet_release(ifl
->ifl_ifp
);
2252 ifnet_list_free(ifnet_t
*interfaces
)
2256 if (interfaces
== NULL
)
2259 for (i
= 0; interfaces
[i
]; i
++)
2260 ifnet_release(interfaces
[i
]);
2262 FREE(interfaces
, M_TEMP
);
2265 /*************************************************************************/
2266 /* ifaddr_t accessors */
2267 /*************************************************************************/
2270 ifaddr_reference(ifaddr_t ifa
)
2280 ifaddr_release(ifaddr_t ifa
)
2290 ifaddr_address_family(ifaddr_t ifa
)
2292 sa_family_t family
= 0;
2296 if (ifa
->ifa_addr
!= NULL
)
2297 family
= ifa
->ifa_addr
->sa_family
;
2304 ifaddr_address(ifaddr_t ifa
, struct sockaddr
*out_addr
, u_int32_t addr_size
)
2308 if (ifa
== NULL
|| out_addr
== NULL
)
2312 if (ifa
->ifa_addr
== NULL
) {
2317 copylen
= (addr_size
>= ifa
->ifa_addr
->sa_len
) ?
2318 ifa
->ifa_addr
->sa_len
: addr_size
;
2319 bcopy(ifa
->ifa_addr
, out_addr
, copylen
);
2321 if (ifa
->ifa_addr
->sa_len
> addr_size
) {
2331 ifaddr_dstaddress(ifaddr_t ifa
, struct sockaddr
*out_addr
, u_int32_t addr_size
)
2335 if (ifa
== NULL
|| out_addr
== NULL
)
2339 if (ifa
->ifa_dstaddr
== NULL
) {
2344 copylen
= (addr_size
>= ifa
->ifa_dstaddr
->sa_len
) ?
2345 ifa
->ifa_dstaddr
->sa_len
: addr_size
;
2346 bcopy(ifa
->ifa_dstaddr
, out_addr
, copylen
);
2348 if (ifa
->ifa_dstaddr
->sa_len
> addr_size
) {
2358 ifaddr_netmask(ifaddr_t ifa
, struct sockaddr
*out_addr
, u_int32_t addr_size
)
2362 if (ifa
== NULL
|| out_addr
== NULL
)
2366 if (ifa
->ifa_netmask
== NULL
) {
2371 copylen
= addr_size
>= ifa
->ifa_netmask
->sa_len
?
2372 ifa
->ifa_netmask
->sa_len
: addr_size
;
2373 bcopy(ifa
->ifa_netmask
, out_addr
, copylen
);
2375 if (ifa
->ifa_netmask
->sa_len
> addr_size
) {
2385 ifaddr_ifnet(ifaddr_t ifa
)
2392 /* ifa_ifp is set once at creation time; it is never changed */
2399 ifaddr_withaddr(const struct sockaddr
*address
)
2401 if (address
== NULL
)
2404 return (ifa_ifwithaddr(address
));
2408 ifaddr_withdstaddr(const struct sockaddr
*address
)
2410 if (address
== NULL
)
2413 return (ifa_ifwithdstaddr(address
));
2417 ifaddr_withnet(const struct sockaddr
*net
)
2422 return (ifa_ifwithnet(net
));
2426 ifaddr_withroute(int flags
, const struct sockaddr
*destination
,
2427 const struct sockaddr
*gateway
)
2429 if (destination
== NULL
|| gateway
== NULL
)
2432 return (ifa_ifwithroute(flags
, destination
, gateway
));
2436 ifaddr_findbestforaddr(const struct sockaddr
*addr
, ifnet_t interface
)
2438 if (addr
== NULL
|| interface
== NULL
)
2441 return (ifaof_ifpforaddr(addr
, interface
));
2445 ifmaddr_reference(ifmultiaddr_t ifmaddr
)
2447 if (ifmaddr
== NULL
)
2450 IFMA_ADDREF(ifmaddr
);
2455 ifmaddr_release(ifmultiaddr_t ifmaddr
)
2457 if (ifmaddr
== NULL
)
2460 IFMA_REMREF(ifmaddr
);
2465 ifmaddr_address(ifmultiaddr_t ifma
, struct sockaddr
*out_addr
,
2466 u_int32_t addr_size
)
2470 if (ifma
== NULL
|| out_addr
== NULL
)
2474 if (ifma
->ifma_addr
== NULL
) {
2479 copylen
= (addr_size
>= ifma
->ifma_addr
->sa_len
?
2480 ifma
->ifma_addr
->sa_len
: addr_size
);
2481 bcopy(ifma
->ifma_addr
, out_addr
, copylen
);
2483 if (ifma
->ifma_addr
->sa_len
> addr_size
) {
2492 ifmaddr_lladdress(ifmultiaddr_t ifma
, struct sockaddr
*out_addr
,
2493 u_int32_t addr_size
)
2495 struct ifmultiaddr
*ifma_ll
;
2497 if (ifma
== NULL
|| out_addr
== NULL
)
2499 if ((ifma_ll
= ifma
->ifma_ll
) == NULL
)
2502 return (ifmaddr_address(ifma_ll
, out_addr
, addr_size
));
2506 ifmaddr_ifnet(ifmultiaddr_t ifma
)
2508 return ((ifma
== NULL
) ? NULL
: ifma
->ifma_ifp
);
2511 /**************************************************************************/
2512 /* interface cloner */
2513 /**************************************************************************/
2516 ifnet_clone_attach(struct ifnet_clone_params
*cloner_params
,
2517 if_clone_t
*ifcloner
)
2520 struct if_clone
*ifc
= NULL
;
2523 if (cloner_params
== NULL
|| ifcloner
== NULL
||
2524 cloner_params
->ifc_name
== NULL
||
2525 cloner_params
->ifc_create
== NULL
||
2526 cloner_params
->ifc_destroy
== NULL
||
2527 (namelen
= strlen(cloner_params
->ifc_name
)) >= IFNAMSIZ
) {
2532 if (if_clone_lookup(cloner_params
->ifc_name
, NULL
) != NULL
) {
2533 printf("%s: already a cloner for %s\n", __func__
,
2534 cloner_params
->ifc_name
);
2539 /* Make room for name string */
2540 ifc
= _MALLOC(sizeof (struct if_clone
) + IFNAMSIZ
+ 1, M_CLONE
,
2543 printf("%s: _MALLOC failed\n", __func__
);
2547 strlcpy((char *)(ifc
+ 1), cloner_params
->ifc_name
, IFNAMSIZ
+ 1);
2548 ifc
->ifc_name
= (char *)(ifc
+ 1);
2549 ifc
->ifc_namelen
= namelen
;
2550 ifc
->ifc_maxunit
= IF_MAXUNIT
;
2551 ifc
->ifc_create
= cloner_params
->ifc_create
;
2552 ifc
->ifc_destroy
= cloner_params
->ifc_destroy
;
2554 error
= if_clone_attach(ifc
);
2556 printf("%s: if_clone_attach failed %d\n", __func__
, error
);
2569 ifnet_clone_detach(if_clone_t ifcloner
)
2572 struct if_clone
*ifc
= ifcloner
;
2574 if (ifc
== NULL
|| ifc
->ifc_name
== NULL
)
2577 if ((if_clone_lookup(ifc
->ifc_name
, NULL
)) == NULL
) {
2578 printf("%s: no cloner for %s\n", __func__
, ifc
->ifc_name
);
2583 if_clone_detach(ifc
);
2591 /**************************************************************************/
2593 /**************************************************************************/
2596 ifnet_get_local_ports_extended(ifnet_t ifp
, protocol_family_t protocol
,
2597 u_int32_t flags
, u_int8_t
*bitfield
)
2600 u_int32_t inp_flags
= 0;
2602 if (bitfield
== NULL
)
2614 /* bit string is long enough to hold 16-bit port values */
2615 bzero(bitfield
, bitstr_size(65536));
2617 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_WILDCARDOK
) ?
2618 INPCB_GET_PORTS_USED_WILDCARDOK
: 0);
2619 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_NOWAKEUPOK
) ?
2620 INPCB_GET_PORTS_USED_NOWAKEUPOK
: 0);
2621 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_RECVANYIFONLY
) ?
2622 INPCB_GET_PORTS_USED_RECVANYIFONLY
: 0);
2623 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_EXTBGIDLEONLY
) ?
2624 INPCB_GET_PORTS_USED_EXTBGIDLEONLY
: 0);
2625 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_ACTIVEONLY
) ?
2626 INPCB_GET_PORTS_USED_ACTIVEONLY
: 0);
2629 ifindex
= (ifp
!= NULL
) ? ifp
->if_index
: 0;
2631 if (!(flags
& IFNET_GET_LOCAL_PORTS_TCPONLY
))
2632 udp_get_ports_used(ifindex
, protocol
, inp_flags
,
2635 if (!(flags
& IFNET_GET_LOCAL_PORTS_UDPONLY
))
2636 tcp_get_ports_used(ifindex
, protocol
, inp_flags
,
2642 ifnet_get_local_ports(ifnet_t ifp
, u_int8_t
*bitfield
)
2644 u_int32_t flags
= IFNET_GET_LOCAL_PORTS_WILDCARDOK
;
2645 return (ifnet_get_local_ports_extended(ifp
, PF_UNSPEC
, flags
,
2650 ifnet_notice_node_presence(ifnet_t ifp
, struct sockaddr
*sa
, int32_t rssi
,
2651 int lqm
, int npm
, u_int8_t srvinfo
[48])
2653 if (ifp
== NULL
|| sa
== NULL
|| srvinfo
== NULL
)
2655 if (sa
->sa_len
> sizeof(struct sockaddr_storage
))
2657 if (sa
->sa_family
!= AF_LINK
&& sa
->sa_family
!= AF_INET6
)
2660 dlil_node_present(ifp
, sa
, rssi
, lqm
, npm
, srvinfo
);
2665 ifnet_notice_node_absence(ifnet_t ifp
, struct sockaddr
*sa
)
2667 if (ifp
== NULL
|| sa
== NULL
)
2669 if (sa
->sa_len
> sizeof(struct sockaddr_storage
))
2671 if (sa
->sa_family
!= AF_LINK
&& sa
->sa_family
!= AF_INET6
)
2674 dlil_node_absent(ifp
, sa
);
2679 ifnet_notice_master_elected(ifnet_t ifp
)
2684 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_MASTER_ELECTED
, NULL
, 0);
2689 ifnet_tx_compl_status(ifnet_t ifp
, mbuf_t m
, tx_compl_val_t val
)
2693 m_do_tx_compl_callback(m
, ifp
);
2699 ifnet_tx_compl(ifnet_t ifp
, mbuf_t m
)
2701 m_do_tx_compl_callback(m
, ifp
);
2707 ifnet_report_issues(ifnet_t ifp
, u_int8_t modid
[IFNET_MODIDLEN
],
2708 u_int8_t info
[IFNET_MODARGLEN
])
2710 if (ifp
== NULL
|| modid
== NULL
)
2713 dlil_report_issues(ifp
, modid
, info
);
2718 ifnet_set_delegate(ifnet_t ifp
, ifnet_t delegated_ifp
)
2720 ifnet_t odifp
= NULL
;
2724 else if (!ifnet_is_attached(ifp
, 1))
2727 ifnet_lock_exclusive(ifp
);
2728 odifp
= ifp
->if_delegated
.ifp
;
2729 if (odifp
!= NULL
&& odifp
== delegated_ifp
) {
2730 /* delegate info is unchanged; nothing more to do */
2731 ifnet_lock_done(ifp
);
2734 // Test if this delegate interface would cause a loop
2735 ifnet_t delegate_check_ifp
= delegated_ifp
;
2736 while (delegate_check_ifp
!= NULL
) {
2737 if (delegate_check_ifp
== ifp
) {
2738 printf("%s: delegating to %s would cause a loop\n",
2739 ifp
->if_xname
, delegated_ifp
->if_xname
);
2740 ifnet_lock_done(ifp
);
2743 delegate_check_ifp
= delegate_check_ifp
->if_delegated
.ifp
;
2745 bzero(&ifp
->if_delegated
, sizeof (ifp
->if_delegated
));
2746 if (delegated_ifp
!= NULL
&& ifp
!= delegated_ifp
) {
2747 ifp
->if_delegated
.ifp
= delegated_ifp
;
2748 ifnet_reference(delegated_ifp
);
2749 ifp
->if_delegated
.type
= delegated_ifp
->if_type
;
2750 ifp
->if_delegated
.family
= delegated_ifp
->if_family
;
2751 ifp
->if_delegated
.subfamily
= delegated_ifp
->if_subfamily
;
2752 ifp
->if_delegated
.expensive
=
2753 delegated_ifp
->if_eflags
& IFEF_EXPENSIVE
? 1 : 0;
2756 * Propogate flags related to ECN from delegated interface
2758 ifp
->if_eflags
&= ~(IFEF_ECN_ENABLE
|IFEF_ECN_DISABLE
);
2759 ifp
->if_eflags
|= (delegated_ifp
->if_eflags
&
2760 (IFEF_ECN_ENABLE
|IFEF_ECN_DISABLE
));
2762 printf("%s: is now delegating %s (type 0x%x, family %u, "
2763 "sub-family %u)\n", ifp
->if_xname
, delegated_ifp
->if_xname
,
2764 delegated_ifp
->if_type
, delegated_ifp
->if_family
,
2765 delegated_ifp
->if_subfamily
);
2768 ifnet_lock_done(ifp
);
2770 if (odifp
!= NULL
) {
2771 if (odifp
!= delegated_ifp
) {
2772 printf("%s: is no longer delegating %s\n",
2773 ifp
->if_xname
, odifp
->if_xname
);
2775 ifnet_release(odifp
);
2778 /* Generate a kernel event */
2779 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IFDELEGATE_CHANGED
, NULL
, 0);
2782 /* Release the io ref count */
2783 ifnet_decr_iorefcnt(ifp
);
2789 ifnet_get_delegate(ifnet_t ifp
, ifnet_t
*pdelegated_ifp
)
2791 if (ifp
== NULL
|| pdelegated_ifp
== NULL
)
2793 else if (!ifnet_is_attached(ifp
, 1))
2796 ifnet_lock_shared(ifp
);
2797 if (ifp
->if_delegated
.ifp
!= NULL
)
2798 ifnet_reference(ifp
->if_delegated
.ifp
);
2799 *pdelegated_ifp
= ifp
->if_delegated
.ifp
;
2800 ifnet_lock_done(ifp
);
2802 /* Release the io ref count */
2803 ifnet_decr_iorefcnt(ifp
);
2809 ifnet_get_keepalive_offload_frames(ifnet_t ifp
,
2810 struct ifnet_keepalive_offload_frame
*frames_array
,
2811 u_int32_t frames_array_count
, size_t frame_data_offset
,
2812 u_int32_t
*used_frames_count
)
2816 if (frames_array
== NULL
|| used_frames_count
== NULL
||
2817 frame_data_offset
>= IFNET_KEEPALIVE_OFFLOAD_FRAME_DATA_SIZE
)
2820 /* frame_data_offset should be 32-bit aligned */
2821 if (P2ROUNDUP(frame_data_offset
, sizeof(u_int32_t
)) !=
2825 *used_frames_count
= 0;
2826 if (frames_array_count
== 0)
2829 for (i
= 0; i
< frames_array_count
; i
++) {
2830 struct ifnet_keepalive_offload_frame
*frame
= frames_array
+ i
;
2832 bzero(frame
, sizeof(struct ifnet_keepalive_offload_frame
));
2835 /* First collect IPSec related keep-alive frames */
2836 *used_frames_count
= key_fill_offload_frames_for_savs(ifp
,
2837 frames_array
, frames_array_count
, frame_data_offset
);
2839 /* If there is more room, collect other UDP keep-alive frames */
2840 if (*used_frames_count
< frames_array_count
)
2841 udp_fill_keepalive_offload_frames(ifp
, frames_array
,
2842 frames_array_count
, frame_data_offset
,
2845 /* If there is more room, collect other TCP keep-alive frames */
2846 if (*used_frames_count
< frames_array_count
)
2847 tcp_fill_keepalive_offload_frames(ifp
, frames_array
,
2848 frames_array_count
, frame_data_offset
,
2851 VERIFY(*used_frames_count
<= frames_array_count
);
2857 ifnet_link_status_report(ifnet_t ifp
, const void *buffer
,
2860 struct if_link_status
*ifsr
;
2863 if (ifp
== NULL
|| buffer
== NULL
|| buffer_len
== 0)
2866 ifnet_lock_shared(ifp
);
2869 * Make sure that the interface is attached but there is no need
2870 * to take a reference because this call is coming from the driver.
2872 if (!ifnet_is_attached(ifp
, 0)) {
2873 ifnet_lock_done(ifp
);
2877 lck_rw_lock_exclusive(&ifp
->if_link_status_lock
);
2880 * If this is the first status report then allocate memory
2883 if (ifp
->if_link_status
== NULL
) {
2884 MALLOC(ifp
->if_link_status
, struct if_link_status
*,
2885 sizeof(struct if_link_status
), M_TEMP
, M_ZERO
);
2886 if (ifp
->if_link_status
== NULL
) {
2892 ifsr
= __DECONST(struct if_link_status
*, buffer
);
2894 if (ifp
->if_type
== IFT_CELLULAR
) {
2895 struct if_cellular_status_v1
*if_cell_sr
, *new_cell_sr
;
2897 * Currently we have a single version -- if it does
2898 * not match, just return.
2900 if (ifsr
->ifsr_version
!=
2901 IF_CELLULAR_STATUS_REPORT_CURRENT_VERSION
) {
2906 if (ifsr
->ifsr_len
!= sizeof(*if_cell_sr
)) {
2912 &ifp
->if_link_status
->ifsr_u
.ifsr_cell
.if_cell_u
.if_status_v1
;
2913 new_cell_sr
= &ifsr
->ifsr_u
.ifsr_cell
.if_cell_u
.if_status_v1
;
2914 /* Check if we need to act on any new notifications */
2915 if ((new_cell_sr
->valid_bitmask
&
2916 IF_CELL_UL_MSS_RECOMMENDED_VALID
) &&
2917 new_cell_sr
->mss_recommended
!=
2918 if_cell_sr
->mss_recommended
) {
2919 atomic_bitset_32(&tcbinfo
.ipi_flags
,
2920 INPCBINFO_UPDATE_MSS
);
2921 inpcb_timer_sched(&tcbinfo
, INPCB_TIMER_FAST
);
2923 necp_update_all_clients();
2927 /* Finally copy the new information */
2928 ifp
->if_link_status
->ifsr_version
= ifsr
->ifsr_version
;
2929 ifp
->if_link_status
->ifsr_len
= ifsr
->ifsr_len
;
2930 if_cell_sr
->valid_bitmask
= 0;
2931 bcopy(new_cell_sr
, if_cell_sr
, sizeof(*if_cell_sr
));
2933 } else if (ifp
->if_subfamily
== IFNET_SUBFAMILY_WIFI
) {
2934 struct if_wifi_status_v1
*if_wifi_sr
, *new_wifi_sr
;
2937 if (ifsr
->ifsr_version
!=
2938 IF_WIFI_STATUS_REPORT_CURRENT_VERSION
) {
2943 if (ifsr
->ifsr_len
!= sizeof(*if_wifi_sr
)) {
2949 &ifp
->if_link_status
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
2951 &ifsr
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
2952 ifp
->if_link_status
->ifsr_version
= ifsr
->ifsr_version
;
2953 ifp
->if_link_status
->ifsr_len
= ifsr
->ifsr_len
;
2954 if_wifi_sr
->valid_bitmask
= 0;
2955 bcopy(new_wifi_sr
, if_wifi_sr
, sizeof(*if_wifi_sr
));
2958 * Update the bandwidth values if we got recent values
2959 * reported through the other KPI.
2961 if (!(new_wifi_sr
->valid_bitmask
&
2962 IF_WIFI_UL_MAX_BANDWIDTH_VALID
) &&
2963 ifp
->if_output_bw
.max_bw
> 0) {
2964 if_wifi_sr
->valid_bitmask
|=
2965 IF_WIFI_UL_MAX_BANDWIDTH_VALID
;
2966 if_wifi_sr
->ul_max_bandwidth
=
2967 ifp
->if_output_bw
.max_bw
;
2969 if (!(new_wifi_sr
->valid_bitmask
&
2970 IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID
) &&
2971 ifp
->if_output_bw
.eff_bw
> 0) {
2972 if_wifi_sr
->valid_bitmask
|=
2973 IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID
;
2974 if_wifi_sr
->ul_effective_bandwidth
=
2975 ifp
->if_output_bw
.eff_bw
;
2977 if (!(new_wifi_sr
->valid_bitmask
&
2978 IF_WIFI_DL_MAX_BANDWIDTH_VALID
) &&
2979 ifp
->if_input_bw
.max_bw
> 0) {
2980 if_wifi_sr
->valid_bitmask
|=
2981 IF_WIFI_DL_MAX_BANDWIDTH_VALID
;
2982 if_wifi_sr
->dl_max_bandwidth
=
2983 ifp
->if_input_bw
.max_bw
;
2985 if (!(new_wifi_sr
->valid_bitmask
&
2986 IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID
) &&
2987 ifp
->if_input_bw
.eff_bw
> 0) {
2988 if_wifi_sr
->valid_bitmask
|=
2989 IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID
;
2990 if_wifi_sr
->dl_effective_bandwidth
=
2991 ifp
->if_input_bw
.eff_bw
;
2996 lck_rw_done(&ifp
->if_link_status_lock
);
2997 ifnet_lock_done(ifp
);
3001 /*************************************************************************/
3002 /* Fastlane QoS Ca */
3003 /*************************************************************************/
3006 ifnet_set_fastlane_capable(ifnet_t interface
, boolean_t capable
)
3008 if (interface
== NULL
)
3011 if_set_qosmarking_mode(interface
,
3012 capable
? IFRTYPE_QOSMARKING_FASTLANE
: IFRTYPE_QOSMARKING_MODE_NONE
);
3018 ifnet_get_fastlane_capable(ifnet_t interface
, boolean_t
*capable
)
3020 if (interface
== NULL
|| capable
== NULL
)
3022 if (interface
->if_eflags
& IFEF_QOSMARKING_CAPABLE
)
3030 ifnet_get_unsent_bytes(ifnet_t interface
, int64_t *unsent_bytes
)
3034 if (interface
== NULL
|| unsent_bytes
== NULL
)
3037 bytes
= *unsent_bytes
= 0;
3039 if (!IF_FULLY_ATTACHED(interface
))
3042 bytes
= interface
->if_sndbyte_unsent
;
3044 if (interface
->if_eflags
& IFEF_TXSTART
)
3045 bytes
+= IFCQ_BYTES(&interface
->if_snd
);
3046 *unsent_bytes
= bytes
;
3052 ifnet_get_buffer_status(const ifnet_t ifp
, ifnet_buffer_status_t
*buf_status
)
3054 if (ifp
== NULL
|| buf_status
== NULL
)
3057 bzero(buf_status
, sizeof (*buf_status
));
3059 if (!IF_FULLY_ATTACHED(ifp
))
3062 if (ifp
->if_eflags
& IFEF_TXSTART
)
3063 buf_status
->buf_interface
= IFCQ_BYTES(&ifp
->if_snd
);
3065 buf_status
->buf_sndbuf
= ((buf_status
->buf_interface
!= 0) ||
3066 (ifp
->if_sndbyte_unsent
!= 0)) ? 1 : 0;
3072 ifnet_normalise_unsent_data(void)
3076 ifnet_head_lock_shared();
3077 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
3078 ifnet_lock_exclusive(ifp
);
3079 if (!IF_FULLY_ATTACHED(ifp
)) {
3080 ifnet_lock_done(ifp
);
3083 if (!(ifp
->if_eflags
& IFEF_TXSTART
)) {
3084 ifnet_lock_done(ifp
);
3088 if (ifp
->if_sndbyte_total
> 0 ||
3089 IFCQ_BYTES(&ifp
->if_snd
) > 0)
3090 ifp
->if_unsent_data_cnt
++;
3092 ifnet_lock_done(ifp
);