2 * Copyright (c) 2004-2015 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/route.h>
52 #include <libkern/libkern.h>
53 #include <libkern/OSAtomic.h>
54 #include <kern/locks.h>
55 #include <kern/clock.h>
56 #include <sys/sockio.h>
58 #include <sys/sysctl.h>
60 #include <netinet/ip_var.h>
61 #include <netinet/udp.h>
62 #include <netinet/udp_var.h>
63 #include <netinet/tcp.h>
64 #include <netinet/tcp_var.h>
65 #include <netinet/in_pcb.h>
67 #include <netinet/igmp_var.h>
70 #include <netinet6/mld6_var.h>
73 #include "net/net_str_id.h"
76 #include <sys/kauth.h>
77 #include <security/mac_framework.h>
80 #define TOUCHLASTCHANGE(__if_lastchange) { \
81 (__if_lastchange)->tv_sec = net_uptime(); \
82 (__if_lastchange)->tv_usec = 0; \
85 static errno_t
ifnet_defrouter_llreachinfo(ifnet_t
, int,
86 struct ifnet_llreach_info
*);
87 static void ifnet_kpi_free(ifnet_t
);
88 static errno_t
ifnet_list_get_common(ifnet_family_t
, boolean_t
, ifnet_t
**,
90 static errno_t
ifnet_set_lladdr_internal(ifnet_t
, const void *, size_t,
92 static errno_t
ifnet_awdl_check_eflags(ifnet_t
, u_int32_t
*, u_int32_t
*);
95 * Temporary work around until we have real reference counting
97 * We keep the bits about calling dlil_if_release (which should be
98 * called recycle) transparent by calling it from our if_free function
99 * pointer. We have to keep the client's original detach function
100 * somewhere so we can call it.
103 ifnet_kpi_free(ifnet_t ifp
)
105 ifnet_detached_func detach_func
= ifp
->if_kpi_storage
;
107 if (detach_func
!= NULL
)
110 if (ifp
->if_broadcast
.length
> sizeof (ifp
->if_broadcast
.u
.buffer
)) {
111 FREE(ifp
->if_broadcast
.u
.ptr
, M_IFADDR
);
112 ifp
->if_broadcast
.u
.ptr
= NULL
;
115 dlil_if_release(ifp
);
119 ifnet_allocate(const struct ifnet_init_params
*init
, ifnet_t
*interface
)
121 struct ifnet_init_eparams einit
;
123 bzero(&einit
, sizeof (einit
));
125 einit
.ver
= IFNET_INIT_CURRENT_VERSION
;
126 einit
.len
= sizeof (einit
);
127 einit
.flags
= IFNET_INIT_LEGACY
;
128 einit
.uniqueid
= init
->uniqueid
;
129 einit
.uniqueid_len
= init
->uniqueid_len
;
130 einit
.name
= init
->name
;
131 einit
.unit
= init
->unit
;
132 einit
.family
= init
->family
;
133 einit
.type
= init
->type
;
134 einit
.output
= init
->output
;
135 einit
.demux
= init
->demux
;
136 einit
.add_proto
= init
->add_proto
;
137 einit
.del_proto
= init
->del_proto
;
138 einit
.check_multi
= init
->check_multi
;
139 einit
.framer
= init
->framer
;
140 einit
.softc
= init
->softc
;
141 einit
.ioctl
= init
->ioctl
;
142 einit
.set_bpf_tap
= init
->set_bpf_tap
;
143 einit
.detach
= init
->detach
;
144 einit
.event
= init
->event
;
145 einit
.broadcast_addr
= init
->broadcast_addr
;
146 einit
.broadcast_len
= init
->broadcast_len
;
148 return (ifnet_allocate_extended(&einit
, interface
));
152 ifnet_allocate_extended(const struct ifnet_init_eparams
*einit0
,
155 struct ifnet_init_eparams einit
;
156 struct ifnet
*ifp
= NULL
;
161 if (einit
.ver
!= IFNET_INIT_CURRENT_VERSION
||
162 einit
.len
< sizeof (einit
))
165 if (einit
.family
== 0 || einit
.name
== NULL
||
166 strlen(einit
.name
) >= IFNAMSIZ
||
167 (einit
.type
& 0xFFFFFF00) != 0 || einit
.type
== 0)
170 if (einit
.flags
& IFNET_INIT_LEGACY
) {
171 if (einit
.output
== NULL
|| einit
.flags
!= IFNET_INIT_LEGACY
)
174 einit
.pre_enqueue
= NULL
;
176 einit
.output_ctl
= NULL
;
177 einit
.output_sched_model
= IFNET_SCHED_MODEL_NORMAL
;
178 einit
.input_poll
= NULL
;
179 einit
.input_ctl
= NULL
;
181 if (einit
.start
== NULL
)
185 if (einit
.output_sched_model
>= IFNET_SCHED_MODEL_MAX
)
188 if (einit
.flags
& IFNET_INIT_INPUT_POLL
) {
189 if (einit
.input_poll
== NULL
|| einit
.input_ctl
== NULL
)
192 einit
.input_poll
= NULL
;
193 einit
.input_ctl
= NULL
;
197 error
= dlil_if_acquire(einit
.family
, einit
.uniqueid
,
198 einit
.uniqueid_len
, &ifp
);
204 * Cast ifp->if_name as non const. dlil_if_acquire sets it up
205 * to point to storage of at least IFNAMSIZ bytes. It is safe
208 strlcpy(__DECONST(char *, ifp
->if_name
), einit
.name
, IFNAMSIZ
);
209 ifp
->if_type
= einit
.type
;
210 ifp
->if_family
= einit
.family
;
211 ifp
->if_subfamily
= einit
.subfamily
;
212 ifp
->if_unit
= einit
.unit
;
213 ifp
->if_output
= einit
.output
;
214 ifp
->if_pre_enqueue
= einit
.pre_enqueue
;
215 ifp
->if_start
= einit
.start
;
216 ifp
->if_output_ctl
= einit
.output_ctl
;
217 ifp
->if_output_sched_model
= einit
.output_sched_model
;
218 ifp
->if_output_bw
.eff_bw
= einit
.output_bw
;
219 ifp
->if_output_bw
.max_bw
= einit
.output_bw_max
;
220 ifp
->if_output_lt
.eff_lt
= einit
.output_lt
;
221 ifp
->if_output_lt
.max_lt
= einit
.output_lt_max
;
222 ifp
->if_input_poll
= einit
.input_poll
;
223 ifp
->if_input_ctl
= einit
.input_ctl
;
224 ifp
->if_input_bw
.eff_bw
= einit
.input_bw
;
225 ifp
->if_input_bw
.max_bw
= einit
.input_bw_max
;
226 ifp
->if_input_lt
.eff_lt
= einit
.input_lt
;
227 ifp
->if_input_lt
.max_lt
= einit
.input_lt_max
;
228 ifp
->if_demux
= einit
.demux
;
229 ifp
->if_add_proto
= einit
.add_proto
;
230 ifp
->if_del_proto
= einit
.del_proto
;
231 ifp
->if_check_multi
= einit
.check_multi
;
232 ifp
->if_framer_legacy
= einit
.framer
;
233 ifp
->if_framer
= einit
.framer_extended
;
234 ifp
->if_softc
= einit
.softc
;
235 ifp
->if_ioctl
= einit
.ioctl
;
236 ifp
->if_set_bpf_tap
= einit
.set_bpf_tap
;
237 ifp
->if_free
= ifnet_kpi_free
;
238 ifp
->if_event
= einit
.event
;
239 ifp
->if_kpi_storage
= einit
.detach
;
241 /* Initialize external name (name + unit) */
242 snprintf(__DECONST(char *, ifp
->if_xname
), IFXNAMSIZ
,
243 "%s%d", ifp
->if_name
, ifp
->if_unit
);
246 * On embedded, framer() is already in the extended form;
247 * we simply use it as is, unless the caller specifies
248 * framer_extended() which will then override it.
250 * On non-embedded, framer() has long been exposed as part
251 * of the public KPI, and therefore its signature must
252 * remain the same (without the pre- and postpend length
253 * parameters.) We special case ether_frameout, such that
254 * it gets mapped to its extended variant. All other cases
255 * utilize the stub routine which will simply return zeroes
256 * for those new parameters.
258 * Internally, DLIL will only use the extended callback
259 * variant which is represented by if_framer.
261 if (ifp
->if_framer
== NULL
&& ifp
->if_framer_legacy
!= NULL
) {
262 if (ifp
->if_framer_legacy
== ether_frameout
)
263 ifp
->if_framer
= ether_frameout_extended
;
265 ifp
->if_framer
= ifnet_framer_stub
;
268 if (ifp
->if_output_bw
.eff_bw
> ifp
->if_output_bw
.max_bw
)
269 ifp
->if_output_bw
.max_bw
= ifp
->if_output_bw
.eff_bw
;
270 else if (ifp
->if_output_bw
.eff_bw
== 0)
271 ifp
->if_output_bw
.eff_bw
= ifp
->if_output_bw
.max_bw
;
273 if (ifp
->if_input_bw
.eff_bw
> ifp
->if_input_bw
.max_bw
)
274 ifp
->if_input_bw
.max_bw
= ifp
->if_input_bw
.eff_bw
;
275 else if (ifp
->if_input_bw
.eff_bw
== 0)
276 ifp
->if_input_bw
.eff_bw
= ifp
->if_input_bw
.max_bw
;
278 if (ifp
->if_output_bw
.max_bw
== 0)
279 ifp
->if_output_bw
= ifp
->if_input_bw
;
280 else if (ifp
->if_input_bw
.max_bw
== 0)
281 ifp
->if_input_bw
= ifp
->if_output_bw
;
283 /* Pin if_baudrate to 32 bits */
284 br
= MAX(ifp
->if_output_bw
.max_bw
, ifp
->if_input_bw
.max_bw
);
286 ifp
->if_baudrate
= (br
> 0xFFFFFFFF) ? 0xFFFFFFFF : br
;
288 if (ifp
->if_output_lt
.eff_lt
> ifp
->if_output_lt
.max_lt
)
289 ifp
->if_output_lt
.max_lt
= ifp
->if_output_lt
.eff_lt
;
290 else if (ifp
->if_output_lt
.eff_lt
== 0)
291 ifp
->if_output_lt
.eff_lt
= ifp
->if_output_lt
.max_lt
;
293 if (ifp
->if_input_lt
.eff_lt
> ifp
->if_input_lt
.max_lt
)
294 ifp
->if_input_lt
.max_lt
= ifp
->if_input_lt
.eff_lt
;
295 else if (ifp
->if_input_lt
.eff_lt
== 0)
296 ifp
->if_input_lt
.eff_lt
= ifp
->if_input_lt
.max_lt
;
298 if (ifp
->if_output_lt
.max_lt
== 0)
299 ifp
->if_output_lt
= ifp
->if_input_lt
;
300 else if (ifp
->if_input_lt
.max_lt
== 0)
301 ifp
->if_input_lt
= ifp
->if_output_lt
;
303 if (ifp
->if_ioctl
== NULL
)
304 ifp
->if_ioctl
= ifp_if_ioctl
;
306 if (ifp
->if_start
!= NULL
) {
307 ifp
->if_eflags
|= IFEF_TXSTART
;
308 if (ifp
->if_pre_enqueue
== NULL
)
309 ifp
->if_pre_enqueue
= ifnet_enqueue
;
310 ifp
->if_output
= ifp
->if_pre_enqueue
;
312 ifp
->if_eflags
&= ~IFEF_TXSTART
;
315 if (ifp
->if_input_poll
!= NULL
)
316 ifp
->if_eflags
|= IFEF_RXPOLL
;
318 ifp
->if_eflags
&= ~IFEF_RXPOLL
;
320 VERIFY(!(einit
.flags
& IFNET_INIT_LEGACY
) ||
321 (ifp
->if_pre_enqueue
== NULL
&& ifp
->if_start
== NULL
&&
322 ifp
->if_output_ctl
== NULL
&& ifp
->if_input_poll
== NULL
&&
323 ifp
->if_input_ctl
== NULL
));
324 VERIFY(!(einit
.flags
& IFNET_INIT_INPUT_POLL
) ||
325 (ifp
->if_input_poll
!= NULL
&& ifp
->if_input_ctl
!= NULL
));
327 if (einit
.broadcast_len
&& einit
.broadcast_addr
) {
328 if (einit
.broadcast_len
>
329 sizeof (ifp
->if_broadcast
.u
.buffer
)) {
330 MALLOC(ifp
->if_broadcast
.u
.ptr
, u_char
*,
331 einit
.broadcast_len
, M_IFADDR
, M_NOWAIT
);
332 if (ifp
->if_broadcast
.u
.ptr
== NULL
) {
335 bcopy(einit
.broadcast_addr
,
336 ifp
->if_broadcast
.u
.ptr
,
337 einit
.broadcast_len
);
340 bcopy(einit
.broadcast_addr
,
341 ifp
->if_broadcast
.u
.buffer
,
342 einit
.broadcast_len
);
344 ifp
->if_broadcast
.length
= einit
.broadcast_len
;
346 bzero(&ifp
->if_broadcast
, sizeof (ifp
->if_broadcast
));
350 * output target queue delay is specified in millisecond
351 * convert it to nanoseconds
353 IFCQ_TARGET_QDELAY(&ifp
->if_snd
) =
354 einit
.output_target_qdelay
* 1000 * 1000;
355 IFCQ_MAXLEN(&ifp
->if_snd
) = einit
.sndq_maxlen
;
357 if (einit
.start_delay_qlen
> 0 &&
358 einit
.start_delay_timeout
> 0) {
359 ifp
->if_eflags
|= IFEF_ENQUEUE_MULTI
;
360 ifp
->if_start_delay_qlen
=
361 min(100, einit
.start_delay_qlen
);
362 ifp
->if_start_delay_timeout
=
363 min(20000, einit
.start_delay_timeout
);
364 /* convert timeout to nanoseconds */
365 ifp
->if_start_delay_timeout
*= 1000;
370 // temporary - this should be done in dlil_if_acquire
371 ifnet_reference(ifp
);
373 dlil_if_release(ifp
);
379 * Note: We should do something here to indicate that we haven't been
380 * attached yet. By doing so, we can catch the case in ifnet_release
381 * where the reference count reaches zero and call the recycle
382 * function. If the interface is attached, the interface will be
383 * recycled when the interface's if_free function is called. If the
384 * interface is never attached, the if_free function will never be
385 * called and the interface will never be recycled.
392 ifnet_reference(ifnet_t ifp
)
394 return (dlil_if_ref(ifp
));
398 ifnet_release(ifnet_t ifp
)
400 return (dlil_if_free(ifp
));
404 ifnet_interface_family_find(const char *module_string
,
405 ifnet_family_t
*family_id
)
407 if (module_string
== NULL
|| family_id
== NULL
)
410 return (net_str_id_find_internal(module_string
, family_id
,
415 ifnet_softc(ifnet_t interface
)
417 return ((interface
== NULL
) ? NULL
: interface
->if_softc
);
421 ifnet_name(ifnet_t interface
)
423 return ((interface
== NULL
) ? NULL
: interface
->if_name
);
427 ifnet_family(ifnet_t interface
)
429 return ((interface
== NULL
) ? 0 : interface
->if_family
);
433 ifnet_subfamily(ifnet_t interface
)
435 return ((interface
== NULL
) ? 0 : interface
->if_subfamily
);
439 ifnet_unit(ifnet_t interface
)
441 return ((interface
== NULL
) ? (u_int32_t
)0xffffffff :
442 (u_int32_t
)interface
->if_unit
);
446 ifnet_index(ifnet_t interface
)
448 return ((interface
== NULL
) ? (u_int32_t
)0xffffffff :
449 interface
->if_index
);
453 ifnet_set_flags(ifnet_t interface
, u_int16_t new_flags
, u_int16_t mask
)
457 if (interface
== NULL
)
460 ifnet_lock_exclusive(interface
);
462 /* If we are modifying the up/down state, call if_updown */
463 if ((mask
& IFF_UP
) != 0) {
464 if_updown(interface
, (new_flags
& IFF_UP
) == IFF_UP
);
467 old_flags
= interface
->if_flags
;
468 interface
->if_flags
= (new_flags
& mask
) | (interface
->if_flags
& ~mask
);
469 /* If we are modifying the multicast flag, set/unset the silent flag */
470 if ((old_flags
& IFF_MULTICAST
) !=
471 (interface
->if_flags
& IFF_MULTICAST
)) {
473 if (IGMP_IFINFO(interface
) != NULL
)
474 igmp_initsilent(interface
, IGMP_IFINFO(interface
));
477 if (MLD_IFINFO(interface
) != NULL
)
478 mld6_initsilent(interface
, MLD_IFINFO(interface
));
482 ifnet_lock_done(interface
);
488 ifnet_flags(ifnet_t interface
)
490 return ((interface
== NULL
) ? 0 : interface
->if_flags
);
494 * This routine ensures the following:
496 * If IFEF_AWDL is set by the caller, also set the rest of flags as
497 * defined in IFEF_AWDL_MASK.
499 * If IFEF_AWDL has been set on the interface and the caller attempts
500 * to clear one or more of the associated flags in IFEF_AWDL_MASK,
503 * If IFEF_AWDL_RESTRICTED is set by the caller, make sure IFEF_AWDL is set
506 * All other flags not associated with AWDL are not affected.
508 * See <net/if.h> for current definition of IFEF_AWDL_MASK.
511 ifnet_awdl_check_eflags(ifnet_t ifp
, u_int32_t
*new_eflags
, u_int32_t
*mask
)
515 ifnet_lock_assert(ifp
, IFNET_LCK_ASSERT_EXCLUSIVE
);
517 eflags
= (*new_eflags
& *mask
) | (ifp
->if_eflags
& ~(*mask
));
519 if (ifp
->if_eflags
& IFEF_AWDL
) {
520 if (eflags
& IFEF_AWDL
) {
521 if ((eflags
& IFEF_AWDL_MASK
) != IFEF_AWDL_MASK
)
524 *new_eflags
&= ~IFEF_AWDL_MASK
;
525 *mask
|= IFEF_AWDL_MASK
;
527 } else if (eflags
& IFEF_AWDL
) {
528 *new_eflags
|= IFEF_AWDL_MASK
;
529 *mask
|= IFEF_AWDL_MASK
;
530 } else if (eflags
& IFEF_AWDL_RESTRICTED
&&
531 !(ifp
->if_eflags
& IFEF_AWDL
))
538 ifnet_set_eflags(ifnet_t interface
, u_int32_t new_flags
, u_int32_t mask
)
541 struct kev_msg ev_msg
;
542 struct net_event_data ev_data
;
544 if (interface
== NULL
)
547 bzero(&ev_msg
, sizeof(ev_msg
));
548 ifnet_lock_exclusive(interface
);
550 * Sanity checks for IFEF_AWDL and its related flags.
552 if (ifnet_awdl_check_eflags(interface
, &new_flags
, &mask
) != 0) {
553 ifnet_lock_done(interface
);
556 oeflags
= interface
->if_eflags
;
557 interface
->if_eflags
=
558 (new_flags
& mask
) | (interface
->if_eflags
& ~mask
);
559 ifnet_lock_done(interface
);
560 if (interface
->if_eflags
& IFEF_AWDL_RESTRICTED
&&
561 !(oeflags
& IFEF_AWDL_RESTRICTED
)) {
562 ev_msg
.event_code
= KEV_DL_AWDL_RESTRICTED
;
564 * The interface is now restricted to applications that have
566 * The check for the entitlement will be done in the data
567 * path, so we don't have to do anything here.
569 } else if (oeflags
& IFEF_AWDL_RESTRICTED
&&
570 !(interface
->if_eflags
& IFEF_AWDL_RESTRICTED
))
571 ev_msg
.event_code
= KEV_DL_AWDL_UNRESTRICTED
;
573 * Notify configd so that it has a chance to perform better
574 * reachability detection.
576 if (ev_msg
.event_code
) {
577 bzero(&ev_data
, sizeof(ev_data
));
578 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
579 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
580 ev_msg
.kev_subclass
= KEV_DL_SUBCLASS
;
581 strlcpy(ev_data
.if_name
, interface
->if_name
, IFNAMSIZ
);
582 ev_data
.if_family
= interface
->if_family
;
583 ev_data
.if_unit
= interface
->if_unit
;
584 ev_msg
.dv
[0].data_length
= sizeof(struct net_event_data
);
585 ev_msg
.dv
[0].data_ptr
= &ev_data
;
586 ev_msg
.dv
[1].data_length
= 0;
587 kev_post_msg(&ev_msg
);
594 ifnet_eflags(ifnet_t interface
)
596 return ((interface
== NULL
) ? 0 : interface
->if_eflags
);
600 ifnet_set_idle_flags_locked(ifnet_t ifp
, u_int32_t new_flags
, u_int32_t mask
)
607 lck_mtx_assert(rnh_lock
, LCK_MTX_ASSERT_OWNED
);
608 ifnet_lock_assert(ifp
, IFNET_LCK_ASSERT_EXCLUSIVE
);
611 * If this is called prior to ifnet attach, the actual work will
612 * be done at attach time. Otherwise, if it is called after
613 * ifnet detach, then it is a no-op.
615 if (!ifnet_is_attached(ifp
, 0)) {
616 ifp
->if_idle_new_flags
= new_flags
;
617 ifp
->if_idle_new_flags_mask
= mask
;
620 ifp
->if_idle_new_flags
= ifp
->if_idle_new_flags_mask
= 0;
623 before
= ifp
->if_idle_flags
;
624 ifp
->if_idle_flags
= (new_flags
& mask
) | (ifp
->if_idle_flags
& ~mask
);
625 after
= ifp
->if_idle_flags
;
627 if ((after
- before
) < 0 && ifp
->if_idle_flags
== 0 &&
628 ifp
->if_want_aggressive_drain
!= 0) {
629 ifp
->if_want_aggressive_drain
= 0;
630 if (ifnet_aggressive_drainers
== 0)
631 panic("%s: ifp=%p negative aggdrain!", __func__
, ifp
);
632 } else if ((after
- before
) > 0 && ifp
->if_want_aggressive_drain
== 0) {
633 ifp
->if_want_aggressive_drain
++;
634 if (++ifnet_aggressive_drainers
== 0)
635 panic("%s: ifp=%p wraparound aggdrain!", __func__
, ifp
);
642 ifnet_set_idle_flags(ifnet_t ifp
, u_int32_t new_flags
, u_int32_t mask
)
646 lck_mtx_lock(rnh_lock
);
647 ifnet_lock_exclusive(ifp
);
648 err
= ifnet_set_idle_flags_locked(ifp
, new_flags
, mask
);
649 ifnet_lock_done(ifp
);
650 lck_mtx_unlock(rnh_lock
);
656 ifnet_idle_flags(ifnet_t ifp
)
658 return ((ifp
== NULL
) ? 0 : ifp
->if_idle_flags
);
662 ifnet_set_link_quality(ifnet_t ifp
, int quality
)
666 if (ifp
== NULL
|| quality
< IFNET_LQM_MIN
|| quality
> IFNET_LQM_MAX
) {
671 if (!ifnet_is_attached(ifp
, 0)) {
676 if_lqm_update(ifp
, quality
, 0);
683 ifnet_link_quality(ifnet_t ifp
)
688 return (IFNET_LQM_THRESH_OFF
);
690 ifnet_lock_shared(ifp
);
691 lqm
= ifp
->if_interface_state
.lqm_state
;
692 ifnet_lock_done(ifp
);
698 ifnet_set_interface_state(ifnet_t ifp
,
699 struct if_interface_state
*if_interface_state
)
703 if (ifp
== NULL
|| if_interface_state
== NULL
) {
708 if (!ifnet_is_attached(ifp
, 0)) {
713 if_state_update(ifp
, if_interface_state
);
720 ifnet_get_interface_state(ifnet_t ifp
,
721 struct if_interface_state
*if_interface_state
)
725 if (ifp
== NULL
|| if_interface_state
== NULL
) {
730 if (!ifnet_is_attached(ifp
, 0)) {
735 if_get_state(ifp
, if_interface_state
);
743 ifnet_defrouter_llreachinfo(ifnet_t ifp
, int af
,
744 struct ifnet_llreach_info
*iflri
)
746 if (ifp
== NULL
|| iflri
== NULL
)
749 VERIFY(af
== AF_INET
|| af
== AF_INET6
);
751 return (ifnet_llreach_get_defrouter(ifp
, af
, iflri
));
755 ifnet_inet_defrouter_llreachinfo(ifnet_t ifp
, struct ifnet_llreach_info
*iflri
)
757 return (ifnet_defrouter_llreachinfo(ifp
, AF_INET
, iflri
));
761 ifnet_inet6_defrouter_llreachinfo(ifnet_t ifp
, struct ifnet_llreach_info
*iflri
)
763 return (ifnet_defrouter_llreachinfo(ifp
, AF_INET6
, iflri
));
767 ifnet_set_capabilities_supported(ifnet_t ifp
, u_int32_t new_caps
,
776 ifnet_lock_exclusive(ifp
);
777 tmp
= (new_caps
& mask
) | (ifp
->if_capabilities
& ~mask
);
778 if ((tmp
& ~IFCAP_VALID
))
781 ifp
->if_capabilities
= tmp
;
782 ifnet_lock_done(ifp
);
788 ifnet_capabilities_supported(ifnet_t ifp
)
790 return ((ifp
== NULL
) ? 0 : ifp
->if_capabilities
);
795 ifnet_set_capabilities_enabled(ifnet_t ifp
, u_int32_t new_caps
,
800 struct kev_msg ev_msg
;
801 struct net_event_data ev_data
;
806 ifnet_lock_exclusive(ifp
);
807 tmp
= (new_caps
& mask
) | (ifp
->if_capenable
& ~mask
);
808 if ((tmp
& ~IFCAP_VALID
) || (tmp
& ~ifp
->if_capabilities
))
811 ifp
->if_capenable
= tmp
;
812 ifnet_lock_done(ifp
);
814 /* Notify application of the change */
815 bzero(&ev_data
, sizeof (struct net_event_data
));
816 bzero(&ev_msg
, sizeof (struct kev_msg
));
817 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
818 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
819 ev_msg
.kev_subclass
= KEV_DL_SUBCLASS
;
821 ev_msg
.event_code
= KEV_DL_IFCAP_CHANGED
;
822 strlcpy(&ev_data
.if_name
[0], ifp
->if_name
, IFNAMSIZ
);
823 ev_data
.if_family
= ifp
->if_family
;
824 ev_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
825 ev_msg
.dv
[0].data_length
= sizeof (struct net_event_data
);
826 ev_msg
.dv
[0].data_ptr
= &ev_data
;
827 ev_msg
.dv
[1].data_length
= 0;
828 kev_post_msg(&ev_msg
);
834 ifnet_capabilities_enabled(ifnet_t ifp
)
836 return ((ifp
== NULL
) ? 0 : ifp
->if_capenable
);
839 static const ifnet_offload_t offload_mask
=
840 (IFNET_CSUM_IP
| IFNET_CSUM_TCP
| IFNET_CSUM_UDP
| IFNET_CSUM_FRAGMENT
|
841 IFNET_IP_FRAGMENT
| IFNET_CSUM_TCPIPV6
| IFNET_CSUM_UDPIPV6
|
842 IFNET_IPV6_FRAGMENT
| IFNET_CSUM_PARTIAL
| IFNET_VLAN_TAGGING
|
843 IFNET_VLAN_MTU
| IFNET_MULTIPAGES
| IFNET_TSO_IPV4
| IFNET_TSO_IPV6
|
846 static const ifnet_offload_t any_offload_csum
=
847 (IFNET_CSUM_IP
| IFNET_CSUM_TCP
| IFNET_CSUM_UDP
| IFNET_CSUM_FRAGMENT
|
848 IFNET_CSUM_TCPIPV6
| IFNET_CSUM_UDPIPV6
| IFNET_CSUM_PARTIAL
);
851 ifnet_set_offload(ifnet_t interface
, ifnet_offload_t offload
)
853 u_int32_t ifcaps
= 0;
855 if (interface
== NULL
)
858 ifnet_lock_exclusive(interface
);
859 interface
->if_hwassist
= (offload
& offload_mask
);
861 * Hardware capable of partial checksum offload is
862 * flexible enough to handle any transports utilizing
863 * Internet Checksumming. Include those transports
864 * here, and leave the final decision to IP.
866 if (interface
->if_hwassist
& IFNET_CSUM_PARTIAL
) {
867 interface
->if_hwassist
|= (IFNET_CSUM_TCP
| IFNET_CSUM_UDP
|
868 IFNET_CSUM_TCPIPV6
| IFNET_CSUM_UDPIPV6
);
871 log(LOG_DEBUG
, "%s: set offload flags=%b\n",
873 interface
->if_hwassist
, IFNET_OFFLOADF_BITS
);
875 ifnet_lock_done(interface
);
877 if ((offload
& any_offload_csum
))
878 ifcaps
|= IFCAP_HWCSUM
;
879 if ((offload
& IFNET_TSO_IPV4
))
880 ifcaps
|= IFCAP_TSO4
;
881 if ((offload
& IFNET_TSO_IPV6
))
882 ifcaps
|= IFCAP_TSO6
;
883 if ((offload
& IFNET_VLAN_MTU
))
884 ifcaps
|= IFCAP_VLAN_MTU
;
885 if ((offload
& IFNET_VLAN_TAGGING
))
886 ifcaps
|= IFCAP_VLAN_HWTAGGING
;
887 if ((offload
& IFNET_TX_STATUS
))
888 ifcaps
|= IFNET_TX_STATUS
;
890 (void) ifnet_set_capabilities_supported(interface
, ifcaps
,
892 (void) ifnet_set_capabilities_enabled(interface
, ifcaps
,
900 ifnet_offload(ifnet_t interface
)
902 return ((interface
== NULL
) ?
903 0 : (interface
->if_hwassist
& offload_mask
));
907 ifnet_set_tso_mtu(ifnet_t interface
, sa_family_t family
, u_int32_t mtuLen
)
911 if (interface
== NULL
|| mtuLen
< interface
->if_mtu
)
916 if (interface
->if_hwassist
& IFNET_TSO_IPV4
)
917 interface
->if_tso_v4_mtu
= mtuLen
;
923 if (interface
->if_hwassist
& IFNET_TSO_IPV6
)
924 interface
->if_tso_v6_mtu
= mtuLen
;
930 error
= EPROTONOSUPPORT
;
938 ifnet_get_tso_mtu(ifnet_t interface
, sa_family_t family
, u_int32_t
*mtuLen
)
942 if (interface
== NULL
|| mtuLen
== NULL
)
947 if (interface
->if_hwassist
& IFNET_TSO_IPV4
)
948 *mtuLen
= interface
->if_tso_v4_mtu
;
954 if (interface
->if_hwassist
& IFNET_TSO_IPV6
)
955 *mtuLen
= interface
->if_tso_v6_mtu
;
961 error
= EPROTONOSUPPORT
;
969 ifnet_set_wake_flags(ifnet_t interface
, u_int32_t properties
, u_int32_t mask
)
971 struct kev_msg ev_msg
;
972 struct net_event_data ev_data
;
974 bzero(&ev_data
, sizeof (struct net_event_data
));
975 bzero(&ev_msg
, sizeof (struct kev_msg
));
977 if (interface
== NULL
)
980 /* Do not accept wacky values */
981 if ((properties
& mask
) & ~IF_WAKE_VALID_FLAGS
)
984 ifnet_lock_exclusive(interface
);
986 interface
->if_wake_properties
=
987 (properties
& mask
) | (interface
->if_wake_properties
& ~mask
);
989 ifnet_lock_done(interface
);
991 (void) ifnet_touch_lastchange(interface
);
993 /* Notify application of the change */
994 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
995 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
996 ev_msg
.kev_subclass
= KEV_DL_SUBCLASS
;
998 ev_msg
.event_code
= KEV_DL_WAKEFLAGS_CHANGED
;
999 strlcpy(&ev_data
.if_name
[0], interface
->if_name
, IFNAMSIZ
);
1000 ev_data
.if_family
= interface
->if_family
;
1001 ev_data
.if_unit
= (u_int32_t
)interface
->if_unit
;
1002 ev_msg
.dv
[0].data_length
= sizeof (struct net_event_data
);
1003 ev_msg
.dv
[0].data_ptr
= &ev_data
;
1004 ev_msg
.dv
[1].data_length
= 0;
1005 kev_post_msg(&ev_msg
);
1011 ifnet_get_wake_flags(ifnet_t interface
)
1013 return ((interface
== NULL
) ? 0 : interface
->if_wake_properties
);
1017 * Should MIB data store a copy?
1020 ifnet_set_link_mib_data(ifnet_t interface
, void *mibData
, u_int32_t mibLen
)
1022 if (interface
== NULL
)
1025 ifnet_lock_exclusive(interface
);
1026 interface
->if_linkmib
= (void*)mibData
;
1027 interface
->if_linkmiblen
= mibLen
;
1028 ifnet_lock_done(interface
);
1033 ifnet_get_link_mib_data(ifnet_t interface
, void *mibData
, u_int32_t
*mibLen
)
1037 if (interface
== NULL
)
1040 ifnet_lock_shared(interface
);
1041 if (*mibLen
< interface
->if_linkmiblen
)
1043 if (result
== 0 && interface
->if_linkmib
== NULL
)
1047 *mibLen
= interface
->if_linkmiblen
;
1048 bcopy(interface
->if_linkmib
, mibData
, *mibLen
);
1050 ifnet_lock_done(interface
);
1056 ifnet_get_link_mib_data_length(ifnet_t interface
)
1058 return ((interface
== NULL
) ? 0 : interface
->if_linkmiblen
);
1062 ifnet_output(ifnet_t interface
, protocol_family_t protocol_family
,
1063 mbuf_t m
, void *route
, const struct sockaddr
*dest
)
1065 if (interface
== NULL
|| protocol_family
== 0 || m
== NULL
) {
1070 return (dlil_output(interface
, protocol_family
, m
, route
, dest
, 0, NULL
));
1074 ifnet_output_raw(ifnet_t interface
, protocol_family_t protocol_family
, mbuf_t m
)
1076 if (interface
== NULL
|| m
== NULL
) {
1081 return (dlil_output(interface
, protocol_family
, m
, NULL
, NULL
, 1, NULL
));
1085 ifnet_set_mtu(ifnet_t interface
, u_int32_t mtu
)
1087 if (interface
== NULL
)
1090 interface
->if_mtu
= mtu
;
1095 ifnet_mtu(ifnet_t interface
)
1097 return ((interface
== NULL
) ? 0 : interface
->if_mtu
);
1101 ifnet_type(ifnet_t interface
)
1103 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_type
);
1107 ifnet_set_addrlen(ifnet_t interface
, u_char addrlen
)
1109 if (interface
== NULL
)
1112 interface
->if_data
.ifi_addrlen
= addrlen
;
1117 ifnet_addrlen(ifnet_t interface
)
1119 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_addrlen
);
1123 ifnet_set_hdrlen(ifnet_t interface
, u_char hdrlen
)
1125 if (interface
== NULL
)
1128 interface
->if_data
.ifi_hdrlen
= hdrlen
;
1133 ifnet_hdrlen(ifnet_t interface
)
1135 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_hdrlen
);
1139 ifnet_set_metric(ifnet_t interface
, u_int32_t metric
)
1141 if (interface
== NULL
)
1144 interface
->if_data
.ifi_metric
= metric
;
1149 ifnet_metric(ifnet_t interface
)
1151 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_metric
);
1155 ifnet_set_baudrate(struct ifnet
*ifp
, u_int64_t baudrate
)
1160 ifp
->if_output_bw
.max_bw
= ifp
->if_input_bw
.max_bw
=
1161 ifp
->if_output_bw
.eff_bw
= ifp
->if_input_bw
.eff_bw
= baudrate
;
1163 /* Pin if_baudrate to 32 bits until we can change the storage size */
1164 ifp
->if_baudrate
= (baudrate
> 0xFFFFFFFF) ? 0xFFFFFFFF : baudrate
;
1170 ifnet_baudrate(struct ifnet
*ifp
)
1172 return ((ifp
== NULL
) ? 0 : ifp
->if_baudrate
);
1176 ifnet_set_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*output_bw
,
1177 struct if_bandwidths
*input_bw
)
1182 /* set input values first (if any), as output values depend on them */
1183 if (input_bw
!= NULL
)
1184 (void) ifnet_set_input_bandwidths(ifp
, input_bw
);
1186 if (output_bw
!= NULL
)
1187 (void) ifnet_set_output_bandwidths(ifp
, output_bw
, FALSE
);
1193 ifnet_set_link_status_outbw(struct ifnet
*ifp
)
1195 struct if_wifi_status_v1
*sr
;
1196 sr
= &ifp
->if_link_status
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
1197 if (ifp
->if_output_bw
.eff_bw
!= 0) {
1198 sr
->valid_bitmask
|=
1199 IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID
;
1200 sr
->ul_effective_bandwidth
=
1201 ifp
->if_output_bw
.eff_bw
;
1203 if (ifp
->if_output_bw
.max_bw
!= 0) {
1204 sr
->valid_bitmask
|=
1205 IF_WIFI_UL_MAX_BANDWIDTH_VALID
;
1206 sr
->ul_max_bandwidth
=
1207 ifp
->if_output_bw
.max_bw
;
1212 ifnet_set_output_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*bw
,
1215 struct if_bandwidths old_bw
;
1216 struct ifclassq
*ifq
;
1219 VERIFY(ifp
!= NULL
&& bw
!= NULL
);
1224 IFCQ_LOCK_ASSERT_HELD(ifq
);
1226 old_bw
= ifp
->if_output_bw
;
1227 if (bw
->eff_bw
!= 0)
1228 ifp
->if_output_bw
.eff_bw
= bw
->eff_bw
;
1229 if (bw
->max_bw
!= 0)
1230 ifp
->if_output_bw
.max_bw
= bw
->max_bw
;
1231 if (ifp
->if_output_bw
.eff_bw
> ifp
->if_output_bw
.max_bw
)
1232 ifp
->if_output_bw
.max_bw
= ifp
->if_output_bw
.eff_bw
;
1233 else if (ifp
->if_output_bw
.eff_bw
== 0)
1234 ifp
->if_output_bw
.eff_bw
= ifp
->if_output_bw
.max_bw
;
1236 /* Pin if_baudrate to 32 bits */
1237 br
= MAX(ifp
->if_output_bw
.max_bw
, ifp
->if_input_bw
.max_bw
);
1239 ifp
->if_baudrate
= (br
> 0xFFFFFFFF) ? 0xFFFFFFFF : br
;
1241 /* Adjust queue parameters if needed */
1242 if (old_bw
.eff_bw
!= ifp
->if_output_bw
.eff_bw
||
1243 old_bw
.max_bw
!= ifp
->if_output_bw
.max_bw
)
1244 ifnet_update_sndq(ifq
, CLASSQ_EV_LINK_BANDWIDTH
);
1250 * If this is a Wifi interface, update the values in
1251 * if_link_status structure also.
1253 if (IFNET_IS_WIFI(ifp
) && ifp
->if_link_status
!= NULL
) {
1254 lck_rw_lock_exclusive(&ifp
->if_link_status_lock
);
1255 ifnet_set_link_status_outbw(ifp
);
1256 lck_rw_done(&ifp
->if_link_status_lock
);
1263 ifnet_set_link_status_inbw(struct ifnet
*ifp
)
1265 struct if_wifi_status_v1
*sr
;
1267 sr
= &ifp
->if_link_status
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
1268 if (ifp
->if_input_bw
.eff_bw
!= 0) {
1269 sr
->valid_bitmask
|=
1270 IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID
;
1271 sr
->dl_effective_bandwidth
=
1272 ifp
->if_input_bw
.eff_bw
;
1274 if (ifp
->if_input_bw
.max_bw
!= 0) {
1275 sr
->valid_bitmask
|=
1276 IF_WIFI_DL_MAX_BANDWIDTH_VALID
;
1277 sr
->dl_max_bandwidth
= ifp
->if_input_bw
.max_bw
;
1282 ifnet_set_input_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*bw
)
1284 struct if_bandwidths old_bw
;
1286 VERIFY(ifp
!= NULL
&& bw
!= NULL
);
1288 old_bw
= ifp
->if_input_bw
;
1289 if (bw
->eff_bw
!= 0)
1290 ifp
->if_input_bw
.eff_bw
= bw
->eff_bw
;
1291 if (bw
->max_bw
!= 0)
1292 ifp
->if_input_bw
.max_bw
= bw
->max_bw
;
1293 if (ifp
->if_input_bw
.eff_bw
> ifp
->if_input_bw
.max_bw
)
1294 ifp
->if_input_bw
.max_bw
= ifp
->if_input_bw
.eff_bw
;
1295 else if (ifp
->if_input_bw
.eff_bw
== 0)
1296 ifp
->if_input_bw
.eff_bw
= ifp
->if_input_bw
.max_bw
;
1298 if (IFNET_IS_WIFI(ifp
) && ifp
->if_link_status
!= NULL
) {
1299 lck_rw_lock_exclusive(&ifp
->if_link_status_lock
);
1300 ifnet_set_link_status_inbw(ifp
);
1301 lck_rw_done(&ifp
->if_link_status_lock
);
1304 if (old_bw
.eff_bw
!= ifp
->if_input_bw
.eff_bw
||
1305 old_bw
.max_bw
!= ifp
->if_input_bw
.max_bw
)
1306 ifnet_update_rcv(ifp
, CLASSQ_EV_LINK_BANDWIDTH
);
1312 ifnet_output_linkrate(struct ifnet
*ifp
)
1314 struct ifclassq
*ifq
= &ifp
->if_snd
;
1317 IFCQ_LOCK_ASSERT_HELD(ifq
);
1319 rate
= ifp
->if_output_bw
.eff_bw
;
1320 if (IFCQ_TBR_IS_ENABLED(ifq
)) {
1321 u_int64_t tbr_rate
= ifp
->if_snd
.ifcq_tbr
.tbr_rate_raw
;
1322 VERIFY(tbr_rate
> 0);
1323 rate
= MIN(rate
, ifp
->if_snd
.ifcq_tbr
.tbr_rate_raw
);
1330 ifnet_input_linkrate(struct ifnet
*ifp
)
1332 return (ifp
->if_input_bw
.eff_bw
);
1336 ifnet_bandwidths(struct ifnet
*ifp
, struct if_bandwidths
*output_bw
,
1337 struct if_bandwidths
*input_bw
)
1342 if (output_bw
!= NULL
)
1343 *output_bw
= ifp
->if_output_bw
;
1344 if (input_bw
!= NULL
)
1345 *input_bw
= ifp
->if_input_bw
;
1351 ifnet_set_latencies(struct ifnet
*ifp
, struct if_latencies
*output_lt
,
1352 struct if_latencies
*input_lt
)
1357 if (output_lt
!= NULL
)
1358 (void) ifnet_set_output_latencies(ifp
, output_lt
, FALSE
);
1360 if (input_lt
!= NULL
)
1361 (void) ifnet_set_input_latencies(ifp
, input_lt
);
1367 ifnet_set_output_latencies(struct ifnet
*ifp
, struct if_latencies
*lt
,
1370 struct if_latencies old_lt
;
1371 struct ifclassq
*ifq
;
1373 VERIFY(ifp
!= NULL
&& lt
!= NULL
);
1378 IFCQ_LOCK_ASSERT_HELD(ifq
);
1380 old_lt
= ifp
->if_output_lt
;
1381 if (lt
->eff_lt
!= 0)
1382 ifp
->if_output_lt
.eff_lt
= lt
->eff_lt
;
1383 if (lt
->max_lt
!= 0)
1384 ifp
->if_output_lt
.max_lt
= lt
->max_lt
;
1385 if (ifp
->if_output_lt
.eff_lt
> ifp
->if_output_lt
.max_lt
)
1386 ifp
->if_output_lt
.max_lt
= ifp
->if_output_lt
.eff_lt
;
1387 else if (ifp
->if_output_lt
.eff_lt
== 0)
1388 ifp
->if_output_lt
.eff_lt
= ifp
->if_output_lt
.max_lt
;
1390 /* Adjust queue parameters if needed */
1391 if (old_lt
.eff_lt
!= ifp
->if_output_lt
.eff_lt
||
1392 old_lt
.max_lt
!= ifp
->if_output_lt
.max_lt
)
1393 ifnet_update_sndq(ifq
, CLASSQ_EV_LINK_LATENCY
);
1402 ifnet_set_input_latencies(struct ifnet
*ifp
, struct if_latencies
*lt
)
1404 struct if_latencies old_lt
;
1406 VERIFY(ifp
!= NULL
&& lt
!= NULL
);
1408 old_lt
= ifp
->if_input_lt
;
1409 if (lt
->eff_lt
!= 0)
1410 ifp
->if_input_lt
.eff_lt
= lt
->eff_lt
;
1411 if (lt
->max_lt
!= 0)
1412 ifp
->if_input_lt
.max_lt
= lt
->max_lt
;
1413 if (ifp
->if_input_lt
.eff_lt
> ifp
->if_input_lt
.max_lt
)
1414 ifp
->if_input_lt
.max_lt
= ifp
->if_input_lt
.eff_lt
;
1415 else if (ifp
->if_input_lt
.eff_lt
== 0)
1416 ifp
->if_input_lt
.eff_lt
= ifp
->if_input_lt
.max_lt
;
1418 if (old_lt
.eff_lt
!= ifp
->if_input_lt
.eff_lt
||
1419 old_lt
.max_lt
!= ifp
->if_input_lt
.max_lt
)
1420 ifnet_update_rcv(ifp
, CLASSQ_EV_LINK_LATENCY
);
1426 ifnet_latencies(struct ifnet
*ifp
, struct if_latencies
*output_lt
,
1427 struct if_latencies
*input_lt
)
1432 if (output_lt
!= NULL
)
1433 *output_lt
= ifp
->if_output_lt
;
1434 if (input_lt
!= NULL
)
1435 *input_lt
= ifp
->if_input_lt
;
1441 ifnet_set_poll_params(struct ifnet
*ifp
, struct ifnet_poll_params
*p
)
1447 else if (!ifnet_is_attached(ifp
, 1))
1450 err
= dlil_rxpoll_set_params(ifp
, p
, FALSE
);
1452 /* Release the io ref count */
1453 ifnet_decr_iorefcnt(ifp
);
1459 ifnet_poll_params(struct ifnet
*ifp
, struct ifnet_poll_params
*p
)
1463 if (ifp
== NULL
|| p
== NULL
)
1465 else if (!ifnet_is_attached(ifp
, 1))
1468 err
= dlil_rxpoll_get_params(ifp
, p
);
1470 /* Release the io ref count */
1471 ifnet_decr_iorefcnt(ifp
);
1477 ifnet_stat_increment(struct ifnet
*ifp
,
1478 const struct ifnet_stat_increment_param
*s
)
1483 if (s
->packets_in
!= 0)
1484 atomic_add_64(&ifp
->if_data
.ifi_ipackets
, s
->packets_in
);
1485 if (s
->bytes_in
!= 0)
1486 atomic_add_64(&ifp
->if_data
.ifi_ibytes
, s
->bytes_in
);
1487 if (s
->errors_in
!= 0)
1488 atomic_add_64(&ifp
->if_data
.ifi_ierrors
, s
->errors_in
);
1490 if (s
->packets_out
!= 0)
1491 atomic_add_64(&ifp
->if_data
.ifi_opackets
, s
->packets_out
);
1492 if (s
->bytes_out
!= 0)
1493 atomic_add_64(&ifp
->if_data
.ifi_obytes
, s
->bytes_out
);
1494 if (s
->errors_out
!= 0)
1495 atomic_add_64(&ifp
->if_data
.ifi_oerrors
, s
->errors_out
);
1497 if (s
->collisions
!= 0)
1498 atomic_add_64(&ifp
->if_data
.ifi_collisions
, s
->collisions
);
1499 if (s
->dropped
!= 0)
1500 atomic_add_64(&ifp
->if_data
.ifi_iqdrops
, s
->dropped
);
1502 /* Touch the last change time. */
1503 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1509 ifnet_stat_increment_in(struct ifnet
*ifp
, u_int32_t packets_in
,
1510 u_int32_t bytes_in
, u_int32_t errors_in
)
1515 if (packets_in
!= 0)
1516 atomic_add_64(&ifp
->if_data
.ifi_ipackets
, packets_in
);
1518 atomic_add_64(&ifp
->if_data
.ifi_ibytes
, bytes_in
);
1520 atomic_add_64(&ifp
->if_data
.ifi_ierrors
, errors_in
);
1522 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1528 ifnet_stat_increment_out(struct ifnet
*ifp
, u_int32_t packets_out
,
1529 u_int32_t bytes_out
, u_int32_t errors_out
)
1534 if (packets_out
!= 0)
1535 atomic_add_64(&ifp
->if_data
.ifi_opackets
, packets_out
);
1537 atomic_add_64(&ifp
->if_data
.ifi_obytes
, bytes_out
);
1538 if (errors_out
!= 0)
1539 atomic_add_64(&ifp
->if_data
.ifi_oerrors
, errors_out
);
1541 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1547 ifnet_set_stat(struct ifnet
*ifp
, const struct ifnet_stats_param
*s
)
1552 atomic_set_64(&ifp
->if_data
.ifi_ipackets
, s
->packets_in
);
1553 atomic_set_64(&ifp
->if_data
.ifi_ibytes
, s
->bytes_in
);
1554 atomic_set_64(&ifp
->if_data
.ifi_imcasts
, s
->multicasts_in
);
1555 atomic_set_64(&ifp
->if_data
.ifi_ierrors
, s
->errors_in
);
1557 atomic_set_64(&ifp
->if_data
.ifi_opackets
, s
->packets_out
);
1558 atomic_set_64(&ifp
->if_data
.ifi_obytes
, s
->bytes_out
);
1559 atomic_set_64(&ifp
->if_data
.ifi_omcasts
, s
->multicasts_out
);
1560 atomic_set_64(&ifp
->if_data
.ifi_oerrors
, s
->errors_out
);
1562 atomic_set_64(&ifp
->if_data
.ifi_collisions
, s
->collisions
);
1563 atomic_set_64(&ifp
->if_data
.ifi_iqdrops
, s
->dropped
);
1564 atomic_set_64(&ifp
->if_data
.ifi_noproto
, s
->no_protocol
);
1566 /* Touch the last change time. */
1567 TOUCHLASTCHANGE(&ifp
->if_lastchange
);
1573 ifnet_stat(struct ifnet
*ifp
, struct ifnet_stats_param
*s
)
1578 atomic_get_64(s
->packets_in
, &ifp
->if_data
.ifi_ipackets
);
1579 atomic_get_64(s
->bytes_in
, &ifp
->if_data
.ifi_ibytes
);
1580 atomic_get_64(s
->multicasts_in
, &ifp
->if_data
.ifi_imcasts
);
1581 atomic_get_64(s
->errors_in
, &ifp
->if_data
.ifi_ierrors
);
1583 atomic_get_64(s
->packets_out
, &ifp
->if_data
.ifi_opackets
);
1584 atomic_get_64(s
->bytes_out
, &ifp
->if_data
.ifi_obytes
);
1585 atomic_get_64(s
->multicasts_out
, &ifp
->if_data
.ifi_omcasts
);
1586 atomic_get_64(s
->errors_out
, &ifp
->if_data
.ifi_oerrors
);
1588 atomic_get_64(s
->collisions
, &ifp
->if_data
.ifi_collisions
);
1589 atomic_get_64(s
->dropped
, &ifp
->if_data
.ifi_iqdrops
);
1590 atomic_get_64(s
->no_protocol
, &ifp
->if_data
.ifi_noproto
);
1596 ifnet_touch_lastchange(ifnet_t interface
)
1598 if (interface
== NULL
)
1601 TOUCHLASTCHANGE(&interface
->if_lastchange
);
1607 ifnet_lastchange(ifnet_t interface
, struct timeval
*last_change
)
1609 if (interface
== NULL
)
1612 *last_change
= interface
->if_data
.ifi_lastchange
;
1613 /* Crude conversion from uptime to calendar time */
1614 last_change
->tv_sec
+= boottime_sec();
1620 ifnet_get_address_list(ifnet_t interface
, ifaddr_t
**addresses
)
1622 return (addresses
== NULL
? EINVAL
:
1623 ifnet_get_address_list_family(interface
, addresses
, 0));
1626 struct ifnet_addr_list
{
1627 SLIST_ENTRY(ifnet_addr_list
) ifal_le
;
1628 struct ifaddr
*ifal_ifa
;
1632 ifnet_get_address_list_family(ifnet_t interface
, ifaddr_t
**addresses
,
1635 return (ifnet_get_address_list_family_internal(interface
, addresses
,
1636 family
, 0, M_NOWAIT
, 0));
1640 ifnet_get_inuse_address_list(ifnet_t interface
, ifaddr_t
**addresses
)
1642 return (addresses
== NULL
? EINVAL
:
1643 ifnet_get_address_list_family_internal(interface
, addresses
,
1644 0, 0, M_NOWAIT
, 1));
1647 extern uint32_t tcp_find_anypcb_byaddr(struct ifaddr
*ifa
);
1649 extern uint32_t udp_find_anypcb_byaddr(struct ifaddr
*ifa
);
1651 __private_extern__ errno_t
1652 ifnet_get_address_list_family_internal(ifnet_t interface
, ifaddr_t
**addresses
,
1653 sa_family_t family
, int detached
, int how
, int return_inuse_addrs
)
1655 SLIST_HEAD(, ifnet_addr_list
) ifal_head
;
1656 struct ifnet_addr_list
*ifal
, *ifal_tmp
;
1663 SLIST_INIT(&ifal_head
);
1665 if (addresses
== NULL
) {
1673 * Interface has been detached, so skip the lookup
1674 * at ifnet_head and go directly to inner loop.
1684 ifnet_head_lock_shared();
1685 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
1686 if (interface
!= NULL
&& ifp
!= interface
)
1689 ifnet_lock_shared(ifp
);
1690 if (interface
== NULL
|| interface
== ifp
) {
1692 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1695 ifa
->ifa_addr
->sa_family
!= family
) {
1699 MALLOC(ifal
, struct ifnet_addr_list
*,
1700 sizeof (*ifal
), M_TEMP
, how
);
1703 ifnet_lock_done(ifp
);
1709 ifal
->ifal_ifa
= ifa
;
1710 IFA_ADDREF_LOCKED(ifa
);
1711 SLIST_INSERT_HEAD(&ifal_head
, ifal
, ifal_le
);
1716 ifnet_lock_done(ifp
);
1727 MALLOC(*addresses
, ifaddr_t
*, sizeof (ifaddr_t
) * (count
+ 1),
1729 if (*addresses
== NULL
) {
1733 bzero(*addresses
, sizeof (ifaddr_t
) * (count
+ 1));
1736 SLIST_FOREACH_SAFE(ifal
, &ifal_head
, ifal_le
, ifal_tmp
) {
1737 SLIST_REMOVE(&ifal_head
, ifal
, ifnet_addr_list
, ifal_le
);
1739 if (return_inuse_addrs
) {
1740 usecount
= tcp_find_anypcb_byaddr(ifal
->ifal_ifa
);
1741 usecount
+= udp_find_anypcb_byaddr(ifal
->ifal_ifa
);
1743 (*addresses
)[index
] = ifal
->ifal_ifa
;
1746 IFA_REMREF(ifal
->ifal_ifa
);
1749 (*addresses
)[--count
] = ifal
->ifal_ifa
;
1752 IFA_REMREF(ifal
->ifal_ifa
);
1757 VERIFY(err
== 0 || *addresses
== NULL
);
1758 if ((err
== 0) && (count
) && ((*addresses
)[0] == NULL
)) {
1759 VERIFY(return_inuse_addrs
== 1);
1760 FREE(*addresses
, M_TEMP
);
1767 ifnet_free_address_list(ifaddr_t
*addresses
)
1771 if (addresses
== NULL
)
1774 for (i
= 0; addresses
[i
] != NULL
; i
++)
1775 IFA_REMREF(addresses
[i
]);
1777 FREE(addresses
, M_TEMP
);
1781 ifnet_lladdr(ifnet_t interface
)
1786 if (interface
== NULL
)
1790 * if_lladdr points to the permanent link address of
1791 * the interface and it never gets deallocated; internal
1792 * code should simply use IF_LLADDR() for performance.
1794 ifa
= interface
->if_lladdr
;
1796 lladdr
= LLADDR(SDL((void *)ifa
->ifa_addr
));
1803 ifnet_llbroadcast_copy_bytes(ifnet_t interface
, void *addr
, size_t buffer_len
,
1806 if (interface
== NULL
|| addr
== NULL
|| out_len
== NULL
)
1809 *out_len
= interface
->if_broadcast
.length
;
1811 if (buffer_len
< interface
->if_broadcast
.length
)
1814 if (interface
->if_broadcast
.length
== 0)
1817 if (interface
->if_broadcast
.length
<=
1818 sizeof (interface
->if_broadcast
.u
.buffer
)) {
1819 bcopy(interface
->if_broadcast
.u
.buffer
, addr
,
1820 interface
->if_broadcast
.length
);
1822 bcopy(interface
->if_broadcast
.u
.ptr
, addr
,
1823 interface
->if_broadcast
.length
);
1830 ifnet_lladdr_copy_bytes_internal(ifnet_t interface
, void *lladdr
,
1831 size_t lladdr_len
, kauth_cred_t
*credp
)
1833 const u_int8_t
*bytes
;
1836 uint8_t sdlbuf
[SOCK_MAXADDRLEN
+ 1];
1840 * Make sure to accomodate the largest possible
1841 * size of SA(if_lladdr)->sa_len.
1843 _CASSERT(sizeof (sdlbuf
) == (SOCK_MAXADDRLEN
+ 1));
1845 if (interface
== NULL
|| lladdr
== NULL
)
1848 ifa
= interface
->if_lladdr
;
1850 bcopy(ifa
->ifa_addr
, &sdlbuf
, SDL(ifa
->ifa_addr
)->sdl_len
);
1853 bytes
= dlil_ifaddr_bytes(SDL(&sdlbuf
), &bytes_len
, credp
);
1854 if (bytes_len
!= lladdr_len
) {
1855 bzero(lladdr
, lladdr_len
);
1858 bcopy(bytes
, lladdr
, bytes_len
);
1865 ifnet_lladdr_copy_bytes(ifnet_t interface
, void *lladdr
, size_t length
)
1867 return (ifnet_lladdr_copy_bytes_internal(interface
, lladdr
, length
,
1872 ifnet_guarded_lladdr_copy_bytes(ifnet_t interface
, void *lladdr
, size_t length
)
1876 net_thread_marks_t marks
;
1878 kauth_cred_t
*credp
;
1883 marks
= net_thread_marks_push(NET_THREAD_CKREQ_LLADDR
);
1884 cred
= kauth_cred_proc_ref(current_proc());
1890 error
= ifnet_lladdr_copy_bytes_internal(interface
, lladdr
, length
,
1894 kauth_cred_unref(credp
);
1895 net_thread_marks_pop(marks
);
1902 ifnet_set_lladdr_internal(ifnet_t interface
, const void *lladdr
,
1903 size_t lladdr_len
, u_char new_type
, int apply_type
)
1908 if (interface
== NULL
)
1911 ifnet_head_lock_shared();
1912 ifnet_lock_exclusive(interface
);
1913 if (lladdr_len
!= 0 &&
1914 (lladdr_len
!= interface
->if_addrlen
|| lladdr
== 0)) {
1915 ifnet_lock_done(interface
);
1919 ifa
= ifnet_addrs
[interface
->if_index
- 1];
1921 struct sockaddr_dl
*sdl
;
1924 sdl
= (struct sockaddr_dl
*)(void *)ifa
->ifa_addr
;
1925 if (lladdr_len
!= 0) {
1926 bcopy(lladdr
, LLADDR(sdl
), lladdr_len
);
1928 bzero(LLADDR(sdl
), interface
->if_addrlen
);
1930 sdl
->sdl_alen
= lladdr_len
;
1933 sdl
->sdl_type
= new_type
;
1939 ifnet_lock_done(interface
);
1942 /* Generate a kernel event */
1944 dlil_post_msg(interface
, KEV_DL_SUBCLASS
,
1945 KEV_DL_LINK_ADDRESS_CHANGED
, NULL
, 0);
1952 ifnet_set_lladdr(ifnet_t interface
, const void* lladdr
, size_t lladdr_len
)
1954 return (ifnet_set_lladdr_internal(interface
, lladdr
, lladdr_len
, 0, 0));
1958 ifnet_set_lladdr_and_type(ifnet_t interface
, const void* lladdr
,
1959 size_t lladdr_len
, u_char type
)
1961 return (ifnet_set_lladdr_internal(interface
, lladdr
,
1962 lladdr_len
, type
, 1));
1966 ifnet_add_multicast(ifnet_t interface
, const struct sockaddr
*maddr
,
1967 ifmultiaddr_t
*ifmap
)
1969 if (interface
== NULL
|| maddr
== NULL
)
1972 /* Don't let users screw up protocols' entries. */
1973 if (maddr
->sa_family
!= AF_UNSPEC
&& maddr
->sa_family
!= AF_LINK
)
1976 return (if_addmulti_anon(interface
, maddr
, ifmap
));
1980 ifnet_remove_multicast(ifmultiaddr_t ifma
)
1982 struct sockaddr
*maddr
;
1987 maddr
= ifma
->ifma_addr
;
1988 /* Don't let users screw up protocols' entries. */
1989 if (maddr
->sa_family
!= AF_UNSPEC
&& maddr
->sa_family
!= AF_LINK
)
1992 return (if_delmulti_anon(ifma
->ifma_ifp
, maddr
));
1996 ifnet_get_multicast_list(ifnet_t ifp
, ifmultiaddr_t
**addresses
)
2000 struct ifmultiaddr
*addr
;
2002 if (ifp
== NULL
|| addresses
== NULL
)
2005 ifnet_lock_shared(ifp
);
2006 LIST_FOREACH(addr
, &ifp
->if_multiaddrs
, ifma_link
) {
2010 MALLOC(*addresses
, ifmultiaddr_t
*, sizeof (ifmultiaddr_t
) * (cmax
+ 1),
2012 if (*addresses
== NULL
) {
2013 ifnet_lock_done(ifp
);
2017 LIST_FOREACH(addr
, &ifp
->if_multiaddrs
, ifma_link
) {
2018 if (count
+ 1 > cmax
)
2020 (*addresses
)[count
] = (ifmultiaddr_t
)addr
;
2021 ifmaddr_reference((*addresses
)[count
]);
2024 (*addresses
)[cmax
] = NULL
;
2025 ifnet_lock_done(ifp
);
2031 ifnet_free_multicast_list(ifmultiaddr_t
*addresses
)
2035 if (addresses
== NULL
)
2038 for (i
= 0; addresses
[i
] != NULL
; i
++)
2039 ifmaddr_release(addresses
[i
]);
2041 FREE(addresses
, M_TEMP
);
2045 ifnet_find_by_name(const char *ifname
, ifnet_t
*ifpp
)
2053 namelen
= strlen(ifname
);
2057 ifnet_head_lock_shared();
2058 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2060 struct sockaddr_dl
*ll_addr
;
2062 ifa
= ifnet_addrs
[ifp
->if_index
- 1];
2067 ll_addr
= (struct sockaddr_dl
*)(void *)ifa
->ifa_addr
;
2069 if (namelen
== ll_addr
->sdl_nlen
&& strncmp(ll_addr
->sdl_data
,
2070 ifname
, ll_addr
->sdl_nlen
) == 0) {
2073 ifnet_reference(*ifpp
);
2080 return ((ifp
== NULL
) ? ENXIO
: 0);
2084 ifnet_list_get(ifnet_family_t family
, ifnet_t
**list
, u_int32_t
*count
)
2086 return (ifnet_list_get_common(family
, FALSE
, list
, count
));
2089 __private_extern__ errno_t
2090 ifnet_list_get_all(ifnet_family_t family
, ifnet_t
**list
, u_int32_t
*count
)
2092 return (ifnet_list_get_common(family
, TRUE
, list
, count
));
2096 SLIST_ENTRY(ifnet_list
) ifl_le
;
2097 struct ifnet
*ifl_ifp
;
2101 ifnet_list_get_common(ifnet_family_t family
, boolean_t get_all
, ifnet_t
**list
,
2104 #pragma unused(get_all)
2105 SLIST_HEAD(, ifnet_list
) ifl_head
;
2106 struct ifnet_list
*ifl
, *ifl_tmp
;
2111 SLIST_INIT(&ifl_head
);
2113 if (list
== NULL
|| count
== NULL
) {
2120 ifnet_head_lock_shared();
2121 TAILQ_FOREACH(ifp
, &ifnet_head
, if_link
) {
2122 if (family
== IFNET_FAMILY_ANY
|| ifp
->if_family
== family
) {
2123 MALLOC(ifl
, struct ifnet_list
*, sizeof (*ifl
),
2131 ifnet_reference(ifp
);
2132 SLIST_INSERT_HEAD(&ifl_head
, ifl
, ifl_le
);
2143 MALLOC(*list
, ifnet_t
*, sizeof (ifnet_t
) * (cnt
+ 1),
2145 if (*list
== NULL
) {
2149 bzero(*list
, sizeof (ifnet_t
) * (cnt
+ 1));
2153 SLIST_FOREACH_SAFE(ifl
, &ifl_head
, ifl_le
, ifl_tmp
) {
2154 SLIST_REMOVE(&ifl_head
, ifl
, ifnet_list
, ifl_le
);
2156 (*list
)[--cnt
] = ifl
->ifl_ifp
;
2158 ifnet_release(ifl
->ifl_ifp
);
2166 ifnet_list_free(ifnet_t
*interfaces
)
2170 if (interfaces
== NULL
)
2173 for (i
= 0; interfaces
[i
]; i
++)
2174 ifnet_release(interfaces
[i
]);
2176 FREE(interfaces
, M_TEMP
);
2180 ifnet_transmit_burst_start(ifnet_t ifp
, mbuf_t pkt
)
2183 uint32_t orig_flags
;
2185 if (ifp
== NULL
|| !(pkt
->m_flags
& M_PKTHDR
))
2188 orig_flags
= OSBitOrAtomic(IF_MEASURED_BW_INPROGRESS
,
2190 if (orig_flags
& IF_MEASURED_BW_INPROGRESS
) {
2191 /* There is already a measurement in progress; skip this one */
2195 ifp
->if_bw
.start_seq
= pkt
->m_pkthdr
.pkt_bwseq
;
2196 ifp
->if_bw
.start_ts
= mach_absolute_time();
2197 #else /*!MEASURE_BW */
2198 #pragma unused(ifp, pkt)
2199 #endif /* !MEASURE_BW */
2203 ifnet_transmit_burst_end(ifnet_t ifp
, mbuf_t pkt
)
2206 uint64_t oseq
, ots
, bytes
, ts
, t
;
2209 if (ifp
== NULL
|| !(pkt
->m_flags
& M_PKTHDR
))
2212 flags
= OSBitOrAtomic(IF_MEASURED_BW_CALCULATION
, &ifp
->if_bw
.flags
);
2214 /* If a calculation is already in progress, just return */
2215 if (flags
& IF_MEASURED_BW_CALCULATION
)
2218 /* Check if a measurement was started at all */
2219 if (!(flags
& IF_MEASURED_BW_INPROGRESS
)) {
2221 * It is an error to call burst_end before burst_start.
2222 * Reset the calculation flag and return.
2227 oseq
= pkt
->m_pkthdr
.pkt_bwseq
;
2228 ots
= mach_absolute_time();
2230 if (ifp
->if_bw
.start_seq
> 0 && oseq
> ifp
->if_bw
.start_seq
) {
2231 ts
= ots
- ifp
->if_bw
.start_ts
;
2233 absolutetime_to_nanoseconds(ts
, &t
);
2234 bytes
= oseq
- ifp
->if_bw
.start_seq
;
2235 ifp
->if_bw
.bytes
= bytes
;
2241 /* Compute bandwidth as bytes/ms */
2242 bw
= (bytes
* NSEC_PER_MSEC
) / t
;
2244 if (ifp
->if_bw
.bw
> 0) {
2247 shft
= if_bw_smoothing_val
;
2248 /* Compute EWMA of bw */
2249 ifp
->if_bw
.bw
= (bw
+
2250 ((ifp
->if_bw
.bw
<< shft
) -
2251 ifp
->if_bw
.bw
)) >> shft
;
2257 ifp
->if_bw
.last_seq
= oseq
;
2258 ifp
->if_bw
.last_ts
= ots
;
2263 flags
= ~(IF_MEASURED_BW_INPROGRESS
| IF_MEASURED_BW_CALCULATION
);
2264 OSBitAndAtomic(flags
, &ifp
->if_bw
.flags
);
2265 #else /* !MEASURE_BW */
2266 #pragma unused(ifp, pkt)
2267 #endif /* !MEASURE_BW */
2270 /****************************************************************************/
2271 /* ifaddr_t accessors */
2272 /****************************************************************************/
2275 ifaddr_reference(ifaddr_t ifa
)
2285 ifaddr_release(ifaddr_t ifa
)
2295 ifaddr_address_family(ifaddr_t ifa
)
2297 sa_family_t family
= 0;
2301 if (ifa
->ifa_addr
!= NULL
)
2302 family
= ifa
->ifa_addr
->sa_family
;
2309 ifaddr_address(ifaddr_t ifa
, struct sockaddr
*out_addr
, u_int32_t addr_size
)
2313 if (ifa
== NULL
|| out_addr
== NULL
)
2317 if (ifa
->ifa_addr
== NULL
) {
2322 copylen
= (addr_size
>= ifa
->ifa_addr
->sa_len
) ?
2323 ifa
->ifa_addr
->sa_len
: addr_size
;
2324 bcopy(ifa
->ifa_addr
, out_addr
, copylen
);
2326 if (ifa
->ifa_addr
->sa_len
> addr_size
) {
2336 ifaddr_dstaddress(ifaddr_t ifa
, struct sockaddr
*out_addr
, u_int32_t addr_size
)
2340 if (ifa
== NULL
|| out_addr
== NULL
)
2344 if (ifa
->ifa_dstaddr
== NULL
) {
2349 copylen
= (addr_size
>= ifa
->ifa_dstaddr
->sa_len
) ?
2350 ifa
->ifa_dstaddr
->sa_len
: addr_size
;
2351 bcopy(ifa
->ifa_dstaddr
, out_addr
, copylen
);
2353 if (ifa
->ifa_dstaddr
->sa_len
> addr_size
) {
2363 ifaddr_netmask(ifaddr_t ifa
, struct sockaddr
*out_addr
, u_int32_t addr_size
)
2367 if (ifa
== NULL
|| out_addr
== NULL
)
2371 if (ifa
->ifa_netmask
== NULL
) {
2376 copylen
= addr_size
>= ifa
->ifa_netmask
->sa_len
?
2377 ifa
->ifa_netmask
->sa_len
: addr_size
;
2378 bcopy(ifa
->ifa_netmask
, out_addr
, copylen
);
2380 if (ifa
->ifa_netmask
->sa_len
> addr_size
) {
2390 ifaddr_ifnet(ifaddr_t ifa
)
2397 /* ifa_ifp is set once at creation time; it is never changed */
2404 ifaddr_withaddr(const struct sockaddr
*address
)
2406 if (address
== NULL
)
2409 return (ifa_ifwithaddr(address
));
2413 ifaddr_withdstaddr(const struct sockaddr
*address
)
2415 if (address
== NULL
)
2418 return (ifa_ifwithdstaddr(address
));
2422 ifaddr_withnet(const struct sockaddr
*net
)
2427 return (ifa_ifwithnet(net
));
2431 ifaddr_withroute(int flags
, const struct sockaddr
*destination
,
2432 const struct sockaddr
*gateway
)
2434 if (destination
== NULL
|| gateway
== NULL
)
2437 return (ifa_ifwithroute(flags
, destination
, gateway
));
2441 ifaddr_findbestforaddr(const struct sockaddr
*addr
, ifnet_t interface
)
2443 if (addr
== NULL
|| interface
== NULL
)
2446 return (ifaof_ifpforaddr(addr
, interface
));
2450 ifmaddr_reference(ifmultiaddr_t ifmaddr
)
2452 if (ifmaddr
== NULL
)
2455 IFMA_ADDREF(ifmaddr
);
2460 ifmaddr_release(ifmultiaddr_t ifmaddr
)
2462 if (ifmaddr
== NULL
)
2465 IFMA_REMREF(ifmaddr
);
2470 ifmaddr_address(ifmultiaddr_t ifma
, struct sockaddr
*out_addr
,
2471 u_int32_t addr_size
)
2475 if (ifma
== NULL
|| out_addr
== NULL
)
2479 if (ifma
->ifma_addr
== NULL
) {
2484 copylen
= (addr_size
>= ifma
->ifma_addr
->sa_len
?
2485 ifma
->ifma_addr
->sa_len
: addr_size
);
2486 bcopy(ifma
->ifma_addr
, out_addr
, copylen
);
2488 if (ifma
->ifma_addr
->sa_len
> addr_size
) {
2497 ifmaddr_lladdress(ifmultiaddr_t ifma
, struct sockaddr
*out_addr
,
2498 u_int32_t addr_size
)
2500 struct ifmultiaddr
*ifma_ll
;
2502 if (ifma
== NULL
|| out_addr
== NULL
)
2504 if ((ifma_ll
= ifma
->ifma_ll
) == NULL
)
2507 return (ifmaddr_address(ifma_ll
, out_addr
, addr_size
));
2511 ifmaddr_ifnet(ifmultiaddr_t ifma
)
2513 return ((ifma
== NULL
) ? NULL
: ifma
->ifma_ifp
);
2516 /******************************************************************************/
2517 /* interface cloner */
2518 /******************************************************************************/
2521 ifnet_clone_attach(struct ifnet_clone_params
*cloner_params
,
2522 if_clone_t
*ifcloner
)
2525 struct if_clone
*ifc
= NULL
;
2528 if (cloner_params
== NULL
|| ifcloner
== NULL
||
2529 cloner_params
->ifc_name
== NULL
||
2530 cloner_params
->ifc_create
== NULL
||
2531 cloner_params
->ifc_destroy
== NULL
||
2532 (namelen
= strlen(cloner_params
->ifc_name
)) >= IFNAMSIZ
) {
2537 if (if_clone_lookup(cloner_params
->ifc_name
, NULL
) != NULL
) {
2538 printf("%s: already a cloner for %s\n", __func__
,
2539 cloner_params
->ifc_name
);
2544 /* Make room for name string */
2545 ifc
= _MALLOC(sizeof (struct if_clone
) + IFNAMSIZ
+ 1, M_CLONE
,
2548 printf("%s: _MALLOC failed\n", __func__
);
2552 strlcpy((char *)(ifc
+ 1), cloner_params
->ifc_name
, IFNAMSIZ
+ 1);
2553 ifc
->ifc_name
= (char *)(ifc
+ 1);
2554 ifc
->ifc_namelen
= namelen
;
2555 ifc
->ifc_maxunit
= IF_MAXUNIT
;
2556 ifc
->ifc_create
= cloner_params
->ifc_create
;
2557 ifc
->ifc_destroy
= cloner_params
->ifc_destroy
;
2559 error
= if_clone_attach(ifc
);
2561 printf("%s: if_clone_attach failed %d\n", __func__
, error
);
2574 ifnet_clone_detach(if_clone_t ifcloner
)
2577 struct if_clone
*ifc
= ifcloner
;
2579 if (ifc
== NULL
|| ifc
->ifc_name
== NULL
)
2582 if ((if_clone_lookup(ifc
->ifc_name
, NULL
)) == NULL
) {
2583 printf("%s: no cloner for %s\n", __func__
, ifc
->ifc_name
);
2588 if_clone_detach(ifc
);
2596 /******************************************************************************/
2598 /******************************************************************************/
2601 ifnet_get_local_ports_extended(ifnet_t ifp
, protocol_family_t protocol
,
2602 u_int32_t flags
, u_int8_t
*bitfield
)
2605 u_int32_t inp_flags
= 0;
2607 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_WILDCARDOK
) ?
2608 INPCB_GET_PORTS_USED_WILDCARDOK
: 0);
2609 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_NOWAKEUPOK
) ?
2610 INPCB_GET_PORTS_USED_NOWAKEUPOK
: 0);
2611 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_RECVANYIFONLY
) ?
2612 INPCB_GET_PORTS_USED_RECVANYIFONLY
: 0);
2613 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_EXTBGIDLEONLY
) ?
2614 INPCB_GET_PORTS_USED_EXTBGIDLEONLY
: 0);
2615 inp_flags
|= ((flags
& IFNET_GET_LOCAL_PORTS_ACTIVEONLY
) ?
2616 INPCB_GET_PORTS_USED_ACTIVEONLY
: 0);
2618 if (bitfield
== NULL
)
2630 /* bit string is long enough to hold 16-bit port values */
2631 bzero(bitfield
, bitstr_size(65536));
2633 ifindex
= (ifp
!= NULL
) ? ifp
->if_index
: 0;
2635 if (!(flags
& IFNET_GET_LOCAL_PORTS_TCPONLY
))
2636 udp_get_ports_used(ifindex
, protocol
, inp_flags
, bitfield
);
2638 if (!(flags
& IFNET_GET_LOCAL_PORTS_UDPONLY
))
2639 tcp_get_ports_used(ifindex
, protocol
, inp_flags
, bitfield
);
2645 ifnet_get_local_ports(ifnet_t ifp
, u_int8_t
*bitfield
)
2647 u_int32_t flags
= IFNET_GET_LOCAL_PORTS_WILDCARDOK
;
2648 return (ifnet_get_local_ports_extended(ifp
, PF_UNSPEC
, flags
,
2653 ifnet_notice_node_presence(ifnet_t ifp
, struct sockaddr
* sa
, int32_t rssi
,
2654 int lqm
, int npm
, u_int8_t srvinfo
[48])
2656 if (ifp
== NULL
|| sa
== NULL
|| srvinfo
== NULL
)
2658 if (sa
->sa_len
> sizeof(struct sockaddr_storage
))
2660 if (sa
->sa_family
!= AF_LINK
&& sa
->sa_family
!= AF_INET6
)
2663 dlil_node_present(ifp
, sa
, rssi
, lqm
, npm
, srvinfo
);
2668 ifnet_notice_node_absence(ifnet_t ifp
, struct sockaddr
* sa
)
2670 if (ifp
== NULL
|| sa
== NULL
)
2672 if (sa
->sa_len
> sizeof(struct sockaddr_storage
))
2674 if (sa
->sa_family
!= AF_LINK
&& sa
->sa_family
!= AF_INET6
)
2677 dlil_node_absent(ifp
, sa
);
2682 ifnet_notice_master_elected(ifnet_t ifp
)
2687 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_MASTER_ELECTED
, NULL
, 0);
2692 ifnet_tx_compl_status(ifnet_t ifp
, mbuf_t m
, tx_compl_val_t val
)
2694 #pragma unused(ifp, m, val)
2695 /* Dummy function to be implemented XXX */
2700 ifnet_report_issues(ifnet_t ifp
, u_int8_t modid
[IFNET_MODIDLEN
],
2701 u_int8_t info
[IFNET_MODARGLEN
])
2703 if (ifp
== NULL
|| modid
== NULL
)
2706 dlil_report_issues(ifp
, modid
, info
);
2711 ifnet_set_delegate(ifnet_t ifp
, ifnet_t delegated_ifp
)
2713 ifnet_t odifp
= NULL
;
2717 else if (!ifnet_is_attached(ifp
, 1))
2720 ifnet_lock_exclusive(ifp
);
2721 odifp
= ifp
->if_delegated
.ifp
;
2722 if (odifp
!= NULL
&& odifp
== delegated_ifp
) {
2723 /* delegate info is unchanged; nothing more to do */
2724 ifnet_lock_done(ifp
);
2727 bzero(&ifp
->if_delegated
, sizeof (ifp
->if_delegated
));
2728 if (delegated_ifp
!= NULL
&& ifp
!= delegated_ifp
) {
2729 ifp
->if_delegated
.ifp
= delegated_ifp
;
2730 ifnet_reference(delegated_ifp
);
2731 ifp
->if_delegated
.type
= delegated_ifp
->if_type
;
2732 ifp
->if_delegated
.family
= delegated_ifp
->if_family
;
2733 ifp
->if_delegated
.subfamily
= delegated_ifp
->if_subfamily
;
2734 ifp
->if_delegated
.expensive
=
2735 delegated_ifp
->if_eflags
& IFEF_EXPENSIVE
? 1 : 0;
2738 * Propogate flags related to ECN from delegated interface
2740 ifp
->if_eflags
&= ~(IFEF_ECN_ENABLE
|IFEF_ECN_DISABLE
);
2741 ifp
->if_eflags
|= (delegated_ifp
->if_eflags
&
2742 (IFEF_ECN_ENABLE
|IFEF_ECN_DISABLE
));
2744 printf("%s: is now delegating %s (type 0x%x, family %u, "
2745 "sub-family %u)\n", ifp
->if_xname
, delegated_ifp
->if_xname
,
2746 delegated_ifp
->if_type
, delegated_ifp
->if_family
,
2747 delegated_ifp
->if_subfamily
);
2750 ifnet_lock_done(ifp
);
2752 if (odifp
!= NULL
) {
2753 if (odifp
!= delegated_ifp
) {
2754 printf("%s: is no longer delegating %s\n",
2755 ifp
->if_xname
, odifp
->if_xname
);
2757 ifnet_release(odifp
);
2760 /* Generate a kernel event */
2761 dlil_post_msg(ifp
, KEV_DL_SUBCLASS
, KEV_DL_IFDELEGATE_CHANGED
, NULL
, 0);
2764 /* Release the io ref count */
2765 ifnet_decr_iorefcnt(ifp
);
2771 ifnet_get_delegate(ifnet_t ifp
, ifnet_t
*pdelegated_ifp
)
2773 if (ifp
== NULL
|| pdelegated_ifp
== NULL
)
2775 else if (!ifnet_is_attached(ifp
, 1))
2778 ifnet_lock_shared(ifp
);
2779 if (ifp
->if_delegated
.ifp
!= NULL
)
2780 ifnet_reference(ifp
->if_delegated
.ifp
);
2781 *pdelegated_ifp
= ifp
->if_delegated
.ifp
;
2782 ifnet_lock_done(ifp
);
2784 /* Release the io ref count */
2785 ifnet_decr_iorefcnt(ifp
);
2791 key_fill_offload_frames_for_savs(ifnet_t ifp
,
2792 struct ifnet_keepalive_offload_frame
*frames_array
,
2793 u_int32_t frames_array_count
, size_t frame_data_offset
);
2796 udp_fill_keepalive_offload_frames(ifnet_t ifp
,
2797 struct ifnet_keepalive_offload_frame
*frames_array
,
2798 u_int32_t frames_array_count
, size_t frame_data_offset
,
2799 u_int32_t
*used_frames_count
);
2802 ifnet_get_keepalive_offload_frames(ifnet_t ifp
,
2803 struct ifnet_keepalive_offload_frame
*frames_array
,
2804 u_int32_t frames_array_count
, size_t frame_data_offset
,
2805 u_int32_t
*used_frames_count
)
2807 if (frames_array
== NULL
|| used_frames_count
== NULL
)
2810 /* frame_data_offset should be 32-bit aligned */
2811 if (P2ROUNDUP(frame_data_offset
, sizeof(u_int32_t
))
2812 != frame_data_offset
)
2815 *used_frames_count
= 0;
2816 if (frames_array_count
== 0)
2819 /* First collect IPSec related keep-alive frames */
2820 *used_frames_count
= key_fill_offload_frames_for_savs(ifp
,
2821 frames_array
, frames_array_count
, frame_data_offset
);
2823 /* If there is more room, collect other UDP keep-alive frames */
2824 if (*used_frames_count
< frames_array_count
)
2825 udp_fill_keepalive_offload_frames(ifp
, frames_array
,
2826 frames_array_count
, frame_data_offset
,
2829 VERIFY(*used_frames_count
<= frames_array_count
);
2834 ifnet_link_status_report(ifnet_t ifp
, const void *buffer
,
2837 struct if_link_status
*ifsr
;
2840 if (ifp
== NULL
|| buffer
== NULL
|| buffer_len
== 0)
2843 ifnet_lock_shared(ifp
);
2846 * Make sure that the interface is attached but there is no need
2847 * to take a reference because this call is coming from the driver.
2849 if (!ifnet_is_attached(ifp
, 0)) {
2850 ifnet_lock_done(ifp
);
2854 lck_rw_lock_exclusive(&ifp
->if_link_status_lock
);
2857 * If this is the first status report then allocate memory
2860 if (ifp
->if_link_status
== NULL
) {
2861 MALLOC(ifp
->if_link_status
, struct if_link_status
*,
2862 sizeof(struct if_link_status
), M_TEMP
, M_ZERO
);
2863 if (ifp
->if_link_status
== NULL
) {
2869 ifsr
= __DECONST(struct if_link_status
*, buffer
);
2871 if (ifp
->if_type
== IFT_CELLULAR
) {
2872 struct if_cellular_status_v1
*if_cell_sr
, *new_cell_sr
;
2874 * Currently we have a single version -- if it does
2875 * not match, just return.
2877 if (ifsr
->ifsr_version
!=
2878 IF_CELLULAR_STATUS_REPORT_CURRENT_VERSION
) {
2883 if (ifsr
->ifsr_len
!= sizeof(*if_cell_sr
)) {
2889 &ifp
->if_link_status
->ifsr_u
.ifsr_cell
.if_cell_u
.if_status_v1
;
2890 new_cell_sr
= &ifsr
->ifsr_u
.ifsr_cell
.if_cell_u
.if_status_v1
;
2891 ifp
->if_link_status
->ifsr_version
= ifsr
->ifsr_version
;
2892 ifp
->if_link_status
->ifsr_len
= ifsr
->ifsr_len
;
2893 if_cell_sr
->valid_bitmask
= 0;
2894 bcopy(new_cell_sr
, if_cell_sr
, sizeof(*if_cell_sr
));
2895 } else if (ifp
->if_subfamily
== IFNET_SUBFAMILY_WIFI
) {
2896 struct if_wifi_status_v1
*if_wifi_sr
, *new_wifi_sr
;
2899 if (ifsr
->ifsr_version
!=
2900 IF_WIFI_STATUS_REPORT_CURRENT_VERSION
) {
2905 if (ifsr
->ifsr_len
!= sizeof(*if_wifi_sr
)) {
2911 &ifp
->if_link_status
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
2913 &ifsr
->ifsr_u
.ifsr_wifi
.if_wifi_u
.if_status_v1
;
2914 ifp
->if_link_status
->ifsr_version
= ifsr
->ifsr_version
;
2915 ifp
->if_link_status
->ifsr_len
= ifsr
->ifsr_len
;
2916 if_wifi_sr
->valid_bitmask
= 0;
2917 bcopy(new_wifi_sr
, if_wifi_sr
, sizeof(*if_wifi_sr
));
2920 * Update the bandwidth values if we got recent values
2921 * reported through the other KPI.
2923 if (!(new_wifi_sr
->valid_bitmask
&
2924 IF_WIFI_UL_MAX_BANDWIDTH_VALID
) &&
2925 ifp
->if_output_bw
.max_bw
> 0) {
2926 if_wifi_sr
->valid_bitmask
|=
2927 IF_WIFI_UL_MAX_BANDWIDTH_VALID
;
2928 if_wifi_sr
->ul_max_bandwidth
=
2929 ifp
->if_output_bw
.max_bw
;
2931 if (!(new_wifi_sr
->valid_bitmask
&
2932 IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID
) &&
2933 ifp
->if_output_bw
.eff_bw
> 0) {
2934 if_wifi_sr
->valid_bitmask
|=
2935 IF_WIFI_UL_EFFECTIVE_BANDWIDTH_VALID
;
2936 if_wifi_sr
->ul_effective_bandwidth
=
2937 ifp
->if_output_bw
.eff_bw
;
2939 if (!(new_wifi_sr
->valid_bitmask
&
2940 IF_WIFI_DL_MAX_BANDWIDTH_VALID
) &&
2941 ifp
->if_input_bw
.max_bw
> 0) {
2942 if_wifi_sr
->valid_bitmask
|=
2943 IF_WIFI_DL_MAX_BANDWIDTH_VALID
;
2944 if_wifi_sr
->dl_max_bandwidth
=
2945 ifp
->if_input_bw
.max_bw
;
2947 if (!(new_wifi_sr
->valid_bitmask
&
2948 IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID
) &&
2949 ifp
->if_input_bw
.eff_bw
> 0) {
2950 if_wifi_sr
->valid_bitmask
|=
2951 IF_WIFI_DL_EFFECTIVE_BANDWIDTH_VALID
;
2952 if_wifi_sr
->dl_effective_bandwidth
=
2953 ifp
->if_input_bw
.eff_bw
;
2958 lck_rw_done(&ifp
->if_link_status_lock
);
2959 ifnet_lock_done(ifp
);
2963 /*************************************************************************/
2964 /* Packet preamble */
2965 /*************************************************************************/
2967 #define MAX_IF_PACKET_PREAMBLE_LEN 32
2970 ifnet_set_packetpreamblelen(ifnet_t interface
, u_int32_t len
)
2974 if (interface
== NULL
|| len
> MAX_IF_PACKET_PREAMBLE_LEN
) {
2978 interface
->if_data
.ifi_preamblelen
= len
;
2984 ifnet_packetpreamblelen(ifnet_t interface
)
2986 return ((interface
== NULL
) ? 0 : interface
->if_data
.ifi_preamblelen
);
2990 ifnet_maxpacketpreamblelen(void)
2992 return (MAX_IF_PACKET_PREAMBLE_LEN
);