2 * Copyright (c) 2000-2020 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 * Copyright (c) 1982, 1986, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)in.c 8.4 (Berkeley) 1/9/95
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/sockio.h>
66 #include <sys/socketvar.h>
67 #include <sys/malloc.h>
69 #include <sys/socket.h>
70 #include <sys/kernel.h>
71 #include <sys/sysctl.h>
72 #include <sys/kern_event.h>
73 #include <sys/syslog.h>
74 #include <sys/mcache.h>
75 #include <sys/protosw.h>
78 #include <kern/zalloc.h>
79 #include <pexpert/pexpert.h>
83 #include <net/if_types.h>
84 #include <net/route.h>
85 #include <net/kpi_protocol.h>
87 #include <net/if_llatbl.h>
88 #include <net/if_arp.h>
90 #include <net/pfvar.h>
93 #include <netinet/in.h>
94 #include <netinet/in_var.h>
95 #include <netinet/in_pcb.h>
96 #include <netinet/igmp_var.h>
97 #include <netinet/ip_var.h>
98 #include <netinet/tcp.h>
99 #include <netinet/tcp_timer.h>
100 #include <netinet/tcp_var.h>
101 #include <netinet/if_ether.h>
103 static int inctl_associd(struct socket
*, u_long
, caddr_t
);
104 static int inctl_connid(struct socket
*, u_long
, caddr_t
);
105 static int inctl_conninfo(struct socket
*, u_long
, caddr_t
);
106 static int inctl_autoaddr(struct ifnet
*, struct ifreq
*);
107 static int inctl_arpipll(struct ifnet
*, struct ifreq
*);
108 static int inctl_setrouter(struct ifnet
*, struct ifreq
*);
109 static int inctl_ifaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
111 static int inctl_ifdstaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
113 static int inctl_ifbrdaddr(struct ifnet
*, struct in_ifaddr
*, u_long
,
115 static int inctl_ifnetmask(struct ifnet
*, struct in_ifaddr
*, u_long
,
118 static void in_socktrim(struct sockaddr_in
*);
119 static int in_ifinit(struct ifnet
*, struct in_ifaddr
*,
120 struct sockaddr_in
*, int);
122 #define IA_HASH_INIT(ia) { \
123 (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1; \
124 (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1; \
127 #define IA_IS_HASHED(ia) \
128 (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 || \
129 (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1))
131 static void in_iahash_remove(struct in_ifaddr
*);
132 static void in_iahash_insert(struct in_ifaddr
*);
133 static void in_iahash_insert_ptp(struct in_ifaddr
*);
134 static struct in_ifaddr
*in_ifaddr_alloc(int);
135 static void in_ifaddr_attached(struct ifaddr
*);
136 static void in_ifaddr_detached(struct ifaddr
*);
137 static void in_ifaddr_free(struct ifaddr
*);
138 static void in_ifaddr_trace(struct ifaddr
*, int);
140 static int in_getassocids(struct socket
*, uint32_t *, user_addr_t
);
141 static int in_getconnids(struct socket
*, sae_associd_t
, uint32_t *, user_addr_t
);
143 /* IPv4 Layer 2 neighbor cache management routines */
144 static void in_lltable_destroy_lle_unlocked(struct llentry
*lle
);
145 static void in_lltable_destroy_lle(struct llentry
*lle
);
146 static struct llentry
*in_lltable_new(struct in_addr addr4
, uint16_t flags
);
147 static int in_lltable_match_prefix(const struct sockaddr
*saddr
,
148 const struct sockaddr
*smask
, uint16_t flags
, struct llentry
*lle
);
149 static void in_lltable_free_entry(struct lltable
*llt
, struct llentry
*lle
);
150 static int in_lltable_rtcheck(struct ifnet
*ifp
, uint16_t flags
, const struct sockaddr
*l3addr
);
151 static inline uint32_t in_lltable_hash_dst(const struct in_addr dst
, uint32_t hsize
);
152 static uint32_t in_lltable_hash(const struct llentry
*lle
, uint32_t hsize
);
153 static void in_lltable_fill_sa_entry(const struct llentry
*lle
, struct sockaddr
*sa
);
154 static inline struct llentry
* in_lltable_find_dst(struct lltable
*llt
, struct in_addr dst
);
155 static void in_lltable_delete_entry(struct lltable
*llt
, struct llentry
*lle
);
156 static struct llentry
* in_lltable_alloc(struct lltable
*llt
, uint16_t flags
, const struct sockaddr
*l3addr
);
157 static struct llentry
* in_lltable_lookup(struct lltable
*llt
, uint16_t flags
, const struct sockaddr
*l3addr
);
158 static int in_lltable_dump_entry(struct lltable
*llt
, struct llentry
*lle
, struct sysctl_req
*wr
);
159 static struct lltable
* in_lltattach(struct ifnet
*ifp
);
161 static int subnetsarelocal
= 0;
162 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
,
163 CTLFLAG_RW
| CTLFLAG_LOCKED
, &subnetsarelocal
, 0, "");
165 /* Track whether or not the SIOCARPIPLL ioctl has been called */
166 u_int32_t ipv4_ll_arp_aware
= 0;
168 #define INIFA_TRACE_HIST_SIZE 32 /* size of trace history */
171 __private_extern__
unsigned int inifa_trace_hist_size
= INIFA_TRACE_HIST_SIZE
;
173 struct in_ifaddr_dbg
{
174 struct in_ifaddr inifa
; /* in_ifaddr */
175 struct in_ifaddr inifa_old
; /* saved in_ifaddr */
176 u_int16_t inifa_refhold_cnt
; /* # of IFA_ADDREF */
177 u_int16_t inifa_refrele_cnt
; /* # of IFA_REMREF */
179 * Alloc and free callers.
181 ctrace_t inifa_alloc
;
184 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
186 ctrace_t inifa_refhold
[INIFA_TRACE_HIST_SIZE
];
187 ctrace_t inifa_refrele
[INIFA_TRACE_HIST_SIZE
];
191 TAILQ_ENTRY(in_ifaddr_dbg
) inifa_trash_link
;
194 /* List of trash in_ifaddr entries protected by inifa_trash_lock */
195 static TAILQ_HEAD(, in_ifaddr_dbg
) inifa_trash_head
;
196 static decl_lck_mtx_data(, inifa_trash_lock
);
199 static unsigned int inifa_debug
= 1; /* debugging (enabled) */
201 static unsigned int inifa_debug
; /* debugging (disabled) */
203 static unsigned int inifa_size
; /* size of zone element */
204 static struct zone
*inifa_zone
; /* zone for in_ifaddr */
206 #define INIFA_ZONE_NAME "in_ifaddr" /* zone name */
208 static const unsigned int in_extra_size
= sizeof(struct in_ifextra
);
209 static const unsigned int in_extra_bufsize
= in_extra_size
+
210 sizeof(void *) + sizeof(uint64_t);
213 * Return 1 if the address is
215 * - unicast or multicast link local
216 * - routed via a link level gateway
217 * - belongs to a directly connected (sub)net
220 inaddr_local(struct in_addr in
)
223 struct sockaddr_in sin
;
226 if (ntohl(in
.s_addr
) == INADDR_LOOPBACK
||
227 IN_LINKLOCAL(ntohl(in
.s_addr
))) {
229 } else if (ntohl(in
.s_addr
) >= INADDR_UNSPEC_GROUP
&&
230 ntohl(in
.s_addr
) <= INADDR_MAX_LOCAL_GROUP
) {
233 sin
.sin_family
= AF_INET
;
234 sin
.sin_len
= sizeof(sin
);
236 rt
= rtalloc1((struct sockaddr
*)&sin
, 0, 0);
240 if (rt
->rt_gateway
->sa_family
== AF_LINK
||
241 (rt
->rt_ifp
->if_flags
& IFF_LOOPBACK
)) {
247 local
= in_localaddr(in
);
254 * Return 1 if an internet address is for a ``local'' host
255 * (one to which we have a connection). If subnetsarelocal
256 * is true, this includes other subnets of the local net,
257 * otherwise, it includes the directly-connected (sub)nets.
258 * The IPv4 link local prefix 169.254/16 is also included.
261 in_localaddr(struct in_addr in
)
263 u_int32_t i
= ntohl(in
.s_addr
);
264 struct in_ifaddr
*ia
;
266 if (IN_LINKLOCAL(i
)) {
270 if (subnetsarelocal
) {
271 lck_rw_lock_shared(in_ifaddr_rwlock
);
272 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
273 ia
= ia
->ia_link
.tqe_next
) {
274 IFA_LOCK(&ia
->ia_ifa
);
275 if ((i
& ia
->ia_netmask
) == ia
->ia_net
) {
276 IFA_UNLOCK(&ia
->ia_ifa
);
277 lck_rw_done(in_ifaddr_rwlock
);
280 IFA_UNLOCK(&ia
->ia_ifa
);
282 lck_rw_done(in_ifaddr_rwlock
);
284 lck_rw_lock_shared(in_ifaddr_rwlock
);
285 for (ia
= in_ifaddrhead
.tqh_first
; ia
!= NULL
;
286 ia
= ia
->ia_link
.tqe_next
) {
287 IFA_LOCK(&ia
->ia_ifa
);
288 if ((i
& ia
->ia_subnetmask
) == ia
->ia_subnet
) {
289 IFA_UNLOCK(&ia
->ia_ifa
);
290 lck_rw_done(in_ifaddr_rwlock
);
293 IFA_UNLOCK(&ia
->ia_ifa
);
295 lck_rw_done(in_ifaddr_rwlock
);
301 * Determine whether an IP address is in a reserved set of addresses
302 * that may not be forwarded, or whether datagrams to that destination
306 in_canforward(struct in_addr in
)
308 u_int32_t i
= ntohl(in
.s_addr
);
311 if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
)) {
315 net
= i
& IN_CLASSA_NET
;
316 if (net
== 0 || net
== (IN_LOOPBACKNET
<< IN_CLASSA_NSHIFT
)) {
324 * Trim a mask in a sockaddr
327 in_socktrim(struct sockaddr_in
*ap
)
329 char *cplim
= (char *)&ap
->sin_addr
;
330 char *cp
= (char *)(&ap
->sin_addr
+ 1);
333 while (--cp
>= cplim
) {
335 (ap
)->sin_len
= (uint8_t)(cp
- (char *)(ap
) + 1);
341 static int in_interfaces
; /* number of external internet interfaces */
344 in_domifattach(struct ifnet
*ifp
)
350 if ((error
= proto_plumb(PF_INET
, ifp
)) && error
!= EEXIST
) {
351 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s\n",
352 __func__
, error
, if_name(ifp
));
353 } else if (error
== 0 && ifp
->if_inetdata
== NULL
) {
355 struct in_ifextra
*ext
;
358 if ((ext
= (struct in_ifextra
*)_MALLOC(in_extra_bufsize
,
359 M_IFADDR
, M_WAITOK
| M_ZERO
)) == NULL
) {
361 errorx
= proto_unplumb(PF_INET
, ifp
);
364 "%s: proto_unplumb returned %d if=%s%d\n",
365 __func__
, errorx
, ifp
->if_name
,
371 /* Align on 64-bit boundary */
372 base
= (void *)P2ROUNDUP((intptr_t)ext
+ sizeof(uint64_t),
374 VERIFY(((intptr_t)base
+ in_extra_size
) <=
375 ((intptr_t)ext
+ in_extra_bufsize
));
376 pbuf
= (void **)((intptr_t)base
- sizeof(void *));
378 ifp
->if_inetdata
= base
;
379 IN_IFEXTRA(ifp
)->ii_llt
= in_lltattach(ifp
);
380 VERIFY(IS_P2ALIGNED(ifp
->if_inetdata
, sizeof(uint64_t)));
383 if (error
== 0 && ifp
->if_inetdata
!= NULL
) {
385 * Since the structure is never freed, we need to
386 * zero out its contents to avoid reusing stale data.
387 * A little redundant with allocation above, but it
388 * keeps the code simpler for all cases.
390 bzero(ifp
->if_inetdata
, in_extra_size
);
395 static __attribute__((noinline
)) int
396 inctl_associd(struct socket
*so
, u_long cmd
, caddr_t data
)
400 struct so_aidreq32 a32
;
401 struct so_aidreq64 a64
;
407 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
408 bcopy(data
, &u
.a32
, sizeof(u
.a32
));
409 error
= in_getassocids(so
, &u
.a32
.sar_cnt
, u
.a32
.sar_aidp
);
411 bcopy(&u
.a32
, data
, sizeof(u
.a32
));
415 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
416 bcopy(data
, &u
.a64
, sizeof(u
.a64
));
417 error
= in_getassocids(so
, &u
.a64
.sar_cnt
, (user_addr_t
)u
.a64
.sar_aidp
);
419 bcopy(&u
.a64
, data
, sizeof(u
.a64
));
431 static __attribute__((noinline
)) int
432 inctl_connid(struct socket
*so
, u_long cmd
, caddr_t data
)
436 struct so_cidreq32 c32
;
437 struct so_cidreq64 c64
;
443 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
444 bcopy(data
, &u
.c32
, sizeof(u
.c32
));
445 error
= in_getconnids(so
, u
.c32
.scr_aid
, &u
.c32
.scr_cnt
,
448 bcopy(&u
.c32
, data
, sizeof(u
.c32
));
452 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
453 bcopy(data
, &u
.c64
, sizeof(u
.c64
));
454 error
= in_getconnids(so
, u
.c64
.scr_aid
, &u
.c64
.scr_cnt
,
455 (user_addr_t
)u
.c64
.scr_cidp
);
457 bcopy(&u
.c64
, data
, sizeof(u
.c64
));
469 static __attribute__((noinline
)) int
470 inctl_conninfo(struct socket
*so
, u_long cmd
, caddr_t data
)
474 struct so_cinforeq32 ci32
;
475 struct so_cinforeq64 ci64
;
481 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
482 bcopy(data
, &u
.ci32
, sizeof(u
.ci32
));
483 error
= in_getconninfo(so
, u
.ci32
.scir_cid
, &u
.ci32
.scir_flags
,
484 &u
.ci32
.scir_ifindex
, &u
.ci32
.scir_error
, u
.ci32
.scir_src
,
485 &u
.ci32
.scir_src_len
, u
.ci32
.scir_dst
, &u
.ci32
.scir_dst_len
,
486 &u
.ci32
.scir_aux_type
, u
.ci32
.scir_aux_data
,
487 &u
.ci32
.scir_aux_len
);
489 bcopy(&u
.ci32
, data
, sizeof(u
.ci32
));
493 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
494 bcopy(data
, &u
.ci64
, sizeof(u
.ci64
));
495 error
= in_getconninfo(so
, u
.ci64
.scir_cid
, &u
.ci64
.scir_flags
,
496 &u
.ci64
.scir_ifindex
, &u
.ci64
.scir_error
, (user_addr_t
)u
.ci64
.scir_src
,
497 &u
.ci64
.scir_src_len
, (user_addr_t
)u
.ci64
.scir_dst
, &u
.ci64
.scir_dst_len
,
498 &u
.ci64
.scir_aux_type
, (user_addr_t
)u
.ci64
.scir_aux_data
,
499 &u
.ci64
.scir_aux_len
);
501 bcopy(&u
.ci64
, data
, sizeof(u
.ci64
));
514 * Caller passes in the ioctl data pointer directly via "ifr", with the
515 * expectation that this routine always uses bcopy() or other byte-aligned
518 static __attribute__((noinline
)) int
519 inctl_autoaddr(struct ifnet
*ifp
, struct ifreq
*ifr
)
521 int error
= 0, intval
;
525 bcopy(&ifr
->ifr_intval
, &intval
, sizeof(intval
));
527 ifnet_lock_exclusive(ifp
);
530 * An interface in IPv4 router mode implies that it
531 * is configured with a static IP address and should
532 * not act as a DHCP client; prevent SIOCAUTOADDR from
533 * being set in that mode.
535 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
536 intval
= 0; /* be safe; clear flag if set */
539 if_set_eflags(ifp
, IFEF_AUTOCONFIGURING
);
543 if_clear_eflags(ifp
, IFEF_AUTOCONFIGURING
);
545 ifnet_lock_done(ifp
);
551 * Caller passes in the ioctl data pointer directly via "ifr", with the
552 * expectation that this routine always uses bcopy() or other byte-aligned
555 static __attribute__((noinline
)) int
556 inctl_arpipll(struct ifnet
*ifp
, struct ifreq
*ifr
)
558 int error
= 0, intval
;
562 bcopy(&ifr
->ifr_intval
, &intval
, sizeof(intval
));
563 ipv4_ll_arp_aware
= 1;
565 ifnet_lock_exclusive(ifp
);
568 * An interface in IPv4 router mode implies that it
569 * is configured with a static IP address and should
570 * not have to deal with IPv4 Link-Local Address;
571 * prevent SIOCARPIPLL from being set in that mode.
573 if (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) {
574 intval
= 0; /* be safe; clear flag if set */
577 if_set_eflags(ifp
, IFEF_ARPLL
);
581 if_clear_eflags(ifp
, IFEF_ARPLL
);
583 ifnet_lock_done(ifp
);
589 * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on
590 * the interface. When in this mode, IPv4 Link-Local Address support is
591 * disabled in ARP, and DHCP client support is disabled in IP input; turning
592 * any of them on would cause an error to be returned. Entering or exiting
593 * this mode will result in the removal of IPv4 addresses currently configured
596 * Caller passes in the ioctl data pointer directly via "ifr", with the
597 * expectation that this routine always uses bcopy() or other byte-aligned
600 static __attribute__((noinline
)) int
601 inctl_setrouter(struct ifnet
*ifp
, struct ifreq
*ifr
)
603 int error
= 0, intval
;
607 /* Router mode isn't valid for loopback */
608 if (ifp
->if_flags
& IFF_LOOPBACK
) {
612 bcopy(&ifr
->ifr_intval
, &intval
, sizeof(intval
));
620 ifnet_lock_exclusive(ifp
);
622 if_set_eflags(ifp
, IFEF_IPV4_ROUTER
);
623 if_clear_eflags(ifp
, (IFEF_ARPLL
| IFEF_AUTOCONFIGURING
));
625 if_clear_eflags(ifp
, IFEF_IPV4_ROUTER
);
627 ifnet_lock_done(ifp
);
629 /* purge all IPv4 addresses configured on this interface */
636 * Caller passes in the ioctl data pointer directly via "ifr", with the
637 * expectation that this routine always uses bcopy() or other byte-aligned
640 static __attribute__((noinline
)) int
641 inctl_ifaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
644 struct kev_in_data in_event_data
;
645 struct kev_msg ev_msg
;
646 struct sockaddr_in addr
;
652 bzero(&in_event_data
, sizeof(struct kev_in_data
));
653 bzero(&ev_msg
, sizeof(struct kev_msg
));
656 case SIOCGIFADDR
: /* struct ifreq */
658 error
= EADDRNOTAVAIL
;
661 IFA_LOCK(&ia
->ia_ifa
);
662 bcopy(&ia
->ia_addr
, &ifr
->ifr_addr
, sizeof(addr
));
663 IFA_UNLOCK(&ia
->ia_ifa
);
666 case SIOCSIFADDR
: /* struct ifreq */
668 bcopy(&ifr
->ifr_addr
, &addr
, sizeof(addr
));
670 * If this is a new address, the reference count for the
671 * hash table has been taken at creation time above.
673 error
= in_ifinit(ifp
, ia
, &addr
, 1);
675 (void) ifnet_notify_address(ifp
, AF_INET
);
679 case SIOCAIFADDR
: { /* struct {if,in_}aliasreq */
680 struct in_aliasreq
*ifra
= (struct in_aliasreq
*)ifr
;
681 struct sockaddr_in broadaddr
, mask
;
682 int hostIsNew
, maskIsNew
;
685 bcopy(&ifra
->ifra_addr
, &addr
, sizeof(addr
));
686 bcopy(&ifra
->ifra_broadaddr
, &broadaddr
, sizeof(broadaddr
));
687 bcopy(&ifra
->ifra_mask
, &mask
, sizeof(mask
));
693 IFA_LOCK(&ia
->ia_ifa
);
694 if (ia
->ia_addr
.sin_family
== AF_INET
) {
695 if (addr
.sin_len
== 0) {
698 } else if (addr
.sin_addr
.s_addr
==
699 ia
->ia_addr
.sin_addr
.s_addr
) {
703 if (mask
.sin_len
!= 0) {
704 IFA_UNLOCK(&ia
->ia_ifa
);
705 in_ifscrub(ifp
, ia
, 0);
706 IFA_LOCK(&ia
->ia_ifa
);
707 ia
->ia_sockmask
.sin_len
= sizeof(struct sockaddr_in
);
708 ia
->ia_sockmask
.sin_family
= AF_INET
;
709 ia
->ia_sockmask
.sin_port
= 0;
710 ia
->ia_sockmask
.sin_addr
= mask
.sin_addr
;
711 bzero(&ia
->ia_sockmask
.sin_zero
, sizeof(ia
->ia_dstaddr
.sin_zero
));
713 ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
);
716 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
717 (broadaddr
.sin_family
== AF_INET
)) {
718 IFA_UNLOCK(&ia
->ia_ifa
);
719 in_ifscrub(ifp
, ia
, 0);
720 IFA_LOCK(&ia
->ia_ifa
);
721 ia
->ia_dstaddr
.sin_family
= AF_INET
;
722 ia
->ia_dstaddr
.sin_len
= sizeof(struct sockaddr_in
);
723 ia
->ia_dstaddr
.sin_port
= 0;
724 ia
->ia_dstaddr
.sin_addr
= broadaddr
.sin_addr
;
725 bzero(&ia
->ia_dstaddr
.sin_zero
, sizeof(ia
->ia_dstaddr
.sin_zero
));
726 maskIsNew
= 1; /* We lie; but the effect's the same */
728 if (addr
.sin_family
== AF_INET
&& (hostIsNew
|| maskIsNew
)) {
729 IFA_UNLOCK(&ia
->ia_ifa
);
730 error
= in_ifinit(ifp
, ia
, &addr
, 0);
732 IFA_UNLOCK(&ia
->ia_ifa
);
735 (void) ifnet_notify_address(ifp
, AF_INET
);
737 IFA_LOCK(&ia
->ia_ifa
);
738 if ((ifp
->if_flags
& IFF_BROADCAST
) &&
739 (broadaddr
.sin_family
== AF_INET
)) {
740 ia
->ia_broadaddr
.sin_family
= AF_INET
;
741 ia
->ia_broadaddr
.sin_len
= sizeof(struct sockaddr_in
);
742 ia
->ia_broadaddr
.sin_port
= 0;
743 ia
->ia_broadaddr
.sin_addr
= broadaddr
.sin_addr
;
744 bzero(&ia
->ia_broadaddr
.sin_zero
, sizeof(ia
->ia_broadaddr
.sin_zero
));
750 if ((error
== 0) || (error
== EEXIST
)) {
751 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
752 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
753 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
756 ev_msg
.event_code
= KEV_INET_NEW_ADDR
;
758 ev_msg
.event_code
= KEV_INET_CHANGED_ADDR
;
761 if (ia
->ia_ifa
.ifa_dstaddr
) {
762 in_event_data
.ia_dstaddr
=
763 ((struct sockaddr_in
*)(void *)ia
->
764 ia_ifa
.ifa_dstaddr
)->sin_addr
;
766 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
768 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
769 in_event_data
.ia_net
= ia
->ia_net
;
770 in_event_data
.ia_netmask
= ia
->ia_netmask
;
771 in_event_data
.ia_subnet
= ia
->ia_subnet
;
772 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
773 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
774 IFA_UNLOCK(&ia
->ia_ifa
);
775 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
776 ifp
->if_name
, IFNAMSIZ
);
777 in_event_data
.link_data
.if_family
= ifp
->if_family
;
778 in_event_data
.link_data
.if_unit
= ifp
->if_unit
;
780 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
781 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
782 ev_msg
.dv
[1].data_length
= 0;
784 dlil_post_complete_msg(ifp
, &ev_msg
);
786 IFA_UNLOCK(&ia
->ia_ifa
);
791 case SIOCDIFADDR
: /* struct ifreq */
793 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
);
794 if (error
== EOPNOTSUPP
) {
801 /* Fill out the kernel event information */
802 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
803 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
804 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
806 ev_msg
.event_code
= KEV_INET_ADDR_DELETED
;
808 IFA_LOCK(&ia
->ia_ifa
);
809 if (ia
->ia_ifa
.ifa_dstaddr
) {
810 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
811 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
813 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
815 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
816 in_event_data
.ia_net
= ia
->ia_net
;
817 in_event_data
.ia_netmask
= ia
->ia_netmask
;
818 in_event_data
.ia_subnet
= ia
->ia_subnet
;
819 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
820 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
821 IFA_UNLOCK(&ia
->ia_ifa
);
822 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
823 ifp
->if_name
, IFNAMSIZ
);
824 in_event_data
.link_data
.if_family
= ifp
->if_family
;
825 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
827 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
828 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
829 ev_msg
.dv
[1].data_length
= 0;
832 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
833 /* Release ia_link reference */
835 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
);
837 if (IA_IS_HASHED(ia
)) {
838 in_iahash_remove(ia
);
841 lck_rw_done(in_ifaddr_rwlock
);
844 * in_ifscrub kills the interface route.
846 in_ifscrub(ifp
, ia
, 0);
847 ifnet_lock_exclusive(ifp
);
849 /* if_detach_ifa() releases ifa_link reference */
850 if_detach_ifa(ifp
, ifa
);
851 /* Our reference to this address is dropped at the bottom */
854 /* invalidate route caches */
855 routegenid_inet_update();
858 * If the interface supports multicast, and no address is left,
859 * remove the "all hosts" multicast group from that interface.
861 if ((ifp
->if_flags
& IFF_MULTICAST
) ||
862 ifp
->if_allhostsinm
!= NULL
) {
863 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
865 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
871 ifnet_lock_done(ifp
);
873 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
874 if (ifa
== NULL
&& ifp
->if_allhostsinm
!= NULL
) {
875 struct in_multi
*inm
= ifp
->if_allhostsinm
;
876 ifp
->if_allhostsinm
= NULL
;
879 /* release the reference for allhostsinm */
882 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
884 ifnet_lock_done(ifp
);
887 /* Post the kernel event */
888 dlil_post_complete_msg(ifp
, &ev_msg
);
891 * See if there is any IPV4 address left and if so,
892 * reconfigure KDP to use current primary address.
894 ifa
= ifa_ifpgetprimary(ifp
, AF_INET
);
897 * NOTE: SIOCSIFADDR is defined with struct ifreq
898 * as parameter, but here we are sending it down
899 * to the interface with a pointer to struct ifaddr,
900 * for legacy reasons.
902 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
);
903 if (error
== EOPNOTSUPP
) {
907 /* Release reference from ifa_ifpgetprimary() */
910 (void) ifnet_notify_address(ifp
, AF_INET
);
922 * Caller passes in the ioctl data pointer directly via "ifr", with the
923 * expectation that this routine always uses bcopy() or other byte-aligned
926 static __attribute__((noinline
)) int
927 inctl_ifdstaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
930 struct kev_in_data in_event_data
;
931 struct kev_msg ev_msg
;
932 struct sockaddr_in dstaddr
;
937 if (!(ifp
->if_flags
& IFF_POINTOPOINT
)) {
941 bzero(&in_event_data
, sizeof(struct kev_in_data
));
942 bzero(&ev_msg
, sizeof(struct kev_msg
));
945 case SIOCGIFDSTADDR
: /* struct ifreq */
947 error
= EADDRNOTAVAIL
;
950 IFA_LOCK(&ia
->ia_ifa
);
951 bcopy(&ia
->ia_dstaddr
, &ifr
->ifr_dstaddr
, sizeof(dstaddr
));
952 IFA_UNLOCK(&ia
->ia_ifa
);
955 case SIOCSIFDSTADDR
: /* struct ifreq */
957 IFA_LOCK(&ia
->ia_ifa
);
958 dstaddr
= ia
->ia_dstaddr
;
960 ia
->ia_dstaddr
.sin_family
= AF_INET
;
961 ia
->ia_dstaddr
.sin_len
= sizeof(struct sockaddr_in
);
962 ia
->ia_dstaddr
.sin_port
= 0;
963 bcopy(&(SIN(&ifr
->ifr_dstaddr
)->sin_addr
),
964 &ia
->ia_dstaddr
.sin_addr
, sizeof(ia
->ia_dstaddr
.sin_addr
));
965 bzero(&ia
->ia_dstaddr
.sin_zero
, sizeof(ia
->ia_dstaddr
.sin_zero
));
967 IFA_UNLOCK(&ia
->ia_ifa
);
969 * NOTE: SIOCSIFDSTADDR is defined with struct ifreq
970 * as parameter, but here we are sending it down
971 * to the interface with a pointer to struct ifaddr,
972 * for legacy reasons.
974 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
);
975 IFA_LOCK(&ia
->ia_ifa
);
976 if (error
== EOPNOTSUPP
) {
980 ia
->ia_dstaddr
= dstaddr
;
981 IFA_UNLOCK(&ia
->ia_ifa
);
984 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
986 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
987 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
988 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
990 ev_msg
.event_code
= KEV_INET_SIFDSTADDR
;
992 if (ia
->ia_ifa
.ifa_dstaddr
) {
993 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
994 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
996 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
999 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1000 in_event_data
.ia_net
= ia
->ia_net
;
1001 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1002 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1003 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1004 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1005 IFA_UNLOCK(&ia
->ia_ifa
);
1006 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
1007 ifp
->if_name
, IFNAMSIZ
);
1008 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1009 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1011 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1012 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
1013 ev_msg
.dv
[1].data_length
= 0;
1015 dlil_post_complete_msg(ifp
, &ev_msg
);
1017 lck_mtx_lock(rnh_lock
);
1018 IFA_LOCK(&ia
->ia_ifa
);
1019 if (ia
->ia_flags
& IFA_ROUTE
) {
1020 ia
->ia_ifa
.ifa_dstaddr
= (struct sockaddr
*)&dstaddr
;
1021 IFA_UNLOCK(&ia
->ia_ifa
);
1022 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1023 IFA_LOCK(&ia
->ia_ifa
);
1024 ia
->ia_ifa
.ifa_dstaddr
=
1025 (struct sockaddr
*)&ia
->ia_dstaddr
;
1026 IFA_UNLOCK(&ia
->ia_ifa
);
1027 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
,
1030 IFA_UNLOCK(&ia
->ia_ifa
);
1032 lck_mtx_unlock(rnh_lock
);
1046 * Caller passes in the ioctl data pointer directly via "ifr", with the
1047 * expectation that this routine always uses bcopy() or other byte-aligned
1050 static __attribute__((noinline
)) int
1051 inctl_ifbrdaddr(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
1054 struct kev_in_data in_event_data
;
1055 struct kev_msg ev_msg
;
1058 VERIFY(ifp
!= NULL
);
1061 return EADDRNOTAVAIL
;
1064 if (!(ifp
->if_flags
& IFF_BROADCAST
)) {
1068 bzero(&in_event_data
, sizeof(struct kev_in_data
));
1069 bzero(&ev_msg
, sizeof(struct kev_msg
));
1072 case SIOCGIFBRDADDR
: /* struct ifreq */
1073 IFA_LOCK(&ia
->ia_ifa
);
1074 bcopy(&ia
->ia_broadaddr
, &ifr
->ifr_broadaddr
,
1075 sizeof(struct sockaddr_in
));
1076 IFA_UNLOCK(&ia
->ia_ifa
);
1079 case SIOCSIFBRDADDR
: /* struct ifreq */
1080 IFA_LOCK(&ia
->ia_ifa
);
1082 ia
->ia_broadaddr
.sin_family
= AF_INET
;
1083 ia
->ia_broadaddr
.sin_len
= sizeof(struct sockaddr_in
);
1084 ia
->ia_broadaddr
.sin_port
= 0;
1085 bcopy(&(SIN(&ifr
->ifr_broadaddr
)->sin_addr
),
1086 &ia
->ia_broadaddr
.sin_addr
, sizeof(ia
->ia_broadaddr
.sin_addr
));
1087 bzero(&ia
->ia_broadaddr
.sin_zero
, sizeof(ia
->ia_broadaddr
.sin_zero
));
1089 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1090 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1091 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1093 ev_msg
.event_code
= KEV_INET_SIFBRDADDR
;
1095 if (ia
->ia_ifa
.ifa_dstaddr
) {
1096 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1097 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1099 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1101 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1102 in_event_data
.ia_net
= ia
->ia_net
;
1103 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1104 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1105 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1106 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1107 IFA_UNLOCK(&ia
->ia_ifa
);
1108 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
1109 ifp
->if_name
, IFNAMSIZ
);
1110 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1111 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1113 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1114 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
1115 ev_msg
.dv
[1].data_length
= 0;
1117 dlil_post_complete_msg(ifp
, &ev_msg
);
1129 * Caller passes in the ioctl data pointer directly via "ifr", with the
1130 * expectation that this routine always uses bcopy() or other byte-aligned
1133 static __attribute__((noinline
)) int
1134 inctl_ifnetmask(struct ifnet
*ifp
, struct in_ifaddr
*ia
, u_long cmd
,
1137 struct kev_in_data in_event_data
;
1138 struct kev_msg ev_msg
;
1139 struct sockaddr_in mask
;
1142 VERIFY(ifp
!= NULL
);
1144 bzero(&in_event_data
, sizeof(struct kev_in_data
));
1145 bzero(&ev_msg
, sizeof(struct kev_msg
));
1148 case SIOCGIFNETMASK
: /* struct ifreq */
1150 error
= EADDRNOTAVAIL
;
1153 IFA_LOCK(&ia
->ia_ifa
);
1154 bcopy(&ia
->ia_sockmask
, &ifr
->ifr_addr
, sizeof(mask
));
1155 IFA_UNLOCK(&ia
->ia_ifa
);
1158 case SIOCSIFNETMASK
: { /* struct ifreq */
1161 bcopy(&ifr
->ifr_addr
, &mask
, sizeof(mask
));
1162 i
= mask
.sin_addr
.s_addr
;
1165 IFA_LOCK(&ia
->ia_ifa
);
1166 ia
->ia_subnetmask
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
= i
);
1167 ev_msg
.vendor_code
= KEV_VENDOR_APPLE
;
1168 ev_msg
.kev_class
= KEV_NETWORK_CLASS
;
1169 ev_msg
.kev_subclass
= KEV_INET_SUBCLASS
;
1171 ev_msg
.event_code
= KEV_INET_SIFNETMASK
;
1173 if (ia
->ia_ifa
.ifa_dstaddr
) {
1174 in_event_data
.ia_dstaddr
= ((struct sockaddr_in
*)
1175 (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
;
1177 in_event_data
.ia_dstaddr
.s_addr
= INADDR_ANY
;
1179 in_event_data
.ia_addr
= ia
->ia_addr
.sin_addr
;
1180 in_event_data
.ia_net
= ia
->ia_net
;
1181 in_event_data
.ia_netmask
= ia
->ia_netmask
;
1182 in_event_data
.ia_subnet
= ia
->ia_subnet
;
1183 in_event_data
.ia_subnetmask
= ia
->ia_subnetmask
;
1184 in_event_data
.ia_netbroadcast
= ia
->ia_netbroadcast
;
1185 IFA_UNLOCK(&ia
->ia_ifa
);
1186 (void) strlcpy(&in_event_data
.link_data
.if_name
[0],
1187 ifp
->if_name
, IFNAMSIZ
);
1188 in_event_data
.link_data
.if_family
= ifp
->if_family
;
1189 in_event_data
.link_data
.if_unit
= (u_int32_t
)ifp
->if_unit
;
1191 ev_msg
.dv
[0].data_ptr
= &in_event_data
;
1192 ev_msg
.dv
[0].data_length
= sizeof(struct kev_in_data
);
1193 ev_msg
.dv
[1].data_length
= 0;
1195 dlil_post_complete_msg(ifp
, &ev_msg
);
1208 * Generic INET control operations (ioctl's).
1210 * ifp is NULL if not an interface-specific ioctl.
1212 * Most of the routines called to handle the ioctls would end up being
1213 * tail-call optimized, which unfortunately causes this routine to
1214 * consume too much stack space; this is the reason for the "noinline"
1215 * attribute used on those routines.
1217 * If called directly from within the networking stack (as opposed to via
1218 * pru_control), the socket parameter may be NULL.
1221 in_control(struct socket
*so
, u_long cmd
, caddr_t data
, struct ifnet
*ifp
,
1224 struct ifreq
*ifr
= (struct ifreq
*)(void *)data
;
1225 struct sockaddr_in addr
, dstaddr
;
1226 struct sockaddr_in sin
, *sa
= NULL
;
1227 boolean_t privileged
= (proc_suser(p
) == 0);
1228 boolean_t so_unlocked
= FALSE
;
1229 struct in_ifaddr
*ia
= NULL
;
1234 /* In case it's NULL, make sure it came from the kernel */
1235 VERIFY(so
!= NULL
|| p
== kernproc
);
1238 * ioctls which don't require ifp, but require socket.
1241 case SIOCGASSOCIDS32
: /* struct so_aidreq32 */
1242 case SIOCGASSOCIDS64
: /* struct so_aidreq64 */
1243 return inctl_associd(so
, cmd
, data
);
1246 case SIOCGCONNIDS32
: /* struct so_cidreq32 */
1247 case SIOCGCONNIDS64
: /* struct so_cidreq64 */
1248 return inctl_connid(so
, cmd
, data
);
1251 case SIOCGCONNINFO32
: /* struct so_cinforeq32 */
1252 case SIOCGCONNINFO64
: /* struct so_cinforeq64 */
1253 return inctl_conninfo(so
, cmd
, data
);
1258 * The rest of ioctls require ifp; reject if we don't have one;
1259 * return ENXIO to be consistent with ifioctl().
1266 * ioctls which require ifp but not interface address.
1269 case SIOCAUTOADDR
: /* struct ifreq */
1273 return inctl_autoaddr(ifp
, ifr
);
1276 case SIOCARPIPLL
: /* struct ifreq */
1280 return inctl_arpipll(ifp
, ifr
);
1283 case SIOCGETROUTERMODE
: /* struct ifreq */
1284 intval
= (ifp
->if_eflags
& IFEF_IPV4_ROUTER
) != 0 ? 1 : 0;
1285 bcopy(&intval
, &ifr
->ifr_intval
, sizeof(intval
));
1289 case SIOCSETROUTERMODE
: /* struct ifreq */
1293 return inctl_setrouter(ifp
, ifr
);
1296 case SIOCPROTOATTACH
: /* struct ifreq */
1300 return in_domifattach(ifp
);
1303 case SIOCPROTODETACH
: /* struct ifreq */
1309 * If an IPv4 address is still present, refuse to detach.
1311 ifnet_lock_shared(ifp
);
1312 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1314 if (ifa
->ifa_addr
->sa_family
== AF_INET
) {
1320 ifnet_lock_done(ifp
);
1321 return (ifa
== NULL
) ? proto_unplumb(PF_INET
, ifp
) : EBUSY
;
1326 * ioctls which require interface address; obtain sockaddr_in.
1329 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1333 bcopy(&((struct in_aliasreq
*)(void *)data
)->ifra_addr
,
1338 case SIOCDIFADDR
: /* struct ifreq */
1339 case SIOCSIFADDR
: /* struct ifreq */
1340 case SIOCSIFDSTADDR
: /* struct ifreq */
1341 case SIOCSIFNETMASK
: /* struct ifreq */
1342 case SIOCSIFBRDADDR
: /* struct ifreq */
1347 case SIOCGIFADDR
: /* struct ifreq */
1348 case SIOCGIFDSTADDR
: /* struct ifreq */
1349 case SIOCGIFNETMASK
: /* struct ifreq */
1350 case SIOCGIFBRDADDR
: /* struct ifreq */
1351 bcopy(&ifr
->ifr_addr
, &sin
, sizeof(sin
));
1357 * Find address for this interface, if it exists.
1359 * If an alias address was specified, find that one instead of
1360 * the first one on the interface, if possible.
1364 struct in_ifaddr
*iap
;
1367 * Any failures from this point on must take into account
1368 * a non-NULL "ia" with an outstanding reference count, and
1369 * therefore requires IFA_REMREF. Jump to "done" label
1370 * instead of calling return if "ia" is valid.
1372 lck_rw_lock_shared(in_ifaddr_rwlock
);
1373 TAILQ_FOREACH(iap
, INADDR_HASH(sa
->sin_addr
.s_addr
), ia_hash
) {
1374 IFA_LOCK(&iap
->ia_ifa
);
1375 if (iap
->ia_ifp
== ifp
&&
1376 iap
->ia_addr
.sin_addr
.s_addr
==
1377 sa
->sin_addr
.s_addr
) {
1379 IFA_ADDREF_LOCKED(&iap
->ia_ifa
);
1380 IFA_UNLOCK(&iap
->ia_ifa
);
1383 IFA_UNLOCK(&iap
->ia_ifa
);
1385 lck_rw_done(in_ifaddr_rwlock
);
1388 ifnet_lock_shared(ifp
);
1389 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1391 IFA_LOCK(&iap
->ia_ifa
);
1392 if (iap
->ia_addr
.sin_family
== AF_INET
) {
1394 IFA_ADDREF_LOCKED(&iap
->ia_ifa
);
1395 IFA_UNLOCK(&iap
->ia_ifa
);
1398 IFA_UNLOCK(&iap
->ia_ifa
);
1400 ifnet_lock_done(ifp
);
1405 * Unlock the socket since ifnet_ioctl() may be invoked by
1406 * one of the ioctl handlers below. Socket will be re-locked
1407 * prior to returning.
1410 socket_unlock(so
, 0);
1415 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1416 case SIOCDIFADDR
: /* struct ifreq */
1417 if (cmd
== SIOCAIFADDR
) {
1418 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1419 ifra_addr
, &addr
, sizeof(addr
));
1420 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1421 ifra_dstaddr
, &dstaddr
, sizeof(dstaddr
));
1423 VERIFY(cmd
== SIOCDIFADDR
);
1424 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1425 &addr
, sizeof(addr
));
1426 bzero(&dstaddr
, sizeof(dstaddr
));
1429 if (addr
.sin_family
== AF_INET
) {
1430 struct in_ifaddr
*oia
;
1432 lck_rw_lock_shared(in_ifaddr_rwlock
);
1433 for (oia
= ia
; ia
; ia
= ia
->ia_link
.tqe_next
) {
1434 IFA_LOCK(&ia
->ia_ifa
);
1435 if (ia
->ia_ifp
== ifp
&&
1436 ia
->ia_addr
.sin_addr
.s_addr
==
1437 addr
.sin_addr
.s_addr
) {
1438 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1439 IFA_UNLOCK(&ia
->ia_ifa
);
1442 IFA_UNLOCK(&ia
->ia_ifa
);
1444 lck_rw_done(in_ifaddr_rwlock
);
1446 IFA_REMREF(&oia
->ia_ifa
);
1448 if ((ifp
->if_flags
& IFF_POINTOPOINT
) &&
1449 (cmd
== SIOCAIFADDR
) &&
1450 (dstaddr
.sin_addr
.s_addr
== INADDR_ANY
)) {
1451 error
= EDESTADDRREQ
;
1454 } else if (cmd
== SIOCAIFADDR
) {
1458 if (cmd
== SIOCDIFADDR
) {
1460 error
= EADDRNOTAVAIL
;
1464 IFA_LOCK(&ia
->ia_ifa
);
1466 * Avoid the race condition seen when two
1467 * threads process SIOCDIFADDR command
1470 while (ia
->ia_ifa
.ifa_debug
& IFD_DETACHING
) {
1471 os_log(OS_LOG_DEFAULT
,
1472 "Another thread is already attempting to "
1473 "delete IPv4 address: %s on interface %s. "
1474 "Go to sleep and check again after the operation is done",
1475 inet_ntoa(sa
->sin_addr
), ia
->ia_ifp
->if_xname
);
1476 ia
->ia_ifa
.ifa_del_waiters
++;
1477 (void) msleep(ia
->ia_ifa
.ifa_del_wc
, &ia
->ia_ifa
.ifa_lock
, (PZERO
- 1),
1479 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1482 if ((ia
->ia_ifa
.ifa_debug
& IFD_ATTACHED
) == 0) {
1483 error
= EADDRNOTAVAIL
;
1484 IFA_UNLOCK(&ia
->ia_ifa
);
1488 ia
->ia_ifa
.ifa_debug
|= IFD_DETACHING
;
1489 IFA_UNLOCK(&ia
->ia_ifa
);
1493 case SIOCSIFADDR
: /* struct ifreq */
1494 case SIOCSIFDSTADDR
: /* struct ifreq */
1495 case SIOCSIFNETMASK
: /* struct ifreq */
1496 if (cmd
== SIOCAIFADDR
) {
1497 /* fell thru from above; just repeat it */
1498 bcopy(&((struct in_aliasreq
*)(void *)data
)->
1499 ifra_addr
, &addr
, sizeof(addr
));
1501 VERIFY(cmd
== SIOCDIFADDR
|| cmd
== SIOCSIFADDR
||
1502 cmd
== SIOCSIFNETMASK
|| cmd
== SIOCSIFDSTADDR
);
1503 bcopy(&((struct ifreq
*)(void *)data
)->ifr_addr
,
1504 &addr
, sizeof(addr
));
1507 if (addr
.sin_family
!= AF_INET
&& cmd
== SIOCSIFADDR
) {
1512 ia
= in_ifaddr_alloc(M_WAITOK
);
1517 ifnet_lock_exclusive(ifp
);
1520 /* Hold a reference for this routine */
1521 IFA_ADDREF_LOCKED(ifa
);
1523 ifa
->ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1524 ifa
->ifa_dstaddr
= (struct sockaddr
*)&ia
->ia_dstaddr
;
1525 ifa
->ifa_netmask
= (struct sockaddr
*)&ia
->ia_sockmask
;
1526 ia
->ia_sockmask
.sin_len
= offsetof(struct sockaddr_in
, sin_zero
);
1527 if (ifp
->if_flags
& IFF_BROADCAST
) {
1528 ia
->ia_broadaddr
.sin_len
= sizeof(ia
->ia_addr
);
1529 ia
->ia_broadaddr
.sin_family
= AF_INET
;
1532 if (!(ifp
->if_flags
& IFF_LOOPBACK
)) {
1535 /* if_attach_ifa() holds a reference for ifa_link */
1536 if_attach_ifa(ifp
, ifa
);
1538 * If we have to go through in_ifinit(), make sure
1539 * to avoid installing route(s) based on this address
1540 * via PFC_IFUP event, before the link resolver (ARP)
1543 if (cmd
== SIOCAIFADDR
|| cmd
== SIOCSIFADDR
) {
1544 ifa
->ifa_debug
|= IFD_NOTREADY
;
1547 ifnet_lock_done(ifp
);
1548 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1549 /* Hold a reference for ia_link */
1551 TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
);
1552 lck_rw_done(in_ifaddr_rwlock
);
1554 (void) in_domifattach(ifp
);
1561 case SIOCGIFDSTADDR
: /* struct ifreq */
1562 case SIOCSIFDSTADDR
: /* struct ifreq */
1563 error
= inctl_ifdstaddr(ifp
, ia
, cmd
, ifr
);
1566 case SIOCGIFBRDADDR
: /* struct ifreq */
1567 case SIOCSIFBRDADDR
: /* struct ifreq */
1568 error
= inctl_ifbrdaddr(ifp
, ia
, cmd
, ifr
);
1571 case SIOCGIFNETMASK
: /* struct ifreq */
1572 case SIOCSIFNETMASK
: /* struct ifreq */
1573 error
= inctl_ifnetmask(ifp
, ia
, cmd
, ifr
);
1576 case SIOCGIFADDR
: /* struct ifreq */
1577 case SIOCSIFADDR
: /* struct ifreq */
1578 case SIOCAIFADDR
: /* struct {if,in_}aliasreq */
1579 case SIOCDIFADDR
: /* struct ifreq */
1580 error
= inctl_ifaddr(ifp
, ia
, cmd
, ifr
);
1590 if (cmd
== SIOCDIFADDR
) {
1591 IFA_LOCK(&ia
->ia_ifa
);
1592 ia
->ia_ifa
.ifa_debug
&= ~IFD_DETACHING
;
1593 if (ia
->ia_ifa
.ifa_del_waiters
> 0) {
1594 ia
->ia_ifa
.ifa_del_waiters
= 0;
1595 wakeup(ia
->ia_ifa
.ifa_del_wc
);
1597 IFA_UNLOCK(&ia
->ia_ifa
);
1599 IFA_REMREF(&ia
->ia_ifa
);
1609 * Delete any existing route for an interface.
1612 in_ifscrub(struct ifnet
*ifp
, struct in_ifaddr
*ia
, int locked
)
1614 IFA_LOCK(&ia
->ia_ifa
);
1615 if ((ia
->ia_flags
& IFA_ROUTE
) == 0) {
1616 IFA_UNLOCK(&ia
->ia_ifa
);
1619 IFA_UNLOCK(&ia
->ia_ifa
);
1621 lck_mtx_lock(rnh_lock
);
1623 if (ifp
->if_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)) {
1624 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
);
1626 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0);
1628 IFA_LOCK(&ia
->ia_ifa
);
1629 ia
->ia_flags
&= ~IFA_ROUTE
;
1630 IFA_UNLOCK(&ia
->ia_ifa
);
1632 lck_mtx_unlock(rnh_lock
);
1637 * Caller must hold in_ifaddr_rwlock as writer.
1640 in_iahash_remove(struct in_ifaddr
*ia
)
1642 LCK_RW_ASSERT(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1643 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1645 if (!IA_IS_HASHED(ia
)) {
1646 panic("attempt to remove wrong ia %p from hash table\n", ia
);
1649 TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
);
1651 if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) {
1652 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
,
1659 * Caller must hold in_ifaddr_rwlock as writer.
1662 in_iahash_insert(struct in_ifaddr
*ia
)
1664 LCK_RW_ASSERT(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1665 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1667 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1668 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1670 } else if (IA_IS_HASHED(ia
)) {
1671 panic("attempt to double-insert ia %p into hash table\n", ia
);
1674 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1676 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1680 * Some point to point interfaces that are tunnels borrow the address from
1681 * an underlying interface (e.g. VPN server). In order for source address
1682 * selection logic to find the underlying interface first, we add the address
1683 * of borrowing point to point interfaces at the end of the list.
1684 * (see rdar://6733789)
1686 * Caller must hold in_ifaddr_rwlock as writer.
1689 in_iahash_insert_ptp(struct in_ifaddr
*ia
)
1691 struct in_ifaddr
*tmp_ifa
;
1692 struct ifnet
*tmp_ifp
;
1694 LCK_RW_ASSERT(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
);
1695 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1697 if (ia
->ia_addr
.sin_family
!= AF_INET
) {
1698 panic("attempt to insert wrong ia %p into hash table\n", ia
);
1700 } else if (IA_IS_HASHED(ia
)) {
1701 panic("attempt to double-insert ia %p into hash table\n", ia
);
1704 IFA_UNLOCK(&ia
->ia_ifa
);
1705 TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1707 IFA_LOCK(&tmp_ifa
->ia_ifa
);
1708 /* ia->ia_addr won't change, so check without lock */
1709 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr
==
1710 ia
->ia_addr
.sin_addr
.s_addr
) {
1711 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1714 IFA_UNLOCK(&tmp_ifa
->ia_ifa
);
1716 tmp_ifp
= (tmp_ifa
== NULL
) ? NULL
: tmp_ifa
->ia_ifp
;
1718 IFA_LOCK(&ia
->ia_ifa
);
1719 if (tmp_ifp
== NULL
) {
1720 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1723 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
),
1726 IFA_ADDREF_LOCKED(&ia
->ia_ifa
);
1730 * Initialize an interface's internet address
1731 * and routing table entry.
1734 in_ifinit(struct ifnet
*ifp
, struct in_ifaddr
*ia
, struct sockaddr_in
*sin
,
1737 u_int32_t i
= ntohl(sin
->sin_addr
.s_addr
);
1738 struct sockaddr_in oldaddr
;
1739 int flags
= RTF_UP
, error
;
1740 struct ifaddr
*ifa0
;
1744 /* Take an extra reference for this routine */
1745 IFA_ADDREF(&ia
->ia_ifa
);
1747 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1748 IFA_LOCK(&ia
->ia_ifa
);
1749 oldaddr
= ia
->ia_addr
;
1750 if (IA_IS_HASHED(ia
)) {
1752 in_iahash_remove(ia
);
1756 * Interface addresses should not contain port or sin_zero information.
1758 SIN(&ia
->ia_addr
)->sin_family
= AF_INET
;
1759 SIN(&ia
->ia_addr
)->sin_len
= sizeof(struct sockaddr_in
);
1760 SIN(&ia
->ia_addr
)->sin_port
= 0;
1761 bzero(&SIN(&ia
->ia_addr
)->sin_zero
, sizeof(sin
->sin_zero
));
1762 if ((ifp
->if_flags
& IFF_POINTOPOINT
)) {
1763 in_iahash_insert_ptp(ia
);
1765 in_iahash_insert(ia
);
1767 IFA_UNLOCK(&ia
->ia_ifa
);
1768 lck_rw_done(in_ifaddr_rwlock
);
1771 * Give the interface a chance to initialize if this is its first
1772 * address, and to validate the address if necessary. Send down
1773 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1774 * We find the first IPV4 address assigned to it and check if this
1775 * is the same as the one passed into this routine.
1777 ifa0
= ifa_ifpgetprimary(ifp
, AF_INET
);
1778 cmd
= (&ia
->ia_ifa
== ifa0
) ? SIOCSIFADDR
: SIOCAIFADDR
;
1779 error
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
);
1780 if (error
== EOPNOTSUPP
) {
1784 * If we've just sent down SIOCAIFADDR, send another ioctl down
1785 * for SIOCSIFADDR for the first IPV4 address of the interface,
1786 * because an address change on one of the addresses will result
1787 * in the removal of the previous first IPV4 address. KDP needs
1788 * be reconfigured with the current primary IPV4 address.
1790 if (error
== 0 && cmd
== SIOCAIFADDR
) {
1792 * NOTE: SIOCSIFADDR is defined with struct ifreq
1793 * as parameter, but here we are sending it down
1794 * to the interface with a pointer to struct ifaddr,
1795 * for legacy reasons.
1797 error
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
);
1798 if (error
== EOPNOTSUPP
) {
1803 /* Release reference from ifa_ifpgetprimary() */
1807 lck_rw_lock_exclusive(in_ifaddr_rwlock
);
1808 IFA_LOCK(&ia
->ia_ifa
);
1809 if (IA_IS_HASHED(ia
)) {
1810 in_iahash_remove(ia
);
1812 ia
->ia_addr
= oldaddr
;
1814 if ((ifp
->if_flags
& IFF_POINTOPOINT
)) {
1815 in_iahash_insert_ptp(ia
);
1817 in_iahash_insert(ia
);
1820 IFA_UNLOCK(&ia
->ia_ifa
);
1821 lck_rw_done(in_ifaddr_rwlock
);
1822 /* Release extra reference taken above */
1823 IFA_REMREF(&ia
->ia_ifa
);
1826 lck_mtx_lock(rnh_lock
);
1827 IFA_LOCK(&ia
->ia_ifa
);
1829 * Address has been initialized by the link resolver (ARP)
1830 * via ifnet_ioctl() above; it may now generate route(s).
1832 ia
->ia_ifa
.ifa_debug
&= ~IFD_NOTREADY
;
1834 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&oldaddr
;
1835 IFA_UNLOCK(&ia
->ia_ifa
);
1836 in_ifscrub(ifp
, ia
, 1);
1837 IFA_LOCK(&ia
->ia_ifa
);
1838 ia
->ia_ifa
.ifa_addr
= (struct sockaddr
*)&ia
->ia_addr
;
1840 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
);
1842 ia
->ia_netmask
= IN_CLASSA_NET
;
1843 } else if (IN_CLASSB(i
)) {
1844 ia
->ia_netmask
= IN_CLASSB_NET
;
1846 ia
->ia_netmask
= IN_CLASSC_NET
;
1849 * The subnet mask usually includes at least the standard network part,
1850 * but may may be smaller in the case of supernetting.
1851 * If it is set, we believe it.
1853 if (ia
->ia_subnetmask
== 0) {
1854 ia
->ia_subnetmask
= ia
->ia_netmask
;
1855 ia
->ia_sockmask
.sin_addr
.s_addr
= htonl(ia
->ia_subnetmask
);
1857 ia
->ia_netmask
&= ia
->ia_subnetmask
;
1859 ia
->ia_net
= i
& ia
->ia_netmask
;
1860 ia
->ia_subnet
= i
& ia
->ia_subnetmask
;
1861 in_socktrim(&ia
->ia_sockmask
);
1863 * Add route for the network.
1865 ia
->ia_ifa
.ifa_metric
= ifp
->if_metric
;
1866 if (ifp
->if_flags
& IFF_BROADCAST
) {
1867 ia
->ia_broadaddr
.sin_addr
.s_addr
=
1868 htonl(ia
->ia_subnet
| ~ia
->ia_subnetmask
);
1869 ia
->ia_netbroadcast
.s_addr
=
1870 htonl(ia
->ia_net
| ~ia
->ia_netmask
);
1871 } else if (ifp
->if_flags
& IFF_LOOPBACK
) {
1872 ia
->ia_ifa
.ifa_dstaddr
= ia
->ia_ifa
.ifa_addr
;
1874 } else if (ifp
->if_flags
& IFF_POINTOPOINT
) {
1875 if (ia
->ia_dstaddr
.sin_family
!= AF_INET
) {
1876 IFA_UNLOCK(&ia
->ia_ifa
);
1877 lck_mtx_unlock(rnh_lock
);
1878 /* Release extra reference taken above */
1879 IFA_REMREF(&ia
->ia_ifa
);
1882 ia
->ia_dstaddr
.sin_len
= sizeof(struct sockaddr_in
);
1885 IFA_UNLOCK(&ia
->ia_ifa
);
1887 if ((error
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) {
1888 IFA_LOCK(&ia
->ia_ifa
);
1889 ia
->ia_flags
|= IFA_ROUTE
;
1890 IFA_UNLOCK(&ia
->ia_ifa
);
1892 lck_mtx_unlock(rnh_lock
);
1894 /* XXX check if the subnet route points to the same interface */
1895 if (error
== EEXIST
) {
1900 * If the interface supports multicast, join the "all hosts"
1901 * multicast group on that interface.
1903 if (ifp
->if_flags
& IFF_MULTICAST
) {
1904 struct in_addr addr
;
1906 lck_mtx_lock(&ifp
->if_addrconfig_lock
);
1907 addr
.s_addr
= htonl(INADDR_ALLHOSTS_GROUP
);
1908 if (ifp
->if_allhostsinm
== NULL
) {
1909 struct in_multi
*inm
;
1910 inm
= in_addmulti(&addr
, ifp
);
1914 * Keep the reference on inm added by
1915 * in_addmulti above for storing the
1916 * pointer in allhostsinm.
1918 ifp
->if_allhostsinm
= inm
;
1920 printf("%s: failed to add membership to "
1921 "all-hosts multicast address on %s\n",
1922 __func__
, if_name(ifp
));
1925 lck_mtx_unlock(&ifp
->if_addrconfig_lock
);
1928 /* Release extra reference taken above */
1929 IFA_REMREF(&ia
->ia_ifa
);
1932 /* invalidate route caches */
1933 routegenid_inet_update();
1940 * Return TRUE if the address might be a local broadcast address.
1943 in_broadcast(struct in_addr in
, struct ifnet
*ifp
)
1948 if (in
.s_addr
== INADDR_BROADCAST
|| in
.s_addr
== INADDR_ANY
) {
1951 if (!(ifp
->if_flags
& IFF_BROADCAST
)) {
1954 t
= ntohl(in
.s_addr
);
1957 * Look through the list of addresses for a match
1958 * with a broadcast address.
1960 #define ia ((struct in_ifaddr *)ifa)
1961 ifnet_lock_shared(ifp
);
1962 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) {
1964 if (ifa
->ifa_addr
->sa_family
== AF_INET
&&
1965 (in
.s_addr
== ia
->ia_broadaddr
.sin_addr
.s_addr
||
1966 in
.s_addr
== ia
->ia_netbroadcast
.s_addr
||
1968 * Check for old-style (host 0) broadcast.
1970 t
== ia
->ia_subnet
|| t
== ia
->ia_net
) &&
1972 * Check for an all one subnetmask. These
1973 * only exist when an interface gets a secondary
1976 ia
->ia_subnetmask
!= (u_int32_t
)0xffffffff) {
1978 ifnet_lock_done(ifp
);
1983 ifnet_lock_done(ifp
);
1989 in_purgeaddrs(struct ifnet
*ifp
)
1991 struct ifaddr
**ifap
;
1994 VERIFY(ifp
!= NULL
);
1997 * Be nice, and try the civilized way first. If we can't get
1998 * rid of them this way, then do it the rough way. We must
1999 * only get here during detach time, after the ifnet has been
2000 * removed from the global list and arrays.
2002 err
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1,
2004 if (err
== 0 && ifap
!= NULL
) {
2007 bzero(&ifr
, sizeof(ifr
));
2008 (void) snprintf(ifr
.ifr_name
, sizeof(ifr
.ifr_name
),
2009 "%s", if_name(ifp
));
2011 for (i
= 0; ifap
[i
] != NULL
; i
++) {
2016 bcopy(ifa
->ifa_addr
, &ifr
.ifr_addr
,
2017 sizeof(struct sockaddr_in
));
2019 err
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
,
2021 /* if we lost the race, ignore it */
2022 if (err
== EADDRNOTAVAIL
) {
2026 char s_addr
[MAX_IPv4_STR_LEN
];
2027 char s_dstaddr
[MAX_IPv4_STR_LEN
];
2028 struct in_addr
*s
, *d
;
2031 s
= &((struct sockaddr_in
*)
2032 (void *)ifa
->ifa_addr
)->sin_addr
;
2033 d
= &((struct sockaddr_in
*)
2034 (void *)ifa
->ifa_dstaddr
)->sin_addr
;
2035 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
,
2037 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
,
2041 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s "
2042 "ifa_dstaddr=%s (err=%d)\n", __func__
,
2043 ifp
->if_xname
, s_addr
, s_dstaddr
, err
);
2046 ifnet_free_address_list(ifap
);
2047 } else if (err
!= 0 && err
!= ENXIO
) {
2048 printf("%s: error retrieving list of AF_INET addresses for "
2049 "ifp=%s (err=%d)\n", __func__
, ifp
->if_xname
, err
);
2054 * Called as part of ip_init
2057 in_ifaddr_init(void)
2061 PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof(inifa_debug
));
2063 inifa_size
= (inifa_debug
== 0) ? sizeof(struct in_ifaddr
) :
2064 sizeof(struct in_ifaddr_dbg
);
2066 inifa_zone
= zone_create(INIFA_ZONE_NAME
, inifa_size
, ZC_NONE
);
2068 lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
);
2069 TAILQ_INIT(&inifa_trash_head
);
2072 static struct in_ifaddr
*
2073 in_ifaddr_alloc(int how
)
2075 struct in_ifaddr
*inifa
;
2077 inifa
= (how
== M_WAITOK
) ? zalloc(inifa_zone
) :
2078 zalloc_noblock(inifa_zone
);
2079 if (inifa
!= NULL
) {
2080 bzero(inifa
, inifa_size
);
2081 inifa
->ia_ifa
.ifa_free
= in_ifaddr_free
;
2082 inifa
->ia_ifa
.ifa_debug
|= IFD_ALLOC
;
2083 inifa
->ia_ifa
.ifa_del_wc
= &inifa
->ia_ifa
.ifa_debug
;
2084 inifa
->ia_ifa
.ifa_del_waiters
= 0;
2085 ifa_lock_init(&inifa
->ia_ifa
);
2086 if (inifa_debug
!= 0) {
2087 struct in_ifaddr_dbg
*inifa_dbg
=
2088 (struct in_ifaddr_dbg
*)inifa
;
2089 inifa
->ia_ifa
.ifa_debug
|= IFD_DEBUG
;
2090 inifa
->ia_ifa
.ifa_trace
= in_ifaddr_trace
;
2091 inifa
->ia_ifa
.ifa_attached
= in_ifaddr_attached
;
2092 inifa
->ia_ifa
.ifa_detached
= in_ifaddr_detached
;
2093 ctrace_record(&inifa_dbg
->inifa_alloc
);
2100 in_ifaddr_free(struct ifaddr
*ifa
)
2102 IFA_LOCK_ASSERT_HELD(ifa
);
2104 if (ifa
->ifa_refcnt
!= 0) {
2105 panic("%s: ifa %p bad ref cnt", __func__
, ifa
);
2108 if (!(ifa
->ifa_debug
& IFD_ALLOC
)) {
2109 panic("%s: ifa %p cannot be freed", __func__
, ifa
);
2112 if (ifa
->ifa_debug
& IFD_DEBUG
) {
2113 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2114 ctrace_record(&inifa_dbg
->inifa_free
);
2115 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
,
2116 sizeof(struct in_ifaddr
));
2117 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2118 /* Become a regular mutex, just in case */
2119 IFA_CONVERT_LOCK(ifa
);
2120 lck_mtx_lock(&inifa_trash_lock
);
2121 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
,
2123 lck_mtx_unlock(&inifa_trash_lock
);
2124 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2128 ifa_lock_destroy(ifa
);
2129 bzero(ifa
, sizeof(struct in_ifaddr
));
2130 zfree(inifa_zone
, ifa
);
2134 in_ifaddr_attached(struct ifaddr
*ifa
)
2136 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2138 IFA_LOCK_ASSERT_HELD(ifa
);
2140 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2141 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2144 if (ifa
->ifa_debug
& IFD_TRASHED
) {
2145 /* Become a regular mutex, just in case */
2146 IFA_CONVERT_LOCK(ifa
);
2147 lck_mtx_lock(&inifa_trash_lock
);
2148 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2149 lck_mtx_unlock(&inifa_trash_lock
);
2150 ifa
->ifa_debug
&= ~IFD_TRASHED
;
2155 in_ifaddr_detached(struct ifaddr
*ifa
)
2157 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2159 IFA_LOCK_ASSERT_HELD(ifa
);
2161 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2162 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2164 } else if (ifa
->ifa_debug
& IFD_TRASHED
) {
2165 panic("%s: ifa %p is already in trash list", __func__
, ifa
);
2168 ifa
->ifa_debug
|= IFD_TRASHED
;
2169 /* Become a regular mutex, just in case */
2170 IFA_CONVERT_LOCK(ifa
);
2171 lck_mtx_lock(&inifa_trash_lock
);
2172 TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
);
2173 lck_mtx_unlock(&inifa_trash_lock
);
2177 in_ifaddr_trace(struct ifaddr
*ifa
, int refhold
)
2179 struct in_ifaddr_dbg
*inifa_dbg
= (struct in_ifaddr_dbg
*)ifa
;
2184 if (!(ifa
->ifa_debug
& IFD_DEBUG
)) {
2185 panic("%s: ifa %p has no debug structure", __func__
, ifa
);
2189 cnt
= &inifa_dbg
->inifa_refhold_cnt
;
2190 tr
= inifa_dbg
->inifa_refhold
;
2192 cnt
= &inifa_dbg
->inifa_refrele_cnt
;
2193 tr
= inifa_dbg
->inifa_refrele
;
2196 idx
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
;
2197 ctrace_record(&tr
[idx
]);
2201 * Handle SIOCGASSOCIDS ioctl for PF_INET domain.
2204 in_getassocids(struct socket
*so
, uint32_t *cnt
, user_addr_t aidp
)
2206 struct inpcb
*inp
= sotoinpcb(so
);
2209 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
) {
2213 /* INPCB has no concept of association */
2214 aid
= SAE_ASSOCID_ANY
;
2217 /* just asking how many there are? */
2218 if (aidp
== USER_ADDR_NULL
) {
2222 return copyout(&aid
, aidp
, sizeof(aid
));
2226 * Handle SIOCGCONNIDS ioctl for PF_INET domain.
2229 in_getconnids(struct socket
*so
, sae_associd_t aid
, uint32_t *cnt
,
2232 struct inpcb
*inp
= sotoinpcb(so
);
2235 if (inp
== NULL
|| inp
->inp_state
== INPCB_STATE_DEAD
) {
2239 if (aid
!= SAE_ASSOCID_ANY
&& aid
!= SAE_ASSOCID_ALL
) {
2243 /* if connected, return 1 connection count */
2244 *cnt
= ((so
->so_state
& SS_ISCONNECTED
) ? 1 : 0);
2246 /* just asking how many there are? */
2247 if (cidp
== USER_ADDR_NULL
) {
2251 /* if INPCB is connected, assign it connid 1 */
2252 cid
= ((*cnt
!= 0) ? 1 : SAE_CONNID_ANY
);
2254 return copyout(&cid
, cidp
, sizeof(cid
));
2258 * Handle SIOCGCONNINFO ioctl for PF_INET domain.
2261 in_getconninfo(struct socket
*so
, sae_connid_t cid
, uint32_t *flags
,
2262 uint32_t *ifindex
, int32_t *soerror
, user_addr_t src
, socklen_t
*src_len
,
2263 user_addr_t dst
, socklen_t
*dst_len
, uint32_t *aux_type
,
2264 user_addr_t aux_data
, uint32_t *aux_len
)
2266 struct inpcb
*inp
= sotoinpcb(so
);
2267 struct sockaddr_in sin
;
2268 struct ifnet
*ifp
= NULL
;
2270 u_int32_t copy_len
= 0;
2273 * Don't test for INPCB_STATE_DEAD since this may be called
2274 * after SOF_PCBCLEARING is set, e.g. after tcp_close().
2281 if (cid
!= SAE_CONNID_ANY
&& cid
!= SAE_CONNID_ALL
&& cid
!= 1) {
2286 ifp
= inp
->inp_last_outifp
;
2287 *ifindex
= ((ifp
!= NULL
) ? ifp
->if_index
: 0);
2288 *soerror
= so
->so_error
;
2290 if (so
->so_state
& SS_ISCONNECTED
) {
2291 *flags
|= (CIF_CONNECTED
| CIF_PREFERRED
);
2293 if (inp
->inp_flags
& INP_BOUND_IF
) {
2294 *flags
|= CIF_BOUND_IF
;
2296 if (!(inp
->inp_flags
& INP_INADDR_ANY
)) {
2297 *flags
|= CIF_BOUND_IP
;
2299 if (!(inp
->inp_flags
& INP_ANONPORT
)) {
2300 *flags
|= CIF_BOUND_PORT
;
2303 bzero(&sin
, sizeof(sin
));
2304 sin
.sin_len
= sizeof(sin
);
2305 sin
.sin_family
= AF_INET
;
2307 /* source address and port */
2308 sin
.sin_port
= inp
->inp_lport
;
2309 sin
.sin_addr
.s_addr
= inp
->inp_laddr
.s_addr
;
2310 if (*src_len
== 0) {
2311 *src_len
= sin
.sin_len
;
2313 if (src
!= USER_ADDR_NULL
) {
2314 copy_len
= min(*src_len
, sizeof(sin
));
2315 error
= copyout(&sin
, src
, copy_len
);
2319 *src_len
= copy_len
;
2323 /* destination address and port */
2324 sin
.sin_port
= inp
->inp_fport
;
2325 sin
.sin_addr
.s_addr
= inp
->inp_faddr
.s_addr
;
2326 if (*dst_len
== 0) {
2327 *dst_len
= sin
.sin_len
;
2329 if (dst
!= USER_ADDR_NULL
) {
2330 copy_len
= min(*dst_len
, sizeof(sin
));
2331 error
= copyout(&sin
, dst
, copy_len
);
2335 *dst_len
= copy_len
;
2339 if (SOCK_PROTO(so
) == IPPROTO_TCP
) {
2340 struct conninfo_tcp tcp_ci
;
2342 *aux_type
= CIAUX_TCP
;
2343 if (*aux_len
== 0) {
2344 *aux_len
= sizeof(tcp_ci
);
2346 if (aux_data
!= USER_ADDR_NULL
) {
2347 copy_len
= min(*aux_len
, sizeof(tcp_ci
));
2348 bzero(&tcp_ci
, sizeof(tcp_ci
));
2349 tcp_getconninfo(so
, &tcp_ci
);
2350 error
= copyout(&tcp_ci
, aux_data
, copy_len
);
2354 *aux_len
= copy_len
;
2367 struct llentry base
;
2370 #define IN_LLTBL_DEFAULT_HSIZE 32
2371 #define IN_LLTBL_HASH(k, h) \
2372 ((((((((k) >> 8) ^ (k)) >> 8) ^ (k)) >> 8) ^ (k)) & ((h) - 1))
2375 * Do actual deallocation of @lle.
2378 in_lltable_destroy_lle_unlocked(struct llentry
*lle
)
2380 LLE_LOCK_DESTROY(lle
);
2381 LLE_REQ_DESTROY(lle
);
2382 FREE(lle
, M_LLTABLE
);
2386 * Called by LLE_FREE_LOCKED when number of references
2390 in_lltable_destroy_lle(struct llentry
*lle
)
2393 in_lltable_destroy_lle_unlocked(lle
);
2396 static struct llentry
*
2397 in_lltable_new(struct in_addr addr4
, uint16_t flags
)
2399 #pragma unused(flags)
2400 struct in_llentry
*lle
;
2402 MALLOC(lle
, struct in_llentry
*, sizeof(struct in_llentry
), M_LLTABLE
, M_NOWAIT
| M_ZERO
);
2403 if (lle
== NULL
) { /* NB: caller generates msg */
2408 * For IPv4 this will trigger "arpresolve" to generate
2411 lle
->base
.la_expire
= net_uptime(); /* mark expired */
2412 lle
->base
.r_l3addr
.addr4
= addr4
;
2413 lle
->base
.lle_refcnt
= 1;
2414 lle
->base
.lle_free
= in_lltable_destroy_lle
;
2416 LLE_LOCK_INIT(&lle
->base
);
2417 LLE_REQ_INIT(&lle
->base
);
2418 //callout_init(&lle->base.lle_timer, 1);
2423 #define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
2424 ((((d).s_addr ^ (a).s_addr) & (m).s_addr)) == 0 )
2427 in_lltable_match_prefix(const struct sockaddr
*saddr
,
2428 const struct sockaddr
*smask
, uint16_t flags
, struct llentry
*lle
)
2430 struct in_addr addr
, mask
, lle_addr
;
2432 addr
= ((const struct sockaddr_in
*)(const void *)saddr
)->sin_addr
;
2433 mask
= ((const struct sockaddr_in
*)(const void *)smask
)->sin_addr
;
2434 lle_addr
.s_addr
= ntohl(lle
->r_l3addr
.addr4
.s_addr
);
2436 if (IN_ARE_MASKED_ADDR_EQUAL(lle_addr
, addr
, mask
) == 0) {
2440 if (lle
->la_flags
& LLE_IFADDR
) {
2442 * Delete LLE_IFADDR records IFF address & flag matches.
2443 * Note that addr is the interface address within prefix
2445 * Note also we should handle 'ifdown' cases without removing
2448 if (addr
.s_addr
== lle_addr
.s_addr
&& (flags
& LLE_STATIC
) != 0) {
2454 /* flags & LLE_STATIC means deleting both dynamic and static entries */
2455 if ((flags
& LLE_STATIC
) || !(lle
->la_flags
& LLE_STATIC
)) {
2463 in_lltable_free_entry(struct lltable
*llt
, struct llentry
*lle
)
2466 size_t pkts_dropped
;
2468 LLE_WLOCK_ASSERT(lle
);
2469 KASSERT(llt
!= NULL
, ("lltable is NULL"));
2471 /* Unlink entry from table if not already */
2472 if ((lle
->la_flags
& LLE_LINKED
) != 0) {
2474 IF_AFDATA_WLOCK_ASSERT(ifp
, llt
->llt_af
);
2475 lltable_unlink_entry(llt
, lle
);
2480 if (callout_stop(&lle
->lle_timer
) > 0) {
2484 /* Drop hold queue */
2485 pkts_dropped
= llentry_free(lle
);
2486 arpstat
.dropped
+= pkts_dropped
;
2491 in_lltable_rtcheck(struct ifnet
*ifp
, uint16_t flags
, const struct sockaddr
*l3addr
)
2493 #pragma unused(flags)
2496 KASSERT(l3addr
->sa_family
== AF_INET
,
2497 ("sin_family %d", l3addr
->sa_family
));
2499 /* XXX rtalloc1 should take a const param */
2500 rt
= rtalloc1(__DECONST(struct sockaddr
*, l3addr
), 0, 0);
2501 if (rt
== NULL
|| (rt
->rt_flags
& RTF_GATEWAY
) || rt
->rt_ifp
!= ifp
) {
2502 log(LOG_INFO
, "IPv4 address: \"%s\" is not on the network\n",
2503 inet_ntoa(((const struct sockaddr_in
*)(const void *)l3addr
)->sin_addr
));
2513 static inline uint32_t
2514 in_lltable_hash_dst(const struct in_addr dst
, uint32_t hsize
)
2516 return IN_LLTBL_HASH(dst
.s_addr
, hsize
);
2520 in_lltable_hash(const struct llentry
*lle
, uint32_t hsize
)
2522 return in_lltable_hash_dst(lle
->r_l3addr
.addr4
, hsize
);
2527 in_lltable_fill_sa_entry(const struct llentry
*lle
, struct sockaddr
*sa
)
2529 struct sockaddr_in
*sin
;
2531 sin
= (struct sockaddr_in
*)(void *)sa
;
2532 bzero(sin
, sizeof(*sin
));
2533 sin
->sin_family
= AF_INET
;
2534 sin
->sin_len
= sizeof(*sin
);
2535 sin
->sin_addr
= lle
->r_l3addr
.addr4
;
2538 static inline struct llentry
*
2539 in_lltable_find_dst(struct lltable
*llt
, struct in_addr dst
)
2541 struct llentry
*lle
;
2542 struct llentries
*lleh
;
2545 hashidx
= in_lltable_hash_dst(dst
, llt
->llt_hsize
);
2546 lleh
= &llt
->lle_head
[hashidx
];
2547 LIST_FOREACH(lle
, lleh
, lle_next
) {
2548 if (lle
->la_flags
& LLE_DELETED
) {
2551 if (lle
->r_l3addr
.addr4
.s_addr
== dst
.s_addr
) {
2560 in_lltable_delete_entry(struct lltable
*llt
, struct llentry
*lle
)
2563 lle
->la_flags
|= LLE_DELETED
;
2564 //EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
2566 log(LOG_INFO
, "ifaddr cache = %p is deleted\n", lle
);
2571 static struct llentry
*
2572 in_lltable_alloc(struct lltable
*llt
, uint16_t flags
, const struct sockaddr
*l3addr
)
2574 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*) (const void *)l3addr
;
2575 struct ifnet
*ifp
= llt
->llt_ifp
;
2576 struct llentry
*lle
;
2578 KASSERT(l3addr
->sa_family
== AF_INET
,
2579 ("sin_family %d", l3addr
->sa_family
));
2582 * A route that covers the given address must have
2583 * been installed 1st because we are doing a resolution,
2586 if (!(flags
& LLE_IFADDR
) &&
2587 in_lltable_rtcheck(ifp
, flags
, l3addr
) != 0) {
2591 lle
= in_lltable_new(sin
->sin_addr
, flags
);
2593 log(LOG_INFO
, "lla_lookup: new lle malloc failed\n");
2596 lle
->la_flags
= flags
& ~LLE_CREATE
;
2597 if (flags
& LLE_STATIC
) {
2598 lle
->r_flags
|= RLLE_VALID
;
2600 if ((flags
& LLE_IFADDR
) == LLE_IFADDR
) {
2601 lltable_set_entry_addr(ifp
, lle
, LLADDR(SDL(ifp
->if_lladdr
->ifa_addr
)));
2602 lle
->la_flags
|= LLE_STATIC
;
2603 lle
->r_flags
|= (RLLE_VALID
| RLLE_IFADDR
);
2609 * Return NULL if not found or marked for deletion.
2610 * If found return lle read locked.
2612 static struct llentry
*
2613 in_lltable_lookup(struct lltable
*llt
, uint16_t flags
, const struct sockaddr
*l3addr
)
2615 const struct sockaddr_in
*sin
= (const struct sockaddr_in
*)(const void *)l3addr
;
2616 struct llentry
*lle
;
2618 IF_AFDATA_WLOCK_ASSERT(llt
->llt_ifp
, llt
->llt_af
);
2620 KASSERT(l3addr
->sa_family
== AF_INET
,
2621 ("sin_family %d", l3addr
->sa_family
));
2622 lle
= in_lltable_find_dst(llt
, sin
->sin_addr
);
2628 KASSERT((flags
& (LLE_UNLOCKED
| LLE_EXCLUSIVE
)) !=
2629 (LLE_UNLOCKED
| LLE_EXCLUSIVE
), ("wrong lle request flags: 0x%X",
2632 if (flags
& LLE_UNLOCKED
) {
2636 if (flags
& LLE_EXCLUSIVE
) {
2646 in_lltable_dump_entry(struct lltable
*llt
, struct llentry
*lle
,
2647 struct sysctl_req
*wr
)
2649 struct ifnet
*ifp
= llt
->llt_ifp
;
2652 struct rt_msghdr rtm
;
2653 struct sockaddr_in sin
;
2654 struct sockaddr_dl sdl
;
2656 struct sockaddr_dl
*sdl
;
2659 bzero(&arpc
, sizeof(arpc
));
2660 /* skip deleted entries */
2661 if ((lle
->la_flags
& LLE_DELETED
) == LLE_DELETED
) {
2664 /* Skip if jailed and not a valid IP of the prison. */
2665 lltable_fill_sa_entry(lle
, (struct sockaddr
*)&arpc
.sin
);
2667 * produce a msg made of:
2669 * struct sockaddr_in; (IPv4)
2670 * struct sockaddr_dl;
2672 arpc
.rtm
.rtm_msglen
= sizeof(arpc
);
2673 arpc
.rtm
.rtm_version
= RTM_VERSION
;
2674 arpc
.rtm
.rtm_type
= RTM_GET
;
2675 arpc
.rtm
.rtm_flags
= RTF_UP
;
2676 arpc
.rtm
.rtm_addrs
= RTA_DST
| RTA_GATEWAY
;
2679 if (lle
->la_flags
& LLE_PUB
) {
2680 arpc
.rtm
.rtm_flags
|= RTF_ANNOUNCE
;
2684 sdl
->sdl_family
= AF_LINK
;
2685 sdl
->sdl_len
= sizeof(*sdl
);
2686 sdl
->sdl_index
= ifp
->if_index
;
2687 sdl
->sdl_type
= ifp
->if_type
;
2688 if ((lle
->la_flags
& LLE_VALID
) == LLE_VALID
) {
2689 sdl
->sdl_alen
= ifp
->if_addrlen
;
2690 bcopy(&lle
->ll_addr
, LLADDR(sdl
), ifp
->if_addrlen
);
2693 bzero(LLADDR(sdl
), ifp
->if_addrlen
);
2696 arpc
.rtm
.rtm_rmx
.rmx_expire
=
2697 lle
->la_flags
& LLE_STATIC
? 0 : (int32_t)lle
->la_expire
;
2698 arpc
.rtm
.rtm_flags
|= (RTF_HOST
| RTF_LLDATA
);
2699 if (lle
->la_flags
& LLE_STATIC
) {
2700 arpc
.rtm
.rtm_flags
|= RTF_STATIC
;
2702 if (lle
->la_flags
& LLE_IFADDR
) {
2703 arpc
.rtm
.rtm_flags
|= RTF_PINNED
;
2705 arpc
.rtm
.rtm_flags
|= RTF_PINNED
;
2706 arpc
.rtm
.rtm_index
= ifp
->if_index
;
2707 error
= SYSCTL_OUT(wr
, &arpc
, sizeof(arpc
));
2712 static struct lltable
*
2713 in_lltattach(struct ifnet
*ifp
)
2715 struct lltable
*llt
;
2717 llt
= lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE
);
2718 llt
->llt_af
= AF_INET
;
2721 llt
->llt_lookup
= in_lltable_lookup
;
2722 llt
->llt_alloc_entry
= in_lltable_alloc
;
2723 llt
->llt_delete_entry
= in_lltable_delete_entry
;
2724 llt
->llt_dump_entry
= in_lltable_dump_entry
;
2725 llt
->llt_hash
= in_lltable_hash
;
2726 llt
->llt_fill_sa_entry
= in_lltable_fill_sa_entry
;
2727 llt
->llt_free_entry
= in_lltable_free_entry
;
2728 llt
->llt_match_prefix
= in_lltable_match_prefix
;
2735 inifa_ifpwithflag(struct ifnet
* ifp
, uint32_t flag
)
2739 ifnet_lock_shared(ifp
);
2740 TAILQ_FOREACH(ifa
, &ifp
->if_addrlist
, ifa_link
)
2743 if (ifa
->ifa_addr
->sa_family
!= AF_INET
) {
2747 if ((((struct in_ifaddr
*)ifa
)->ia_flags
& flag
) == flag
) {
2748 IFA_ADDREF_LOCKED(ifa
);
2754 ifnet_lock_done(ifp
);
2756 return (struct in_ifaddr
*)ifa
;
2760 inifa_ifpclatv4(struct ifnet
* ifp
)
2764 ifnet_lock_shared(ifp
);
2765 TAILQ_FOREACH(ifa
, &ifp
->if_addrlist
, ifa_link
)
2769 if (ifa
->ifa_addr
->sa_family
!= AF_INET
) {
2774 addr
= ntohl(SIN(ifa
->ifa_addr
)->sin_addr
.s_addr
);
2775 if (!IN_LINKLOCAL(addr
) &&
2776 !IN_LOOPBACK(addr
)) {
2777 IFA_ADDREF_LOCKED(ifa
);
2783 ifnet_lock_done(ifp
);
2785 return (struct in_ifaddr
*)ifa
;