2  * Copyright (c) 2000-2016 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> 
  82 #include <net/if_types.h> 
  83 #include <net/route.h> 
  84 #include <net/kpi_protocol.h> 
  86 #include <net/if_llatbl.h> 
  87 #include <net/if_arp.h> 
  89 #include <net/pfvar.h> 
  92 #include <netinet/in.h> 
  93 #include <netinet/in_var.h> 
  94 #include <netinet/in_pcb.h> 
  95 #include <netinet/igmp_var.h> 
  96 #include <netinet/ip_var.h> 
  97 #include <netinet/tcp.h> 
  98 #include <netinet/tcp_timer.h> 
  99 #include <netinet/tcp_var.h> 
 100 #include <netinet/if_ether.h> 
 102 static int inctl_associd(struct socket 
*, u_long
, caddr_t
); 
 103 static int inctl_connid(struct socket 
*, u_long
, caddr_t
); 
 104 static int inctl_conninfo(struct socket 
*, u_long
, caddr_t
); 
 105 static int inctl_autoaddr(struct ifnet 
*, struct ifreq 
*); 
 106 static int inctl_arpipll(struct ifnet 
*, struct ifreq 
*); 
 107 static int inctl_setrouter(struct ifnet 
*, struct ifreq 
*); 
 108 static int inctl_ifaddr(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 110 static int inctl_ifdstaddr(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 112 static int inctl_ifbrdaddr(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 114 static int inctl_ifnetmask(struct ifnet 
*, struct in_ifaddr 
*, u_long
, 
 117 static void in_socktrim(struct sockaddr_in 
*); 
 118 static int in_ifinit(struct ifnet 
*, struct in_ifaddr 
*, 
 119     struct sockaddr_in 
*, int); 
 121 #define IA_HASH_INIT(ia) {                                      \ 
 122         (ia)->ia_hash.tqe_next = (void *)(uintptr_t)-1;         \ 
 123         (ia)->ia_hash.tqe_prev = (void *)(uintptr_t)-1;         \ 
 126 #define IA_IS_HASHED(ia)                                        \ 
 127         (!((ia)->ia_hash.tqe_next == (void *)(uintptr_t)-1 ||   \ 
 128         (ia)->ia_hash.tqe_prev == (void *)(uintptr_t)-1)) 
 130 static void in_iahash_remove(struct in_ifaddr 
*); 
 131 static void in_iahash_insert(struct in_ifaddr 
*); 
 132 static void in_iahash_insert_ptp(struct in_ifaddr 
*); 
 133 static struct in_ifaddr 
*in_ifaddr_alloc(int); 
 134 static void in_ifaddr_attached(struct ifaddr 
*); 
 135 static void in_ifaddr_detached(struct ifaddr 
*); 
 136 static void in_ifaddr_free(struct ifaddr 
*); 
 137 static void in_ifaddr_trace(struct ifaddr 
*, int); 
 139 static int in_getassocids(struct socket 
*, uint32_t *, user_addr_t
); 
 140 static int in_getconnids(struct socket 
*, sae_associd_t
, uint32_t *, user_addr_t
); 
 142 /* IPv4 Layer 2 neighbor cache management routines */ 
 143 static void in_lltable_destroy_lle_unlocked(struct llentry 
*lle
); 
 144 static void in_lltable_destroy_lle(struct llentry 
*lle
); 
 145 static struct llentry 
*in_lltable_new(struct in_addr addr4
, u_int flags
); 
 146 static int in_lltable_match_prefix(const struct sockaddr 
*saddr
, 
 147     const struct sockaddr 
*smask
, u_int flags
, struct llentry 
*lle
); 
 148 static void in_lltable_free_entry(struct lltable 
*llt
, struct llentry 
*lle
); 
 149 static int in_lltable_rtcheck(struct ifnet 
*ifp
, u_int flags
, const struct sockaddr 
*l3addr
); 
 150 static inline uint32_t in_lltable_hash_dst(const struct in_addr dst
, uint32_t hsize
); 
 151 static uint32_t in_lltable_hash(const struct llentry 
*lle
, uint32_t hsize
); 
 152 static void in_lltable_fill_sa_entry(const struct llentry 
*lle
, struct sockaddr 
*sa
); 
 153 static inline struct llentry 
* in_lltable_find_dst(struct lltable 
*llt
, struct in_addr dst
); 
 154 static void in_lltable_delete_entry(struct lltable 
*llt
, struct llentry 
*lle
); 
 155 static struct llentry 
* in_lltable_alloc(struct lltable 
*llt
, u_int flags
, const struct sockaddr 
*l3addr
); 
 156 static struct llentry 
* in_lltable_lookup(struct lltable 
*llt
, u_int flags
, const struct sockaddr 
*l3addr
); 
 157 static int in_lltable_dump_entry(struct lltable 
*llt
, struct llentry 
*lle
, struct sysctl_req 
*wr
); 
 158 static struct lltable 
* in_lltattach(struct ifnet 
*ifp
); 
 160 static int subnetsarelocal 
= 0; 
 161 SYSCTL_INT(_net_inet_ip
, OID_AUTO
, subnets_are_local
, 
 162         CTLFLAG_RW 
| CTLFLAG_LOCKED
, &subnetsarelocal
, 0, ""); 
 164 /* Track whether or not the SIOCARPIPLL ioctl has been called */ 
 165 u_int32_t ipv4_ll_arp_aware 
= 0; 
 167 #define INIFA_TRACE_HIST_SIZE   32      /* size of trace history */ 
 170 __private_extern__ 
unsigned int inifa_trace_hist_size 
= INIFA_TRACE_HIST_SIZE
; 
 172 struct in_ifaddr_dbg 
{ 
 173         struct in_ifaddr        inifa
;                  /* in_ifaddr */ 
 174         struct in_ifaddr        inifa_old
;              /* saved in_ifaddr */ 
 175         u_int16_t               inifa_refhold_cnt
;      /* # of IFA_ADDREF */ 
 176         u_int16_t               inifa_refrele_cnt
;      /* # of IFA_REMREF */ 
 178          * Alloc and free callers. 
 180         ctrace_t                inifa_alloc
; 
 183          * Circular lists of IFA_ADDREF and IFA_REMREF callers. 
 185         ctrace_t                inifa_refhold
[INIFA_TRACE_HIST_SIZE
]; 
 186         ctrace_t                inifa_refrele
[INIFA_TRACE_HIST_SIZE
]; 
 190         TAILQ_ENTRY(in_ifaddr_dbg
) inifa_trash_link
; 
 193 /* List of trash in_ifaddr entries protected by inifa_trash_lock */ 
 194 static TAILQ_HEAD(, in_ifaddr_dbg
) inifa_trash_head
; 
 195 static decl_lck_mtx_data(, inifa_trash_lock
); 
 198 static unsigned int inifa_debug 
= 1;            /* debugging (enabled) */ 
 200 static unsigned int inifa_debug
;                /* debugging (disabled) */ 
 202 static unsigned int inifa_size
;                 /* size of zone element */ 
 203 static struct zone 
*inifa_zone
;                 /* zone for in_ifaddr */ 
 205 #define INIFA_ZONE_MAX          64              /* maximum elements in zone */ 
 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
)) 
 246                         local 
= in_localaddr(in
); 
 253  * Return 1 if an internet address is for a ``local'' host 
 254  * (one to which we have a connection).  If subnetsarelocal 
 255  * is true, this includes other subnets of the local net, 
 256  * otherwise, it includes the directly-connected (sub)nets. 
 257  * The IPv4 link local prefix 169.254/16 is also included. 
 260 in_localaddr(struct in_addr in
) 
 262         u_int32_t i 
= ntohl(in
.s_addr
); 
 263         struct in_ifaddr 
*ia
; 
 268         if (subnetsarelocal
) { 
 269                 lck_rw_lock_shared(in_ifaddr_rwlock
); 
 270                 for (ia 
= in_ifaddrhead
.tqh_first
; ia 
!= NULL
; 
 271                     ia 
= ia
->ia_link
.tqe_next
) { 
 272                         IFA_LOCK(&ia
->ia_ifa
); 
 273                         if ((i 
& ia
->ia_netmask
) == ia
->ia_net
) { 
 274                                 IFA_UNLOCK(&ia
->ia_ifa
); 
 275                                 lck_rw_done(in_ifaddr_rwlock
); 
 278                         IFA_UNLOCK(&ia
->ia_ifa
); 
 280                 lck_rw_done(in_ifaddr_rwlock
); 
 282                 lck_rw_lock_shared(in_ifaddr_rwlock
); 
 283                 for (ia 
= in_ifaddrhead
.tqh_first
; ia 
!= NULL
; 
 284                     ia 
= ia
->ia_link
.tqe_next
) { 
 285                         IFA_LOCK(&ia
->ia_ifa
); 
 286                         if ((i 
& ia
->ia_subnetmask
) == ia
->ia_subnet
) { 
 287                                 IFA_UNLOCK(&ia
->ia_ifa
); 
 288                                 lck_rw_done(in_ifaddr_rwlock
); 
 291                         IFA_UNLOCK(&ia
->ia_ifa
); 
 293                 lck_rw_done(in_ifaddr_rwlock
); 
 299  * Determine whether an IP address is in a reserved set of addresses 
 300  * that may not be forwarded, or whether datagrams to that destination 
 304 in_canforward(struct in_addr in
) 
 306         u_int32_t i 
= ntohl(in
.s_addr
); 
 309         if (IN_EXPERIMENTAL(i
) || IN_MULTICAST(i
)) 
 312                 net 
= i 
& IN_CLASSA_NET
; 
 313                 if (net 
== 0 || net 
== (IN_LOOPBACKNET 
<< IN_CLASSA_NSHIFT
)) 
 320  * Trim a mask in a sockaddr 
 323 in_socktrim(struct sockaddr_in 
*ap
) 
 325         char *cplim 
= (char *)&ap
->sin_addr
; 
 326         char *cp 
= (char *)(&ap
->sin_addr 
+ 1); 
 329         while (--cp 
>= cplim
) 
 331                         (ap
)->sin_len 
= cp 
- (char *)(ap
) + 1; 
 336 static int in_interfaces
;       /* number of external internet interfaces */ 
 339 in_domifattach(struct ifnet 
*ifp
) 
 345         if ((error 
= proto_plumb(PF_INET
, ifp
)) && error 
!= EEXIST
) { 
 346                 log(LOG_ERR
, "%s: proto_plumb returned %d if=%s\n", 
 347                     __func__
, error
, if_name(ifp
)); 
 348         } else if (error 
== 0 && ifp
->if_inetdata 
== NULL
) { 
 350                 struct in_ifextra 
*ext
; 
 353                 if ((ext 
= (struct in_ifextra 
*)_MALLOC(in_extra_bufsize
, 
 354                     M_IFADDR
, M_WAITOK
|M_ZERO
)) == NULL
) { 
 356                         errorx 
= proto_unplumb(PF_INET
, ifp
); 
 359                                     "%s: proto_unplumb returned %d if=%s%d\n", 
 360                                     __func__
, errorx
, ifp
->if_name
, 
 366                 /* Align on 64-bit boundary */ 
 367                 base 
= (void *)P2ROUNDUP((intptr_t)ext 
+ sizeof (uint64_t), 
 369                 VERIFY(((intptr_t)base 
+ in_extra_size
) <= 
 370                     ((intptr_t)ext 
+ in_extra_bufsize
)); 
 371                 pbuf 
= (void **)((intptr_t)base 
- sizeof (void *)); 
 373                 ifp
->if_inetdata 
= base
; 
 374                 IN_IFEXTRA(ifp
)->ii_llt 
= in_lltattach(ifp
); 
 375                 VERIFY(IS_P2ALIGNED(ifp
->if_inetdata
, sizeof (uint64_t))); 
 378         if (error 
== 0 && ifp
->if_inetdata 
!= NULL
) { 
 380                  * Since the structure is never freed, we need to 
 381                  * zero out its contents to avoid reusing stale data. 
 382                  * A little redundant with allocation above, but it 
 383                  * keeps the code simpler for all cases. 
 385                 bzero(ifp
->if_inetdata
, in_extra_size
); 
 390 static __attribute__((noinline
)) int 
 391 inctl_associd(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 395                 struct so_aidreq32 a32
; 
 396                 struct so_aidreq64 a64
; 
 402         case SIOCGASSOCIDS32
:           /* struct so_aidreq32 */ 
 403                 bcopy(data
, &u
.a32
, sizeof (u
.a32
)); 
 404                 error 
= in_getassocids(so
, &u
.a32
.sar_cnt
, u
.a32
.sar_aidp
); 
 406                         bcopy(&u
.a32
, data
, sizeof (u
.a32
)); 
 409         case SIOCGASSOCIDS64
:           /* struct so_aidreq64 */ 
 410                 bcopy(data
, &u
.a64
, sizeof (u
.a64
)); 
 411                 error 
= in_getassocids(so
, &u
.a64
.sar_cnt
, u
.a64
.sar_aidp
); 
 413                         bcopy(&u
.a64
, data
, sizeof (u
.a64
)); 
 424 static __attribute__((noinline
)) int 
 425 inctl_connid(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 429                 struct so_cidreq32 c32
; 
 430                 struct so_cidreq64 c64
; 
 436         case SIOCGCONNIDS32
:            /* struct so_cidreq32 */ 
 437                 bcopy(data
, &u
.c32
, sizeof (u
.c32
)); 
 438                 error 
= in_getconnids(so
, u
.c32
.scr_aid
, &u
.c32
.scr_cnt
, 
 441                         bcopy(&u
.c32
, data
, sizeof (u
.c32
)); 
 444         case SIOCGCONNIDS64
:            /* struct so_cidreq64 */ 
 445                 bcopy(data
, &u
.c64
, sizeof (u
.c64
)); 
 446                 error 
= in_getconnids(so
, u
.c64
.scr_aid
, &u
.c64
.scr_cnt
, 
 449                         bcopy(&u
.c64
, data
, sizeof (u
.c64
)); 
 460 static __attribute__((noinline
)) int 
 461 inctl_conninfo(struct socket 
*so
, u_long cmd
, caddr_t data
) 
 465                 struct so_cinforeq32 ci32
; 
 466                 struct so_cinforeq64 ci64
; 
 472         case SIOCGCONNINFO32
:           /* struct so_cinforeq32 */ 
 473                 bcopy(data
, &u
.ci32
, sizeof (u
.ci32
)); 
 474                 error 
= in_getconninfo(so
, u
.ci32
.scir_cid
, &u
.ci32
.scir_flags
, 
 475                     &u
.ci32
.scir_ifindex
, &u
.ci32
.scir_error
, u
.ci32
.scir_src
, 
 476                     &u
.ci32
.scir_src_len
, u
.ci32
.scir_dst
, &u
.ci32
.scir_dst_len
, 
 477                     &u
.ci32
.scir_aux_type
, u
.ci32
.scir_aux_data
, 
 478                     &u
.ci32
.scir_aux_len
); 
 480                         bcopy(&u
.ci32
, data
, sizeof (u
.ci32
)); 
 483         case SIOCGCONNINFO64
:           /* struct so_cinforeq64 */ 
 484                 bcopy(data
, &u
.ci64
, sizeof (u
.ci64
)); 
 485                 error 
= in_getconninfo(so
, u
.ci64
.scir_cid
, &u
.ci64
.scir_flags
, 
 486                     &u
.ci64
.scir_ifindex
, &u
.ci64
.scir_error
, u
.ci64
.scir_src
, 
 487                     &u
.ci64
.scir_src_len
, u
.ci64
.scir_dst
, &u
.ci64
.scir_dst_len
, 
 488                     &u
.ci64
.scir_aux_type
, u
.ci64
.scir_aux_data
, 
 489                     &u
.ci64
.scir_aux_len
); 
 491                         bcopy(&u
.ci64
, data
, sizeof (u
.ci64
)); 
 503  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 504  * expectation that this routine always uses bcopy() or other byte-aligned 
 507 static __attribute__((noinline
)) int 
 508 inctl_autoaddr(struct ifnet 
*ifp
, struct ifreq 
*ifr
) 
 510         int error 
= 0, intval
; 
 514         bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
)); 
 516         ifnet_lock_exclusive(ifp
); 
 519                  * An interface in IPv4 router mode implies that it 
 520                  * is configured with a static IP address and should 
 521                  * not act as a DHCP client; prevent SIOCAUTOADDR from 
 522                  * being set in that mode. 
 524                 if (ifp
->if_eflags 
& IFEF_IPV4_ROUTER
) { 
 525                         intval 
= 0;     /* be safe; clear flag if set */ 
 528                         ifp
->if_eflags 
|= IFEF_AUTOCONFIGURING
; 
 532                 ifp
->if_eflags 
&= ~IFEF_AUTOCONFIGURING
; 
 533         ifnet_lock_done(ifp
); 
 539  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 540  * expectation that this routine always uses bcopy() or other byte-aligned 
 543 static __attribute__((noinline
)) int 
 544 inctl_arpipll(struct ifnet 
*ifp
, struct ifreq 
*ifr
) 
 546         int error 
= 0, intval
; 
 550         bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
)); 
 551         ipv4_ll_arp_aware 
= 1; 
 553         ifnet_lock_exclusive(ifp
); 
 556                  * An interface in IPv4 router mode implies that it 
 557                  * is configured with a static IP address and should 
 558                  * not have to deal with IPv4 Link-Local Address; 
 559                  * prevent SIOCARPIPLL from being set in that mode. 
 561                 if (ifp
->if_eflags 
& IFEF_IPV4_ROUTER
) { 
 562                         intval 
= 0;     /* be safe; clear flag if set */ 
 565                         ifp
->if_eflags 
|= IFEF_ARPLL
; 
 569                 ifp
->if_eflags 
&= ~IFEF_ARPLL
; 
 570         ifnet_lock_done(ifp
); 
 576  * Handle SIOCSETROUTERMODE to set or clear the IPv4 router mode flag on 
 577  * the interface.  When in this mode, IPv4 Link-Local Address support is 
 578  * disabled in ARP, and DHCP client support is disabled in IP input; turning 
 579  * any of them on would cause an error to be returned.  Entering or exiting 
 580  * this mode will result in the removal of IPv4 addresses currently configured 
 583  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 584  * expectation that this routine always uses bcopy() or other byte-aligned 
 587 static __attribute__((noinline
)) int 
 588 inctl_setrouter(struct ifnet 
*ifp
, struct ifreq 
*ifr
) 
 590         int error 
= 0, intval
; 
 594         /* Router mode isn't valid for loopback */ 
 595         if (ifp
->if_flags 
& IFF_LOOPBACK
) 
 598         bcopy(&ifr
->ifr_intval
, &intval
, sizeof (intval
)); 
 600         ifnet_lock_exclusive(ifp
); 
 602                 ifp
->if_eflags 
|= IFEF_IPV4_ROUTER
; 
 603                 ifp
->if_eflags 
&= ~(IFEF_ARPLL 
| IFEF_AUTOCONFIGURING
); 
 605                 ifp
->if_eflags 
&= ~IFEF_IPV4_ROUTER
; 
 607         ifnet_lock_done(ifp
); 
 609         /* purge all IPv4 addresses configured on this interface */ 
 616  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 617  * expectation that this routine always uses bcopy() or other byte-aligned 
 620 static __attribute__((noinline
)) int 
 621 inctl_ifaddr(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
 624         struct kev_in_data in_event_data
; 
 625         struct kev_msg ev_msg
; 
 626         struct sockaddr_in addr
; 
 632         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
 633         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
 636         case SIOCGIFADDR
:               /* struct ifreq */ 
 638                         error 
= EADDRNOTAVAIL
; 
 641                 IFA_LOCK(&ia
->ia_ifa
); 
 642                 bcopy(&ia
->ia_addr
, &ifr
->ifr_addr
, sizeof (addr
)); 
 643                 IFA_UNLOCK(&ia
->ia_ifa
); 
 646         case SIOCSIFADDR
:               /* struct ifreq */ 
 648                 bcopy(&ifr
->ifr_addr
, &addr
, sizeof (addr
)); 
 650                  * If this is a new address, the reference count for the 
 651                  * hash table has been taken at creation time above. 
 653                 error 
= in_ifinit(ifp
, ia
, &addr
, 1); 
 655                         (void) ifnet_notify_address(ifp
, AF_INET
); 
 659         case SIOCAIFADDR
: {             /* struct {if,in_}aliasreq */ 
 660                 struct in_aliasreq 
*ifra 
= (struct in_aliasreq 
*)ifr
; 
 661                 struct sockaddr_in broadaddr
, mask
; 
 662                 int hostIsNew
, maskIsNew
; 
 665                 bcopy(&ifra
->ifra_addr
, &addr
, sizeof (addr
)); 
 666                 bcopy(&ifra
->ifra_broadaddr
, &broadaddr
, sizeof (broadaddr
)); 
 667                 bcopy(&ifra
->ifra_mask
, &mask
, sizeof (mask
)); 
 673                 IFA_LOCK(&ia
->ia_ifa
); 
 674                 if (ia
->ia_addr
.sin_family 
== AF_INET
) { 
 675                         if (addr
.sin_len 
== 0) { 
 678                         } else if (addr
.sin_addr
.s_addr 
== 
 679                             ia
->ia_addr
.sin_addr
.s_addr
) { 
 684                         IFA_UNLOCK(&ia
->ia_ifa
); 
 685                         in_ifscrub(ifp
, ia
, 0); 
 686                         IFA_LOCK(&ia
->ia_ifa
); 
 687                         ia
->ia_sockmask 
= mask
; 
 689                             ntohl(ia
->ia_sockmask
.sin_addr
.s_addr
); 
 692                 if ((ifp
->if_flags 
& IFF_POINTOPOINT
) && 
 693                     (broadaddr
.sin_family 
== AF_INET
)) { 
 694                         IFA_UNLOCK(&ia
->ia_ifa
); 
 695                         in_ifscrub(ifp
, ia
, 0); 
 696                         IFA_LOCK(&ia
->ia_ifa
); 
 697                         ia
->ia_dstaddr 
= broadaddr
; 
 698                         ia
->ia_dstaddr
.sin_len 
= sizeof (struct sockaddr_in
); 
 699                         maskIsNew  
= 1; /* We lie; but the effect's the same */ 
 701                 if (addr
.sin_family 
== AF_INET 
&& (hostIsNew 
|| maskIsNew
)) { 
 702                         IFA_UNLOCK(&ia
->ia_ifa
); 
 703                         error 
= in_ifinit(ifp
, ia
, &addr
, 0); 
 705                         IFA_UNLOCK(&ia
->ia_ifa
); 
 708                         (void) ifnet_notify_address(ifp
, AF_INET
); 
 710                 IFA_LOCK(&ia
->ia_ifa
); 
 711                 if ((ifp
->if_flags 
& IFF_BROADCAST
) && 
 712                     (broadaddr
.sin_family 
== AF_INET
)) 
 713                         ia
->ia_broadaddr 
= broadaddr
; 
 718                 if ((error 
== 0) || (error 
== EEXIST
)) { 
 719                         ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
 720                         ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
 721                         ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
 724                                 ev_msg
.event_code 
= KEV_INET_NEW_ADDR
; 
 726                                 ev_msg
.event_code 
= KEV_INET_CHANGED_ADDR
; 
 728                         if (ia
->ia_ifa
.ifa_dstaddr
) { 
 729                                 in_event_data
.ia_dstaddr 
= 
 730                                     ((struct sockaddr_in 
*)(void *)ia
-> 
 731                                     ia_ifa
.ifa_dstaddr
)->sin_addr
; 
 733                                 in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
 735                         in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
 736                         in_event_data
.ia_net            
= ia
->ia_net
; 
 737                         in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
 738                         in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
 739                         in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
 740                         in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
 741                         IFA_UNLOCK(&ia
->ia_ifa
); 
 742                         (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
 743                             ifp
->if_name
, IFNAMSIZ
); 
 744                         in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
 745                         in_event_data
.link_data
.if_unit 
= ifp
->if_unit
; 
 747                         ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
 748                         ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
 749                         ev_msg
.dv
[1].data_length 
= 0; 
 751                         dlil_post_complete_msg(ifp
, &ev_msg
); 
 753                         IFA_UNLOCK(&ia
->ia_ifa
); 
 758         case SIOCDIFADDR
:               /* struct ifreq */ 
 760                 error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCDIFADDR
, ia
); 
 761                 if (error 
== EOPNOTSUPP
) 
 764                         /* Reset the detaching flag */ 
 765                         IFA_LOCK(&ia
->ia_ifa
); 
 766                         ia
->ia_ifa
.ifa_debug 
&= ~IFD_DETACHING
; 
 767                         IFA_UNLOCK(&ia
->ia_ifa
); 
 771                 /* Fill out the kernel event information */ 
 772                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
 773                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
 774                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
 776                 ev_msg
.event_code       
= KEV_INET_ADDR_DELETED
; 
 778                 IFA_LOCK(&ia
->ia_ifa
); 
 779                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
 780                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
 781                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
 783                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
 785                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
 786                 in_event_data
.ia_net            
= ia
->ia_net
; 
 787                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
 788                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
 789                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
 790                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
 791                 IFA_UNLOCK(&ia
->ia_ifa
); 
 792                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
 793                     ifp
->if_name
, IFNAMSIZ
); 
 794                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
 795                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
 797                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
 798                 ev_msg
.dv
[0].data_length 
= sizeof(struct kev_in_data
); 
 799                 ev_msg
.dv
[1].data_length 
= 0; 
 802                 lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
 803                 /* Release ia_link reference */ 
 805                 TAILQ_REMOVE(&in_ifaddrhead
, ia
, ia_link
); 
 807                 if (IA_IS_HASHED(ia
)) 
 808                         in_iahash_remove(ia
); 
 810                 lck_rw_done(in_ifaddr_rwlock
); 
 813                  * in_ifscrub kills the interface route. 
 815                 in_ifscrub(ifp
, ia
, 0); 
 816                 ifnet_lock_exclusive(ifp
); 
 818                 /* if_detach_ifa() releases ifa_link reference */ 
 819                 if_detach_ifa(ifp
, ifa
); 
 820                 /* Our reference to this address is dropped at the bottom */ 
 823                 /* invalidate route caches */ 
 824                 routegenid_inet_update(); 
 827                  * If the interface supports multicast, and no address is left, 
 828                  * remove the "all hosts" multicast group from that interface. 
 830                 if ((ifp
->if_flags 
& IFF_MULTICAST
) || 
 831                     ifp
->if_allhostsinm 
!= NULL
) { 
 833                         TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
 835                                 if (ifa
->ifa_addr
->sa_family 
== AF_INET
) { 
 841                         ifnet_lock_done(ifp
); 
 843                         lck_mtx_lock(&ifp
->if_addrconfig_lock
); 
 844                         if (ifa 
== NULL 
&& ifp
->if_allhostsinm 
!= NULL
) { 
 845                                 struct in_multi 
*inm 
= ifp
->if_allhostsinm
; 
 846                                 ifp
->if_allhostsinm 
= NULL
; 
 849                                 /* release the reference for allhostsinm */ 
 852                         lck_mtx_unlock(&ifp
->if_addrconfig_lock
); 
 854                         ifnet_lock_done(ifp
); 
 857                 /* Post the kernel event */ 
 858                 dlil_post_complete_msg(ifp
, &ev_msg
); 
 861                  * See if there is any IPV4 address left and if so, 
 862                  * reconfigure KDP to use current primary address. 
 864                 ifa 
= ifa_ifpgetprimary(ifp
, AF_INET
); 
 867                          * NOTE: SIOCSIFADDR is defined with struct ifreq 
 868                          * as parameter, but here we are sending it down 
 869                          * to the interface with a pointer to struct ifaddr, 
 870                          * for legacy reasons. 
 872                         error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa
); 
 873                         if (error 
== EOPNOTSUPP
) 
 876                         /* Release reference from ifa_ifpgetprimary() */ 
 879                 (void) ifnet_notify_address(ifp
, AF_INET
); 
 891  * Caller passes in the ioctl data pointer directly via "ifr", with the 
 892  * expectation that this routine always uses bcopy() or other byte-aligned 
 895 static __attribute__((noinline
)) int 
 896 inctl_ifdstaddr(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
 899         struct kev_in_data in_event_data
; 
 900         struct kev_msg ev_msg
; 
 901         struct sockaddr_in dstaddr
; 
 906         if (!(ifp
->if_flags 
& IFF_POINTOPOINT
)) 
 909         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
 910         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
 913         case SIOCGIFDSTADDR
:            /* struct ifreq */ 
 915                         error 
= EADDRNOTAVAIL
; 
 918                 IFA_LOCK(&ia
->ia_ifa
); 
 919                 bcopy(&ia
->ia_dstaddr
, &ifr
->ifr_dstaddr
, sizeof (dstaddr
)); 
 920                 IFA_UNLOCK(&ia
->ia_ifa
); 
 923         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
 925                 IFA_LOCK(&ia
->ia_ifa
); 
 926                 dstaddr 
= ia
->ia_dstaddr
; 
 927                 bcopy(&ifr
->ifr_dstaddr
, &ia
->ia_dstaddr
, sizeof (dstaddr
)); 
 928                 if (ia
->ia_dstaddr
.sin_family 
== AF_INET
) 
 929                         ia
->ia_dstaddr
.sin_len 
= sizeof (struct sockaddr_in
); 
 930                 IFA_UNLOCK(&ia
->ia_ifa
); 
 932                  * NOTE: SIOCSIFDSTADDR is defined with struct ifreq 
 933                  * as parameter, but here we are sending it down 
 934                  * to the interface with a pointer to struct ifaddr, 
 935                  * for legacy reasons. 
 937                 error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFDSTADDR
, ia
); 
 938                 IFA_LOCK(&ia
->ia_ifa
); 
 939                 if (error 
== EOPNOTSUPP
) 
 942                         ia
->ia_dstaddr 
= dstaddr
; 
 943                         IFA_UNLOCK(&ia
->ia_ifa
); 
 946                 IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
 948                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
 949                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
 950                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
 952                 ev_msg
.event_code       
= KEV_INET_SIFDSTADDR
; 
 954                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
 955                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
 956                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
 958                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
 961                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
 962                 in_event_data
.ia_net            
= ia
->ia_net
; 
 963                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
 964                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
 965                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
 966                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
 967                 IFA_UNLOCK(&ia
->ia_ifa
); 
 968                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
 969                     ifp
->if_name
, IFNAMSIZ
); 
 970                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
 971                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
 973                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
 974                 ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
 975                 ev_msg
.dv
[1].data_length 
= 0; 
 977                 dlil_post_complete_msg(ifp
, &ev_msg
); 
 979                 lck_mtx_lock(rnh_lock
); 
 980                 IFA_LOCK(&ia
->ia_ifa
); 
 981                 if (ia
->ia_flags 
& IFA_ROUTE
) { 
 982                         ia
->ia_ifa
.ifa_dstaddr 
= (struct sockaddr 
*)&dstaddr
; 
 983                         IFA_UNLOCK(&ia
->ia_ifa
); 
 984                         rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
); 
 985                         IFA_LOCK(&ia
->ia_ifa
); 
 986                         ia
->ia_ifa
.ifa_dstaddr 
= 
 987                             (struct sockaddr 
*)&ia
->ia_dstaddr
; 
 988                         IFA_UNLOCK(&ia
->ia_ifa
); 
 989                         rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, 
 992                         IFA_UNLOCK(&ia
->ia_ifa
); 
 994                 lck_mtx_unlock(rnh_lock
); 
1008  * Caller passes in the ioctl data pointer directly via "ifr", with the 
1009  * expectation that this routine always uses bcopy() or other byte-aligned 
1012 static __attribute__((noinline
)) int 
1013 inctl_ifbrdaddr(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
1016         struct kev_in_data in_event_data
; 
1017         struct kev_msg ev_msg
; 
1020         VERIFY(ifp 
!= NULL
); 
1023                 return (EADDRNOTAVAIL
); 
1025         if (!(ifp
->if_flags 
& IFF_BROADCAST
)) 
1028         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
1029         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
1032         case SIOCGIFBRDADDR
:            /* struct ifreq */ 
1033                 IFA_LOCK(&ia
->ia_ifa
); 
1034                 bcopy(&ia
->ia_broadaddr
, &ifr
->ifr_broadaddr
, 
1035                     sizeof (struct sockaddr_in
)); 
1036                 IFA_UNLOCK(&ia
->ia_ifa
); 
1039         case SIOCSIFBRDADDR
:            /* struct ifreq */ 
1040                 IFA_LOCK(&ia
->ia_ifa
); 
1041                 bcopy(&ifr
->ifr_broadaddr
, &ia
->ia_broadaddr
, 
1042                     sizeof (struct sockaddr_in
)); 
1044                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
1045                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
1046                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
1048                 ev_msg
.event_code 
= KEV_INET_SIFBRDADDR
; 
1050                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
1051                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
1052                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
1054                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
1056                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
1057                 in_event_data
.ia_net            
= ia
->ia_net
; 
1058                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
1059                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
1060                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
1061                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
1062                 IFA_UNLOCK(&ia
->ia_ifa
); 
1063                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
1064                     ifp
->if_name
, IFNAMSIZ
); 
1065                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
1066                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
1068                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
1069                 ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
1070                 ev_msg
.dv
[1].data_length 
= 0; 
1072                 dlil_post_complete_msg(ifp
, &ev_msg
); 
1084  * Caller passes in the ioctl data pointer directly via "ifr", with the 
1085  * expectation that this routine always uses bcopy() or other byte-aligned 
1088 static __attribute__((noinline
)) int 
1089 inctl_ifnetmask(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, u_long cmd
, 
1092         struct kev_in_data in_event_data
; 
1093         struct kev_msg ev_msg
; 
1094         struct sockaddr_in mask
; 
1097         VERIFY(ifp 
!= NULL
); 
1099         bzero(&in_event_data
, sizeof (struct kev_in_data
)); 
1100         bzero(&ev_msg
, sizeof (struct kev_msg
)); 
1103         case SIOCGIFNETMASK
:            /* struct ifreq */ 
1105                         error 
= EADDRNOTAVAIL
; 
1108                 IFA_LOCK(&ia
->ia_ifa
); 
1109                 bcopy(&ia
->ia_sockmask
, &ifr
->ifr_addr
, sizeof (mask
)); 
1110                 IFA_UNLOCK(&ia
->ia_ifa
); 
1113         case SIOCSIFNETMASK
: {          /* struct ifreq */ 
1116                 bcopy(&ifr
->ifr_addr
, &mask
, sizeof (mask
)); 
1117                 i 
= mask
.sin_addr
.s_addr
; 
1120                 IFA_LOCK(&ia
->ia_ifa
); 
1121                 ia
->ia_subnetmask 
= ntohl(ia
->ia_sockmask
.sin_addr
.s_addr 
= i
); 
1122                 ev_msg
.vendor_code      
= KEV_VENDOR_APPLE
; 
1123                 ev_msg
.kev_class        
= KEV_NETWORK_CLASS
; 
1124                 ev_msg
.kev_subclass     
= KEV_INET_SUBCLASS
; 
1126                 ev_msg
.event_code 
= KEV_INET_SIFNETMASK
; 
1128                 if (ia
->ia_ifa
.ifa_dstaddr
) { 
1129                         in_event_data
.ia_dstaddr 
= ((struct sockaddr_in 
*) 
1130                             (void *)ia
->ia_ifa
.ifa_dstaddr
)->sin_addr
; 
1132                         in_event_data
.ia_dstaddr
.s_addr 
= INADDR_ANY
; 
1134                 in_event_data
.ia_addr           
= ia
->ia_addr
.sin_addr
; 
1135                 in_event_data
.ia_net            
= ia
->ia_net
; 
1136                 in_event_data
.ia_netmask        
= ia
->ia_netmask
; 
1137                 in_event_data
.ia_subnet         
= ia
->ia_subnet
; 
1138                 in_event_data
.ia_subnetmask     
= ia
->ia_subnetmask
; 
1139                 in_event_data
.ia_netbroadcast   
= ia
->ia_netbroadcast
; 
1140                 IFA_UNLOCK(&ia
->ia_ifa
); 
1141                 (void) strlcpy(&in_event_data
.link_data
.if_name
[0], 
1142                     ifp
->if_name
, IFNAMSIZ
); 
1143                 in_event_data
.link_data
.if_family 
= ifp
->if_family
; 
1144                 in_event_data
.link_data
.if_unit  
= (u_int32_t
)ifp
->if_unit
; 
1146                 ev_msg
.dv
[0].data_ptr    
= &in_event_data
; 
1147                 ev_msg
.dv
[0].data_length 
= sizeof (struct kev_in_data
); 
1148                 ev_msg
.dv
[1].data_length 
= 0; 
1150                 dlil_post_complete_msg(ifp
, &ev_msg
); 
1163  * Generic INET control operations (ioctl's). 
1165  * ifp is NULL if not an interface-specific ioctl. 
1167  * Most of the routines called to handle the ioctls would end up being 
1168  * tail-call optimized, which unfortunately causes this routine to 
1169  * consume too much stack space; this is the reason for the "noinline" 
1170  * attribute used on those routines. 
1172  * If called directly from within the networking stack (as opposed to via 
1173  * pru_control), the socket parameter may be NULL. 
1176 in_control(struct socket 
*so
, u_long cmd
, caddr_t data
, struct ifnet 
*ifp
, 
1179         struct ifreq 
*ifr 
= (struct ifreq 
*)(void *)data
; 
1180         struct sockaddr_in addr
, dstaddr
; 
1181         struct sockaddr_in sin
, *sa 
= NULL
; 
1182         boolean_t privileged 
= (proc_suser(p
) == 0); 
1183         boolean_t so_unlocked 
= FALSE
; 
1184         struct in_ifaddr 
*ia 
= NULL
; 
1188         /* In case it's NULL, make sure it came from the kernel */ 
1189         VERIFY(so 
!= NULL 
|| p 
== kernproc
); 
1192          * ioctls which don't require ifp, but require socket. 
1195         case SIOCGASSOCIDS32
:           /* struct so_aidreq32 */ 
1196         case SIOCGASSOCIDS64
:           /* struct so_aidreq64 */ 
1197                 return (inctl_associd(so
, cmd
, data
)); 
1200         case SIOCGCONNIDS32
:            /* struct so_cidreq32 */ 
1201         case SIOCGCONNIDS64
:            /* struct so_cidreq64 */ 
1202                 return (inctl_connid(so
, cmd
, data
)); 
1205         case SIOCGCONNINFO32
:           /* struct so_cinforeq32 */ 
1206         case SIOCGCONNINFO64
:           /* struct so_cinforeq64 */ 
1207                 return (inctl_conninfo(so
, cmd
, data
)); 
1212          * The rest of ioctls require ifp; reject if we don't have one; 
1213          * return ENXIO to be consistent with ifioctl(). 
1219          * ioctls which require ifp but not interface address. 
1222         case SIOCAUTOADDR
:              /* struct ifreq */ 
1225                 return (inctl_autoaddr(ifp
, ifr
)); 
1228         case SIOCARPIPLL
:               /* struct ifreq */ 
1231                 return (inctl_arpipll(ifp
, ifr
)); 
1234         case SIOCSETROUTERMODE
:         /* struct ifreq */ 
1237                 return (inctl_setrouter(ifp
, ifr
)); 
1240         case SIOCPROTOATTACH
:           /* struct ifreq */ 
1243                 return (in_domifattach(ifp
)); 
1246         case SIOCPROTODETACH
:           /* struct ifreq */ 
1251                  * If an IPv4 address is still present, refuse to detach. 
1253                 ifnet_lock_shared(ifp
); 
1254                 TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
1256                         if (ifa
->ifa_addr
->sa_family 
== AF_INET
) { 
1262                 ifnet_lock_done(ifp
); 
1263                 return ((ifa 
== NULL
) ? proto_unplumb(PF_INET
, ifp
) : EBUSY
); 
1268          * ioctls which require interface address; obtain sockaddr_in. 
1271         case SIOCAIFADDR
:               /* struct {if,in_}aliasreq */ 
1274                 bcopy(&((struct in_aliasreq 
*)(void *)data
)->ifra_addr
, 
1275                     &sin
, sizeof (sin
)); 
1279         case SIOCDIFADDR
:               /* struct ifreq */ 
1280         case SIOCSIFADDR
:               /* struct ifreq */ 
1281         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
1282         case SIOCSIFNETMASK
:            /* struct ifreq */ 
1283         case SIOCSIFBRDADDR
:            /* struct ifreq */ 
1287         case SIOCGIFADDR
:               /* struct ifreq */ 
1288         case SIOCGIFDSTADDR
:            /* struct ifreq */ 
1289         case SIOCGIFNETMASK
:            /* struct ifreq */ 
1290         case SIOCGIFBRDADDR
:            /* struct ifreq */ 
1291                 bcopy(&ifr
->ifr_addr
, &sin
, sizeof (sin
)); 
1297          * Find address for this interface, if it exists. 
1299          * If an alias address was specified, find that one instead of 
1300          * the first one on the interface, if possible. 
1304                 struct in_ifaddr 
*iap
; 
1307                  * Any failures from this point on must take into account 
1308                  * a non-NULL "ia" with an outstanding reference count, and 
1309                  * therefore requires IFA_REMREF.  Jump to "done" label 
1310                  * instead of calling return if "ia" is valid. 
1312                 lck_rw_lock_shared(in_ifaddr_rwlock
); 
1313                 TAILQ_FOREACH(iap
, INADDR_HASH(sa
->sin_addr
.s_addr
), ia_hash
) { 
1314                         IFA_LOCK(&iap
->ia_ifa
); 
1315                         if (iap
->ia_ifp 
== ifp 
&& 
1316                             iap
->ia_addr
.sin_addr
.s_addr 
== 
1317                             sa
->sin_addr
.s_addr
) { 
1319                                  * Avoid the race condition seen when two 
1320                                  * threads process SIOCDIFADDR command 
1321                                  * at the same time (radar 28942007) 
1323                                 if (cmd 
== SIOCDIFADDR
) { 
1324                                         if (iap
->ia_ifa
.ifa_debug 
& 
1326                                                 IFA_UNLOCK(&iap
->ia_ifa
); 
1329                                                 iap
->ia_ifa
.ifa_debug 
|= 
1334                                 IFA_ADDREF_LOCKED(&iap
->ia_ifa
); 
1335                                 IFA_UNLOCK(&iap
->ia_ifa
); 
1338                         IFA_UNLOCK(&iap
->ia_ifa
); 
1340                 lck_rw_done(in_ifaddr_rwlock
); 
1343                         ifnet_lock_shared(ifp
); 
1344                         TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
1346                                 IFA_LOCK(&iap
->ia_ifa
); 
1347                                 if (iap
->ia_addr
.sin_family 
== AF_INET
) { 
1349                                         IFA_UNLOCK(&iap
->ia_ifa
); 
1352                                 IFA_UNLOCK(&iap
->ia_ifa
); 
1354                         /* take a reference on ia before releasing lock */ 
1356                                 IFA_ADDREF(&ia
->ia_ifa
); 
1357                         ifnet_lock_done(ifp
); 
1362          * Unlock the socket since ifnet_ioctl() may be invoked by 
1363          * one of the ioctl handlers below.  Socket will be re-locked 
1364          * prior to returning. 
1367                 socket_unlock(so
, 0); 
1372         case SIOCAIFADDR
:               /* struct {if,in_}aliasreq */ 
1373         case SIOCDIFADDR
:               /* struct ifreq */ 
1374                 if (cmd 
== SIOCAIFADDR
) { 
1375                         bcopy(&((struct in_aliasreq 
*)(void *)data
)-> 
1376                             ifra_addr
, &addr
, sizeof (addr
)); 
1377                         bcopy(&((struct in_aliasreq 
*)(void *)data
)-> 
1378                             ifra_dstaddr
, &dstaddr
, sizeof (dstaddr
)); 
1380                         VERIFY(cmd 
== SIOCDIFADDR
); 
1381                         bcopy(&((struct ifreq 
*)(void *)data
)->ifr_addr
, 
1382                             &addr
, sizeof (addr
)); 
1383                         bzero(&dstaddr
, sizeof (dstaddr
)); 
1386                 if (addr
.sin_family 
== AF_INET
) { 
1387                         struct in_ifaddr 
*oia
; 
1389                         lck_rw_lock_shared(in_ifaddr_rwlock
); 
1390                         for (oia 
= ia
; ia
; ia 
= ia
->ia_link
.tqe_next
) { 
1391                                 IFA_LOCK(&ia
->ia_ifa
); 
1392                                 if (ia
->ia_ifp 
== ifp 
&& 
1393                                     ia
->ia_addr
.sin_addr
.s_addr 
== 
1394                                     addr
.sin_addr
.s_addr
) { 
1395                                         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
1396                                         IFA_UNLOCK(&ia
->ia_ifa
); 
1399                                 IFA_UNLOCK(&ia
->ia_ifa
); 
1401                         lck_rw_done(in_ifaddr_rwlock
); 
1403                                 IFA_REMREF(&oia
->ia_ifa
); 
1404                         if ((ifp
->if_flags 
& IFF_POINTOPOINT
) && 
1405                             (cmd 
== SIOCAIFADDR
) && 
1406                             (dstaddr
.sin_addr
.s_addr 
== INADDR_ANY
)) { 
1407                                 error 
= EDESTADDRREQ
; 
1410                 } else if (cmd 
== SIOCAIFADDR
) { 
1414                 if (cmd 
== SIOCDIFADDR 
&& ia 
== NULL
) { 
1415                         error 
= EADDRNOTAVAIL
; 
1419         case SIOCSIFADDR
:               /* struct ifreq */ 
1420         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
1421         case SIOCSIFNETMASK
:            /* struct ifreq */ 
1422                 if (cmd 
== SIOCAIFADDR
) { 
1423                         /* fell thru from above; just repeat it */ 
1424                         bcopy(&((struct in_aliasreq 
*)(void *)data
)-> 
1425                             ifra_addr
, &addr
, sizeof (addr
)); 
1427                         VERIFY(cmd 
== SIOCDIFADDR 
|| cmd 
== SIOCSIFADDR 
|| 
1428                             cmd 
== SIOCSIFNETMASK 
|| cmd 
== SIOCSIFDSTADDR
); 
1429                         bcopy(&((struct ifreq 
*)(void *)data
)->ifr_addr
, 
1430                             &addr
, sizeof (addr
)); 
1433                 if (addr
.sin_family 
!= AF_INET 
&& cmd 
== SIOCSIFADDR
) { 
1438                         ia 
= in_ifaddr_alloc(M_WAITOK
); 
1443                         ifnet_lock_exclusive(ifp
); 
1446                         /* Hold a reference for this routine */ 
1447                         IFA_ADDREF_LOCKED(ifa
); 
1449                         ifa
->ifa_addr 
= (struct sockaddr 
*)&ia
->ia_addr
; 
1450                         ifa
->ifa_dstaddr 
= (struct sockaddr 
*)&ia
->ia_dstaddr
; 
1451                         ifa
->ifa_netmask 
= (struct sockaddr 
*)&ia
->ia_sockmask
; 
1452                         ia
->ia_sockmask
.sin_len 
= 8; 
1453                         if (ifp
->if_flags 
& IFF_BROADCAST
) { 
1454                                 ia
->ia_broadaddr
.sin_len 
= sizeof (ia
->ia_addr
); 
1455                                 ia
->ia_broadaddr
.sin_family 
= AF_INET
; 
1458                         if (!(ifp
->if_flags 
& IFF_LOOPBACK
)) 
1460                         /* if_attach_ifa() holds a reference for ifa_link */ 
1461                         if_attach_ifa(ifp
, ifa
); 
1463                          * If we have to go through in_ifinit(), make sure 
1464                          * to avoid installing route(s) based on this address 
1465                          * via PFC_IFUP event, before the link resolver (ARP) 
1468                         if (cmd 
== SIOCAIFADDR 
|| cmd 
== SIOCSIFADDR
) 
1469                                 ifa
->ifa_debug 
|= IFD_NOTREADY
; 
1471                         ifnet_lock_done(ifp
); 
1472                         lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
1473                         /* Hold a reference for ia_link */ 
1475                         TAILQ_INSERT_TAIL(&in_ifaddrhead
, ia
, ia_link
); 
1476                         lck_rw_done(in_ifaddr_rwlock
); 
1478                         (void) in_domifattach(ifp
); 
1485         case SIOCGIFDSTADDR
:            /* struct ifreq */ 
1486         case SIOCSIFDSTADDR
:            /* struct ifreq */ 
1487                 error 
= inctl_ifdstaddr(ifp
, ia
, cmd
, ifr
); 
1490         case SIOCGIFBRDADDR
:            /* struct ifreq */ 
1491         case SIOCSIFBRDADDR
:            /* struct ifreq */ 
1492                 error 
= inctl_ifbrdaddr(ifp
, ia
, cmd
, ifr
); 
1495         case SIOCGIFNETMASK
:            /* struct ifreq */ 
1496         case SIOCSIFNETMASK
:            /* struct ifreq */ 
1497                 error 
= inctl_ifnetmask(ifp
, ia
, cmd
, ifr
); 
1500         case SIOCGIFADDR
:               /* struct ifreq */ 
1501         case SIOCSIFADDR
:               /* struct ifreq */ 
1502         case SIOCAIFADDR
:               /* struct {if,in_}aliasreq */ 
1503         case SIOCDIFADDR
:               /* struct ifreq */ 
1504                 error 
= inctl_ifaddr(ifp
, ia
, cmd
, ifr
); 
1513                 IFA_REMREF(&ia
->ia_ifa
); 
1521  * Delete any existing route for an interface. 
1524 in_ifscrub(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, int locked
) 
1526         IFA_LOCK(&ia
->ia_ifa
); 
1527         if ((ia
->ia_flags 
& IFA_ROUTE
) == 0) { 
1528                 IFA_UNLOCK(&ia
->ia_ifa
); 
1531         IFA_UNLOCK(&ia
->ia_ifa
); 
1533                 lck_mtx_lock(rnh_lock
); 
1534         if (ifp
->if_flags 
& (IFF_LOOPBACK
|IFF_POINTOPOINT
)) 
1535                 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, RTF_HOST
); 
1537                 rtinit_locked(&(ia
->ia_ifa
), (int)RTM_DELETE
, 0); 
1538         IFA_LOCK(&ia
->ia_ifa
); 
1539         ia
->ia_flags 
&= ~IFA_ROUTE
; 
1540         IFA_UNLOCK(&ia
->ia_ifa
); 
1542                 lck_mtx_unlock(rnh_lock
); 
1546  * Caller must hold in_ifaddr_rwlock as writer. 
1549 in_iahash_remove(struct in_ifaddr 
*ia
) 
1551         LCK_RW_ASSERT(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1552         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1554         if (!IA_IS_HASHED(ia
)) { 
1555                 panic("attempt to remove wrong ia %p from hash table\n", ia
); 
1558         TAILQ_REMOVE(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), ia
, ia_hash
); 
1560         if (IFA_REMREF_LOCKED(&ia
->ia_ifa
) == NULL
) { 
1561                 panic("%s: unexpected (missing) refcnt ifa=%p", __func__
, 
1568  * Caller must hold in_ifaddr_rwlock as writer. 
1571 in_iahash_insert(struct in_ifaddr 
*ia
) 
1573         LCK_RW_ASSERT(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1574         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1576         if (ia
->ia_addr
.sin_family 
!= AF_INET
) { 
1577                 panic("attempt to insert wrong ia %p into hash table\n", ia
); 
1579         } else if (IA_IS_HASHED(ia
)) { 
1580                 panic("attempt to double-insert ia %p into hash table\n", ia
); 
1583         TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1585         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
1589  * Some point to point interfaces that are tunnels borrow the address from 
1590  * an underlying interface (e.g. VPN server). In order for source address 
1591  * selection logic to find the underlying interface first, we add the address 
1592  * of borrowing point to point interfaces at the end of the list. 
1593  * (see rdar://6733789) 
1595  * Caller must hold in_ifaddr_rwlock as writer. 
1598 in_iahash_insert_ptp(struct in_ifaddr 
*ia
) 
1600         struct in_ifaddr 
*tmp_ifa
; 
1601         struct ifnet 
*tmp_ifp
; 
1603         LCK_RW_ASSERT(in_ifaddr_rwlock
, LCK_RW_ASSERT_EXCLUSIVE
); 
1604         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1606         if (ia
->ia_addr
.sin_family 
!= AF_INET
) { 
1607                 panic("attempt to insert wrong ia %p into hash table\n", ia
); 
1609         } else if (IA_IS_HASHED(ia
)) { 
1610                 panic("attempt to double-insert ia %p into hash table\n", ia
); 
1613         IFA_UNLOCK(&ia
->ia_ifa
); 
1614         TAILQ_FOREACH(tmp_ifa
, INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1616                 IFA_LOCK(&tmp_ifa
->ia_ifa
); 
1617                 /* ia->ia_addr won't change, so check without lock */ 
1618                 if (IA_SIN(tmp_ifa
)->sin_addr
.s_addr 
== 
1619                     ia
->ia_addr
.sin_addr
.s_addr
) { 
1620                         IFA_UNLOCK(&tmp_ifa
->ia_ifa
); 
1623                 IFA_UNLOCK(&tmp_ifa
->ia_ifa
); 
1625         tmp_ifp 
= (tmp_ifa 
== NULL
) ? NULL 
: tmp_ifa
->ia_ifp
; 
1627         IFA_LOCK(&ia
->ia_ifa
); 
1628         if (tmp_ifp 
== NULL
) { 
1629                 TAILQ_INSERT_HEAD(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1632                 TAILQ_INSERT_TAIL(INADDR_HASH(ia
->ia_addr
.sin_addr
.s_addr
), 
1635         IFA_ADDREF_LOCKED(&ia
->ia_ifa
); 
1639  * Initialize an interface's internet address 
1640  * and routing table entry. 
1643 in_ifinit(struct ifnet 
*ifp
, struct in_ifaddr 
*ia
, struct sockaddr_in 
*sin
, 
1646         u_int32_t i 
= ntohl(sin
->sin_addr
.s_addr
); 
1647         struct sockaddr_in oldaddr
; 
1648         int flags 
= RTF_UP
, error
; 
1649         struct ifaddr 
*ifa0
; 
1653         /* Take an extra reference for this routine */ 
1654         IFA_ADDREF(&ia
->ia_ifa
); 
1656         lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
1657         IFA_LOCK(&ia
->ia_ifa
); 
1658         oldaddr 
= ia
->ia_addr
; 
1659         if (IA_IS_HASHED(ia
)) { 
1661                 in_iahash_remove(ia
); 
1665          * Interface addresses should not contain port or sin_zero information. 
1667         SIN(&ia
->ia_addr
)->sin_family 
= AF_INET
; 
1668         SIN(&ia
->ia_addr
)->sin_len 
= sizeof (struct sockaddr_in
); 
1669         SIN(&ia
->ia_addr
)->sin_port 
= 0; 
1670         bzero(&SIN(&ia
->ia_addr
)->sin_zero
, sizeof (sin
->sin_zero
)); 
1671         if ((ifp
->if_flags 
& IFF_POINTOPOINT
)) 
1672                 in_iahash_insert_ptp(ia
); 
1674                 in_iahash_insert(ia
); 
1675         IFA_UNLOCK(&ia
->ia_ifa
); 
1676         lck_rw_done(in_ifaddr_rwlock
); 
1679          * Give the interface a chance to initialize if this is its first 
1680          * address, and to validate the address if necessary.  Send down 
1681          * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es). 
1682          * We find the first IPV4 address assigned to it and check if this 
1683          * is the same as the one passed into this routine. 
1685         ifa0 
= ifa_ifpgetprimary(ifp
, AF_INET
); 
1686         cmd 
= (&ia
->ia_ifa 
== ifa0
) ? SIOCSIFADDR 
: SIOCAIFADDR
; 
1687         error 
= ifnet_ioctl(ifp
, PF_INET
, cmd
, ia
); 
1688         if (error 
== EOPNOTSUPP
) 
1691          * If we've just sent down SIOCAIFADDR, send another ioctl down 
1692          * for SIOCSIFADDR for the first IPV4 address of the interface, 
1693          * because an address change on one of the addresses will result 
1694          * in the removal of the previous first IPV4 address.  KDP needs 
1695          * be reconfigured with the current primary IPV4 address. 
1697         if (error 
== 0 && cmd 
== SIOCAIFADDR
) { 
1699                  * NOTE: SIOCSIFADDR is defined with struct ifreq 
1700                  * as parameter, but here we are sending it down 
1701                  * to the interface with a pointer to struct ifaddr, 
1702                  * for legacy reasons. 
1704                 error 
= ifnet_ioctl(ifp
, PF_INET
, SIOCSIFADDR
, ifa0
); 
1705                 if (error 
== EOPNOTSUPP
) 
1709         /* Release reference from ifa_ifpgetprimary() */ 
1713                 lck_rw_lock_exclusive(in_ifaddr_rwlock
); 
1714                 IFA_LOCK(&ia
->ia_ifa
); 
1715                 if (IA_IS_HASHED(ia
)) 
1716                         in_iahash_remove(ia
); 
1717                 ia
->ia_addr 
= oldaddr
; 
1719                         if ((ifp
->if_flags 
& IFF_POINTOPOINT
)) 
1720                                 in_iahash_insert_ptp(ia
); 
1722                                 in_iahash_insert(ia
); 
1724                 IFA_UNLOCK(&ia
->ia_ifa
); 
1725                 lck_rw_done(in_ifaddr_rwlock
); 
1726                 /* Release extra reference taken above */ 
1727                 IFA_REMREF(&ia
->ia_ifa
); 
1730         lck_mtx_lock(rnh_lock
); 
1731         IFA_LOCK(&ia
->ia_ifa
); 
1733          * Address has been initialized by the link resolver (ARP) 
1734          * via ifnet_ioctl() above; it may now generate route(s). 
1736         ia
->ia_ifa
.ifa_debug 
&= ~IFD_NOTREADY
; 
1738                 ia
->ia_ifa
.ifa_addr 
= (struct sockaddr 
*)&oldaddr
; 
1739                 IFA_UNLOCK(&ia
->ia_ifa
); 
1740                 in_ifscrub(ifp
, ia
, 1); 
1741                 IFA_LOCK(&ia
->ia_ifa
); 
1742                 ia
->ia_ifa
.ifa_addr 
= (struct sockaddr 
*)&ia
->ia_addr
; 
1744         IFA_LOCK_ASSERT_HELD(&ia
->ia_ifa
); 
1746                 ia
->ia_netmask 
= IN_CLASSA_NET
; 
1747         else if (IN_CLASSB(i
)) 
1748                 ia
->ia_netmask 
= IN_CLASSB_NET
; 
1750                 ia
->ia_netmask 
= IN_CLASSC_NET
; 
1752          * The subnet mask usually includes at least the standard network part, 
1753          * but may may be smaller in the case of supernetting. 
1754          * If it is set, we believe it. 
1756         if (ia
->ia_subnetmask 
== 0) { 
1757                 ia
->ia_subnetmask 
= ia
->ia_netmask
; 
1758                 ia
->ia_sockmask
.sin_addr
.s_addr 
= htonl(ia
->ia_subnetmask
); 
1760                 ia
->ia_netmask 
&= ia
->ia_subnetmask
; 
1761         ia
->ia_net 
= i 
& ia
->ia_netmask
; 
1762         ia
->ia_subnet 
= i 
& ia
->ia_subnetmask
; 
1763         in_socktrim(&ia
->ia_sockmask
); 
1765          * Add route for the network. 
1767         ia
->ia_ifa
.ifa_metric 
= ifp
->if_metric
; 
1768         if (ifp
->if_flags 
& IFF_BROADCAST
) { 
1769                 ia
->ia_broadaddr
.sin_addr
.s_addr 
= 
1770                     htonl(ia
->ia_subnet 
| ~ia
->ia_subnetmask
); 
1771                 ia
->ia_netbroadcast
.s_addr 
= 
1772                     htonl(ia
->ia_net 
| ~ ia
->ia_netmask
); 
1773         } else if (ifp
->if_flags 
& IFF_LOOPBACK
) { 
1774                 ia
->ia_ifa
.ifa_dstaddr 
= ia
->ia_ifa
.ifa_addr
; 
1776         } else if (ifp
->if_flags 
& IFF_POINTOPOINT
) { 
1777                 if (ia
->ia_dstaddr
.sin_family 
!= AF_INET
) { 
1778                         IFA_UNLOCK(&ia
->ia_ifa
); 
1779                         lck_mtx_unlock(rnh_lock
); 
1780                         /* Release extra reference taken above */ 
1781                         IFA_REMREF(&ia
->ia_ifa
); 
1784                 ia
->ia_dstaddr
.sin_len 
= sizeof (struct sockaddr_in
); 
1787         IFA_UNLOCK(&ia
->ia_ifa
); 
1789         if ((error 
= rtinit_locked(&(ia
->ia_ifa
), (int)RTM_ADD
, flags
)) == 0) { 
1790                 IFA_LOCK(&ia
->ia_ifa
); 
1791                 ia
->ia_flags 
|= IFA_ROUTE
; 
1792                 IFA_UNLOCK(&ia
->ia_ifa
); 
1794         lck_mtx_unlock(rnh_lock
); 
1796         /* XXX check if the subnet route points to the same interface */ 
1797         if (error 
== EEXIST
) 
1801          * If the interface supports multicast, join the "all hosts" 
1802          * multicast group on that interface. 
1804         if (ifp
->if_flags 
& IFF_MULTICAST
) { 
1805                 struct in_addr addr
; 
1807                 lck_mtx_lock(&ifp
->if_addrconfig_lock
); 
1808                 addr
.s_addr 
= htonl(INADDR_ALLHOSTS_GROUP
); 
1809                 if (ifp
->if_allhostsinm 
== NULL
) { 
1810                         struct in_multi 
*inm
; 
1811                         inm 
= in_addmulti(&addr
, ifp
); 
1815                                  * Keep the reference on inm added by 
1816                                  * in_addmulti above for storing the 
1817                                  * pointer in allhostsinm. 
1819                                 ifp
->if_allhostsinm 
= inm
; 
1821                                 printf("%s: failed to add membership to " 
1822                                     "all-hosts multicast address on %s\n", 
1823                                     __func__
, if_name(ifp
)); 
1826                 lck_mtx_unlock(&ifp
->if_addrconfig_lock
); 
1829         /* Release extra reference taken above */ 
1830         IFA_REMREF(&ia
->ia_ifa
); 
1833                 /* invalidate route caches */ 
1834                 routegenid_inet_update(); 
1841  * Return TRUE if the address might be a local broadcast address. 
1844 in_broadcast(struct in_addr in
, struct ifnet 
*ifp
) 
1849         if (in
.s_addr 
== INADDR_BROADCAST 
|| in
.s_addr 
== INADDR_ANY
) 
1851         if (!(ifp
->if_flags 
& IFF_BROADCAST
)) 
1853         t 
= ntohl(in
.s_addr
); 
1856          * Look through the list of addresses for a match 
1857          * with a broadcast address. 
1859 #define ia ((struct in_ifaddr *)ifa) 
1860         ifnet_lock_shared(ifp
); 
1861         TAILQ_FOREACH(ifa
, &ifp
->if_addrhead
, ifa_link
) { 
1863                 if (ifa
->ifa_addr
->sa_family 
== AF_INET 
&& 
1864                     (in
.s_addr 
== ia
->ia_broadaddr
.sin_addr
.s_addr 
|| 
1865                      in
.s_addr 
== ia
->ia_netbroadcast
.s_addr 
|| 
1867                       * Check for old-style (host 0) broadcast. 
1869                      t 
== ia
->ia_subnet 
|| t 
== ia
->ia_net
) && 
1871                       * Check for an all one subnetmask. These 
1872                       * only exist when an interface gets a secondary 
1875                      ia
->ia_subnetmask 
!= (u_int32_t
)0xffffffff) { 
1877                         ifnet_lock_done(ifp
); 
1882         ifnet_lock_done(ifp
); 
1888 in_purgeaddrs(struct ifnet 
*ifp
) 
1890         struct ifaddr 
**ifap
; 
1893         VERIFY(ifp 
!= NULL
); 
1896          * Be nice, and try the civilized way first.  If we can't get 
1897          * rid of them this way, then do it the rough way.  We must 
1898          * only get here during detach time, after the ifnet has been 
1899          * removed from the global list and arrays. 
1901         err 
= ifnet_get_address_list_family_internal(ifp
, &ifap
, AF_INET
, 1, 
1903         if (err 
== 0 && ifap 
!= NULL
) { 
1906                 bzero(&ifr
, sizeof (ifr
)); 
1907                 (void) snprintf(ifr
.ifr_name
, sizeof (ifr
.ifr_name
), 
1908                     "%s", if_name(ifp
)); 
1910                 for (i 
= 0; ifap
[i
] != NULL
; i
++) { 
1915                         bcopy(ifa
->ifa_addr
, &ifr
.ifr_addr
, 
1916                             sizeof (struct sockaddr_in
)); 
1918                         err 
= in_control(NULL
, SIOCDIFADDR
, (caddr_t
)&ifr
, ifp
, 
1920                         /* if we lost the race, ignore it */ 
1921                         if (err 
== EADDRNOTAVAIL
) 
1924                                 char s_addr
[MAX_IPv4_STR_LEN
]; 
1925                                 char s_dstaddr
[MAX_IPv4_STR_LEN
]; 
1926                                 struct in_addr 
*s
, *d
; 
1929                                 s 
= &((struct sockaddr_in 
*) 
1930                                     (void *)ifa
->ifa_addr
)->sin_addr
; 
1931                                 d 
= &((struct sockaddr_in 
*) 
1932                                     (void *)ifa
->ifa_dstaddr
)->sin_addr
; 
1933                                 (void) inet_ntop(AF_INET
, &s
->s_addr
, s_addr
, 
1935                                 (void) inet_ntop(AF_INET
, &d
->s_addr
, s_dstaddr
, 
1936                                     sizeof (s_dstaddr
)); 
1939                                 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s " 
1940                                     "ifa_dstaddr=%s (err=%d)\n", __func__
, 
1941                                     ifp
->if_xname
, s_addr
, s_dstaddr
, err
); 
1944                 ifnet_free_address_list(ifap
); 
1945         } else if (err 
!= 0 && err 
!= ENXIO
) { 
1946                 printf("%s: error retrieving list of AF_INET addresses for " 
1947                     "ifp=%s (err=%d)\n", __func__
, ifp
->if_xname
, err
); 
1952  * Called as part of ip_init 
1955 in_ifaddr_init(void) 
1959         PE_parse_boot_argn("ifa_debug", &inifa_debug
, sizeof (inifa_debug
)); 
1961         inifa_size 
= (inifa_debug 
== 0) ? sizeof (struct in_ifaddr
) : 
1962             sizeof (struct in_ifaddr_dbg
); 
1964         inifa_zone 
= zinit(inifa_size
, INIFA_ZONE_MAX 
* inifa_size
, 
1965             0, INIFA_ZONE_NAME
); 
1966         if (inifa_zone 
== NULL
) { 
1967                 panic("%s: failed allocating %s", __func__
, INIFA_ZONE_NAME
); 
1970         zone_change(inifa_zone
, Z_EXPAND
, TRUE
); 
1971         zone_change(inifa_zone
, Z_CALLERACCT
, FALSE
); 
1973         lck_mtx_init(&inifa_trash_lock
, ifa_mtx_grp
, ifa_mtx_attr
); 
1974         TAILQ_INIT(&inifa_trash_head
); 
1977 static struct in_ifaddr 
* 
1978 in_ifaddr_alloc(int how
) 
1980         struct in_ifaddr 
*inifa
; 
1982         inifa 
= (how 
== M_WAITOK
) ? zalloc(inifa_zone
) : 
1983             zalloc_noblock(inifa_zone
); 
1984         if (inifa 
!= NULL
) { 
1985                 bzero(inifa
, inifa_size
); 
1986                 inifa
->ia_ifa
.ifa_free 
= in_ifaddr_free
; 
1987                 inifa
->ia_ifa
.ifa_debug 
|= IFD_ALLOC
; 
1988                 ifa_lock_init(&inifa
->ia_ifa
); 
1989                 if (inifa_debug 
!= 0) { 
1990                         struct in_ifaddr_dbg 
*inifa_dbg 
= 
1991                             (struct in_ifaddr_dbg 
*)inifa
; 
1992                         inifa
->ia_ifa
.ifa_debug 
|= IFD_DEBUG
; 
1993                         inifa
->ia_ifa
.ifa_trace 
= in_ifaddr_trace
; 
1994                         inifa
->ia_ifa
.ifa_attached 
= in_ifaddr_attached
; 
1995                         inifa
->ia_ifa
.ifa_detached 
= in_ifaddr_detached
; 
1996                         ctrace_record(&inifa_dbg
->inifa_alloc
); 
2003 in_ifaddr_free(struct ifaddr 
*ifa
) 
2005         IFA_LOCK_ASSERT_HELD(ifa
); 
2007         if (ifa
->ifa_refcnt 
!= 0) { 
2008                 panic("%s: ifa %p bad ref cnt", __func__
, ifa
); 
2010         } if (!(ifa
->ifa_debug 
& IFD_ALLOC
)) { 
2011                 panic("%s: ifa %p cannot be freed", __func__
, ifa
); 
2014         if (ifa
->ifa_debug 
& IFD_DEBUG
) { 
2015                 struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2016                 ctrace_record(&inifa_dbg
->inifa_free
); 
2017                 bcopy(&inifa_dbg
->inifa
, &inifa_dbg
->inifa_old
, 
2018                     sizeof (struct in_ifaddr
)); 
2019                 if (ifa
->ifa_debug 
& IFD_TRASHED
) { 
2020                         /* Become a regular mutex, just in case */ 
2021                         IFA_CONVERT_LOCK(ifa
); 
2022                         lck_mtx_lock(&inifa_trash_lock
); 
2023                         TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, 
2025                         lck_mtx_unlock(&inifa_trash_lock
); 
2026                         ifa
->ifa_debug 
&= ~IFD_TRASHED
; 
2030         ifa_lock_destroy(ifa
); 
2031         bzero(ifa
, sizeof (struct in_ifaddr
)); 
2032         zfree(inifa_zone
, ifa
); 
2036 in_ifaddr_attached(struct ifaddr 
*ifa
) 
2038         struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2040         IFA_LOCK_ASSERT_HELD(ifa
); 
2042         if (!(ifa
->ifa_debug 
& IFD_DEBUG
)) { 
2043                 panic("%s: ifa %p has no debug structure", __func__
, ifa
); 
2046         if (ifa
->ifa_debug 
& IFD_TRASHED
) { 
2047                 /* Become a regular mutex, just in case */ 
2048                 IFA_CONVERT_LOCK(ifa
); 
2049                 lck_mtx_lock(&inifa_trash_lock
); 
2050                 TAILQ_REMOVE(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
); 
2051                 lck_mtx_unlock(&inifa_trash_lock
); 
2052                 ifa
->ifa_debug 
&= ~IFD_TRASHED
; 
2057 in_ifaddr_detached(struct ifaddr 
*ifa
) 
2059         struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2061         IFA_LOCK_ASSERT_HELD(ifa
); 
2063         if (!(ifa
->ifa_debug 
& IFD_DEBUG
)) { 
2064                 panic("%s: ifa %p has no debug structure", __func__
, ifa
); 
2066         } else if (ifa
->ifa_debug 
& IFD_TRASHED
) { 
2067                 panic("%s: ifa %p is already in trash list", __func__
, ifa
); 
2070         ifa
->ifa_debug 
|= IFD_TRASHED
; 
2071         /* Become a regular mutex, just in case */ 
2072         IFA_CONVERT_LOCK(ifa
); 
2073         lck_mtx_lock(&inifa_trash_lock
); 
2074         TAILQ_INSERT_TAIL(&inifa_trash_head
, inifa_dbg
, inifa_trash_link
); 
2075         lck_mtx_unlock(&inifa_trash_lock
); 
2079 in_ifaddr_trace(struct ifaddr 
*ifa
, int refhold
) 
2081         struct in_ifaddr_dbg 
*inifa_dbg 
= (struct in_ifaddr_dbg 
*)ifa
; 
2086         if (!(ifa
->ifa_debug 
& IFD_DEBUG
)) { 
2087                 panic("%s: ifa %p has no debug structure", __func__
, ifa
); 
2091                 cnt 
= &inifa_dbg
->inifa_refhold_cnt
; 
2092                 tr 
= inifa_dbg
->inifa_refhold
; 
2094                 cnt 
= &inifa_dbg
->inifa_refrele_cnt
; 
2095                 tr 
= inifa_dbg
->inifa_refrele
; 
2098         idx 
= atomic_add_16_ov(cnt
, 1) % INIFA_TRACE_HIST_SIZE
; 
2099         ctrace_record(&tr
[idx
]); 
2103  * Handle SIOCGASSOCIDS ioctl for PF_INET domain. 
2106 in_getassocids(struct socket 
*so
, uint32_t *cnt
, user_addr_t aidp
) 
2108         struct inpcb 
*inp 
= sotoinpcb(so
); 
2111         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
2114         /* INPCB has no concept of association */ 
2115         aid 
= SAE_ASSOCID_ANY
; 
2118         /* just asking how many there are? */ 
2119         if (aidp 
== USER_ADDR_NULL
) 
2122         return (copyout(&aid
, aidp
, sizeof (aid
))); 
2126  * Handle SIOCGCONNIDS ioctl for PF_INET domain. 
2129 in_getconnids(struct socket 
*so
, sae_associd_t aid
, uint32_t *cnt
, 
2132         struct inpcb 
*inp 
= sotoinpcb(so
); 
2135         if (inp 
== NULL 
|| inp
->inp_state 
== INPCB_STATE_DEAD
) 
2138         if (aid 
!= SAE_ASSOCID_ANY 
&& aid 
!= SAE_ASSOCID_ALL
) 
2141         /* if connected, return 1 connection count */ 
2142         *cnt 
= ((so
->so_state 
& SS_ISCONNECTED
) ? 1 : 0); 
2144         /* just asking how many there are? */ 
2145         if (cidp 
== USER_ADDR_NULL
) 
2148         /* if INPCB is connected, assign it connid 1 */ 
2149         cid 
= ((*cnt 
!= 0) ? 1 : SAE_CONNID_ANY
); 
2151         return (copyout(&cid
, cidp
, sizeof (cid
))); 
2155  * Handle SIOCGCONNINFO ioctl for PF_INET domain. 
2158 in_getconninfo(struct socket 
*so
, sae_connid_t cid
, uint32_t *flags
, 
2159     uint32_t *ifindex
, int32_t *soerror
, user_addr_t src
, socklen_t 
*src_len
, 
2160     user_addr_t dst
, socklen_t 
*dst_len
, uint32_t *aux_type
, 
2161     user_addr_t aux_data
, uint32_t *aux_len
) 
2163         struct inpcb 
*inp 
= sotoinpcb(so
); 
2164         struct sockaddr_in sin
; 
2165         struct ifnet 
*ifp 
= NULL
; 
2167         u_int32_t copy_len 
= 0; 
2170          * Don't test for INPCB_STATE_DEAD since this may be called 
2171          * after SOF_PCBCLEARING is set, e.g. after tcp_close(). 
2178         if (cid 
!= SAE_CONNID_ANY 
&& cid 
!= SAE_CONNID_ALL 
&& cid 
!= 1) { 
2183         ifp 
= inp
->inp_last_outifp
; 
2184         *ifindex 
= ((ifp 
!= NULL
) ? ifp
->if_index 
: 0); 
2185         *soerror 
= so
->so_error
; 
2187         if (so
->so_state 
& SS_ISCONNECTED
) 
2188                 *flags 
|= (CIF_CONNECTED 
| CIF_PREFERRED
); 
2189         if (inp
->inp_flags 
& INP_BOUND_IF
) 
2190                 *flags 
|= CIF_BOUND_IF
; 
2191         if (!(inp
->inp_flags 
& INP_INADDR_ANY
)) 
2192                 *flags 
|= CIF_BOUND_IP
; 
2193         if (!(inp
->inp_flags 
& INP_ANONPORT
)) 
2194                 *flags 
|= CIF_BOUND_PORT
; 
2196         bzero(&sin
, sizeof (sin
)); 
2197         sin
.sin_len 
= sizeof (sin
); 
2198         sin
.sin_family 
= AF_INET
; 
2200         /* source address and port */ 
2201         sin
.sin_port 
= inp
->inp_lport
; 
2202         sin
.sin_addr
.s_addr 
= inp
->inp_laddr
.s_addr
; 
2203         if (*src_len 
== 0) { 
2204                 *src_len 
= sin
.sin_len
; 
2206                 if (src 
!= USER_ADDR_NULL
) { 
2207                         copy_len 
= min(*src_len
, sizeof (sin
)); 
2208                         error 
= copyout(&sin
, src
, copy_len
); 
2211                         *src_len 
= copy_len
; 
2215         /* destination address and port */ 
2216         sin
.sin_port 
= inp
->inp_fport
; 
2217         sin
.sin_addr
.s_addr 
= inp
->inp_faddr
.s_addr
; 
2218         if (*dst_len 
== 0) { 
2219                 *dst_len 
= sin
.sin_len
; 
2221                 if (dst 
!= USER_ADDR_NULL
) { 
2222                         copy_len 
= min(*dst_len
, sizeof (sin
)); 
2223                         error 
= copyout(&sin
, dst
, copy_len
); 
2226                         *dst_len 
= copy_len
; 
2230         if (SOCK_PROTO(so
) == IPPROTO_TCP
) { 
2231                 struct conninfo_tcp tcp_ci
; 
2233                 *aux_type 
= CIAUX_TCP
; 
2234                 if (*aux_len 
== 0) { 
2235                         *aux_len 
= sizeof (tcp_ci
); 
2237                         if (aux_data 
!= USER_ADDR_NULL
) { 
2238                                 copy_len 
= min(*aux_len
, sizeof (tcp_ci
)); 
2239                                 bzero(&tcp_ci
, sizeof (tcp_ci
)); 
2240                                 tcp_getconninfo(so
, &tcp_ci
); 
2241                                 error 
= copyout(&tcp_ci
, aux_data
, copy_len
); 
2244                                 *aux_len 
= copy_len
; 
2257         struct llentry          base
; 
2260 #define        IN_LLTBL_DEFAULT_HSIZE  32 
2261 #define        IN_LLTBL_HASH(k, h) \ 
2262     ((((((((k) >> 8) ^ (k)) >> 8) ^ (k)) >> 8) ^ (k)) & ((h) - 1)) 
2265  * Do actual deallocation of @lle. 
2268 in_lltable_destroy_lle_unlocked(struct llentry 
*lle
) 
2270         LLE_LOCK_DESTROY(lle
); 
2271         LLE_REQ_DESTROY(lle
); 
2272         FREE(lle
, M_LLTABLE
); 
2276  * Called by LLE_FREE_LOCKED when number of references 
2280 in_lltable_destroy_lle(struct llentry 
*lle
) 
2283         in_lltable_destroy_lle_unlocked(lle
); 
2286 static struct llentry 
* 
2287 in_lltable_new(struct in_addr addr4
, u_int flags
) 
2289 #pragma unused(flags) 
2290         struct in_llentry 
*lle
; 
2292         MALLOC(lle
, struct in_llentry 
*, sizeof(struct in_llentry
), M_LLTABLE
, M_NOWAIT 
| M_ZERO
); 
2293         if (lle 
== NULL
)                /* NB: caller generates msg */ 
2297          * For IPv4 this will trigger "arpresolve" to generate 
2300         lle
->base
.la_expire 
= net_uptime(); /* mark expired */ 
2301         lle
->base
.r_l3addr
.addr4 
= addr4
; 
2302         lle
->base
.lle_refcnt 
= 1; 
2303         lle
->base
.lle_free 
= in_lltable_destroy_lle
; 
2305         LLE_LOCK_INIT(&lle
->base
); 
2306         LLE_REQ_INIT(&lle
->base
); 
2307         //callout_init(&lle->base.lle_timer, 1); 
2309         return (&lle
->base
); 
2312 #define IN_ARE_MASKED_ADDR_EQUAL(d, a, m)      (               \ 
2313     ((((d).s_addr ^ (a).s_addr) & (m).s_addr)) == 0 ) 
2316 in_lltable_match_prefix(const struct sockaddr 
*saddr
, 
2317     const struct sockaddr 
*smask
, u_int flags
, struct llentry 
*lle
) 
2319         struct in_addr addr
, mask
, lle_addr
; 
2321         addr 
= ((const struct sockaddr_in 
*)(const void *)saddr
)->sin_addr
; 
2322         mask 
= ((const struct sockaddr_in 
*)(const void *)smask
)->sin_addr
; 
2323         lle_addr
.s_addr 
= ntohl(lle
->r_l3addr
.addr4
.s_addr
); 
2325         if (IN_ARE_MASKED_ADDR_EQUAL(lle_addr
, addr
, mask
) == 0) 
2328         if (lle
->la_flags 
& LLE_IFADDR
) { 
2330                  * Delete LLE_IFADDR records IFF address & flag matches. 
2331                  * Note that addr is the interface address within prefix 
2333                  * Note also we should handle 'ifdown' cases without removing 
2336                 if (addr
.s_addr 
== lle_addr
.s_addr 
&& (flags 
& LLE_STATIC
) != 0) 
2341         /* flags & LLE_STATIC means deleting both dynamic and static entries */ 
2342         if ((flags 
& LLE_STATIC
) || !(lle
->la_flags 
& LLE_STATIC
)) 
2349 in_lltable_free_entry(struct lltable 
*llt
, struct llentry 
*lle
) 
2352         size_t pkts_dropped
; 
2354         LLE_WLOCK_ASSERT(lle
); 
2355         KASSERT(llt 
!= NULL
, ("lltable is NULL")); 
2357         /* Unlink entry from table if not already */ 
2358         if ((lle
->la_flags 
& LLE_LINKED
) != 0) { 
2360                 IF_AFDATA_WLOCK_ASSERT(ifp
, llt
->llt_af
); 
2361                 lltable_unlink_entry(llt
, lle
); 
2366         if (callout_stop(&lle
->lle_timer
) > 0) 
2369         /* Drop hold queue */ 
2370         pkts_dropped 
= llentry_free(lle
); 
2371         arpstat
.dropped 
+= pkts_dropped
; 
2376 in_lltable_rtcheck(struct ifnet 
*ifp
, u_int flags
, const struct sockaddr 
*l3addr
) 
2378 #pragma unused(flags) 
2381         KASSERT(l3addr
->sa_family 
== AF_INET
, 
2382                         ("sin_family %d", l3addr
->sa_family
)); 
2384         /* XXX rtalloc1 should take a const param */ 
2385         rt 
= rtalloc1(__DECONST(struct sockaddr 
*, l3addr
), 0, 0); 
2386         if (rt 
== NULL 
|| (rt
->rt_flags 
& RTF_GATEWAY
) || rt
->rt_ifp 
!= ifp
) { 
2387                 log(LOG_INFO
, "IPv4 address: \"%s\" is not on the network\n", 
2388                                 inet_ntoa(((const struct sockaddr_in 
*)(const void *)l3addr
)->sin_addr
)); 
2397 static inline uint32_t 
2398 in_lltable_hash_dst(const struct in_addr dst
, uint32_t hsize
) 
2400         return (IN_LLTBL_HASH(dst
.s_addr
, hsize
)); 
2404 in_lltable_hash(const struct llentry 
*lle
, uint32_t hsize
) 
2406         return (in_lltable_hash_dst(lle
->r_l3addr
.addr4
, hsize
)); 
2411 in_lltable_fill_sa_entry(const struct llentry 
*lle
, struct sockaddr 
*sa
) 
2413         struct sockaddr_in 
*sin
; 
2415         sin 
= (struct sockaddr_in 
*)(void *)sa
; 
2416         bzero(sin
, sizeof(*sin
)); 
2417         sin
->sin_family 
= AF_INET
; 
2418         sin
->sin_len 
= sizeof(*sin
); 
2419         sin
->sin_addr 
= lle
->r_l3addr
.addr4
; 
2422 static inline struct llentry 
* 
2423 in_lltable_find_dst(struct lltable 
*llt
, struct in_addr dst
) 
2425         struct llentry 
*lle
; 
2426         struct llentries 
*lleh
; 
2429         hashidx 
= in_lltable_hash_dst(dst
, llt
->llt_hsize
); 
2430         lleh 
= &llt
->lle_head
[hashidx
]; 
2431         LIST_FOREACH(lle
, lleh
, lle_next
) { 
2432                 if (lle
->la_flags 
& LLE_DELETED
) 
2434                 if (lle
->r_l3addr
.addr4
.s_addr 
== dst
.s_addr
) 
2442 in_lltable_delete_entry(struct lltable 
*llt
, struct llentry 
*lle
) 
2445         lle
->la_flags 
|= LLE_DELETED
; 
2446         //EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED); 
2448         log(LOG_INFO
, "ifaddr cache = %p is deleted\n", lle
); 
2453 static struct llentry 
* 
2454 in_lltable_alloc(struct lltable 
*llt
, u_int flags
, const struct sockaddr 
*l3addr
) 
2456         const struct sockaddr_in 
*sin 
= (const struct sockaddr_in 
*) (const void *)l3addr
; 
2457         struct ifnet 
*ifp 
= llt
->llt_ifp
; 
2458         struct llentry 
*lle
; 
2460         KASSERT(l3addr
->sa_family 
== AF_INET
, 
2461                         ("sin_family %d", l3addr
->sa_family
)); 
2464          * A route that covers the given address must have 
2465          * been installed 1st because we are doing a resolution, 
2468         if (!(flags 
& LLE_IFADDR
) && 
2469                         in_lltable_rtcheck(ifp
, flags
, l3addr
) != 0) 
2472         lle 
= in_lltable_new(sin
->sin_addr
, flags
); 
2474                 log(LOG_INFO
, "lla_lookup: new lle malloc failed\n"); 
2477         lle
->la_flags 
= flags 
& ~LLE_CREATE
; 
2478         if (flags 
& LLE_STATIC
) 
2479                 lle
->r_flags 
|= RLLE_VALID
; 
2480         if ((flags 
& LLE_IFADDR
) == LLE_IFADDR
) { 
2481                 lltable_set_entry_addr(ifp
, lle
, LLADDR(SDL(ifp
->if_lladdr
->ifa_addr
))); 
2482                 lle
->la_flags 
|= LLE_STATIC
; 
2483                 lle
->r_flags 
|= (RLLE_VALID 
| RLLE_IFADDR
); 
2489  * Return NULL if not found or marked for deletion. 
2490  * If found return lle read locked. 
2492 static struct llentry 
* 
2493 in_lltable_lookup(struct lltable 
*llt
, u_int flags
, const struct sockaddr 
*l3addr
) 
2495         const struct sockaddr_in 
*sin 
= (const struct sockaddr_in 
*)(const void *)l3addr
; 
2496         struct llentry 
*lle
; 
2498         IF_AFDATA_WLOCK_ASSERT(llt
->llt_ifp
, llt
->llt_af
); 
2500         KASSERT(l3addr
->sa_family 
== AF_INET
, 
2501                         ("sin_family %d", l3addr
->sa_family
)); 
2502         lle 
= in_lltable_find_dst(llt
, sin
->sin_addr
); 
2507         KASSERT((flags 
& (LLE_UNLOCKED
|LLE_EXCLUSIVE
)) != 
2508             (LLE_UNLOCKED
|LLE_EXCLUSIVE
),("wrong lle request flags: 0x%X", 
2511         if (flags 
& LLE_UNLOCKED
) 
2514         if (flags 
& LLE_EXCLUSIVE
) 
2523 in_lltable_dump_entry(struct lltable 
*llt
, struct llentry 
*lle
, 
2524     struct sysctl_req 
*wr
) 
2526         struct ifnet 
*ifp 
= llt
->llt_ifp
; 
2529                 struct rt_msghdr        rtm
; 
2530                 struct sockaddr_in      sin
; 
2531                 struct sockaddr_dl      sdl
; 
2533         struct sockaddr_dl 
*sdl
; 
2536         bzero(&arpc
, sizeof(arpc
)); 
2537         /* skip deleted entries */ 
2538         if ((lle
->la_flags 
& LLE_DELETED
) == LLE_DELETED
) 
2540         /* Skip if jailed and not a valid IP of the prison. */ 
2541         lltable_fill_sa_entry(lle
,(struct sockaddr 
*)&arpc
.sin
); 
2543          * produce a msg made of: 
2545          *  struct sockaddr_in; (IPv4) 
2546          *  struct sockaddr_dl; 
2548         arpc
.rtm
.rtm_msglen 
= sizeof(arpc
); 
2549         arpc
.rtm
.rtm_version 
= RTM_VERSION
; 
2550         arpc
.rtm
.rtm_type 
= RTM_GET
; 
2551         arpc
.rtm
.rtm_flags 
= RTF_UP
; 
2552         arpc
.rtm
.rtm_addrs 
= RTA_DST 
| RTA_GATEWAY
; 
2555         if (lle
->la_flags 
& LLE_PUB
) 
2556                 arpc
.rtm
.rtm_flags 
|= RTF_ANNOUNCE
; 
2559         sdl
->sdl_family 
= AF_LINK
; 
2560         sdl
->sdl_len 
= sizeof(*sdl
); 
2561         sdl
->sdl_index 
= ifp
->if_index
; 
2562         sdl
->sdl_type 
= ifp
->if_type
; 
2563         if ((lle
->la_flags 
& LLE_VALID
) == LLE_VALID
) { 
2564                 sdl
->sdl_alen 
= ifp
->if_addrlen
; 
2565                 bcopy(&lle
->ll_addr
, LLADDR(sdl
), ifp
->if_addrlen
); 
2568                 bzero(LLADDR(sdl
), ifp
->if_addrlen
); 
2571         arpc
.rtm
.rtm_rmx
.rmx_expire 
= 
2572                 lle
->la_flags 
& LLE_STATIC 
? 0 : lle
->la_expire
; 
2573         arpc
.rtm
.rtm_flags 
|= (RTF_HOST 
| RTF_LLDATA
); 
2574         if (lle
->la_flags 
& LLE_STATIC
) 
2575                 arpc
.rtm
.rtm_flags 
|= RTF_STATIC
; 
2576         if (lle
->la_flags 
& LLE_IFADDR
) 
2577                 arpc
.rtm
.rtm_flags 
|= RTF_PINNED
; 
2578         arpc
.rtm
.rtm_flags 
|= RTF_PINNED
; 
2579         arpc
.rtm
.rtm_index 
= ifp
->if_index
; 
2580         error 
= SYSCTL_OUT(wr
, &arpc
, sizeof(arpc
)); 
2585 static struct lltable 
* 
2586 in_lltattach(struct ifnet 
*ifp
) 
2588         struct lltable 
*llt
; 
2590         llt 
= lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE
); 
2591         llt
->llt_af 
= AF_INET
; 
2594         llt
->llt_lookup 
= in_lltable_lookup
; 
2595         llt
->llt_alloc_entry 
= in_lltable_alloc
; 
2596         llt
->llt_delete_entry 
= in_lltable_delete_entry
; 
2597         llt
->llt_dump_entry 
= in_lltable_dump_entry
; 
2598         llt
->llt_hash 
= in_lltable_hash
; 
2599         llt
->llt_fill_sa_entry 
= in_lltable_fill_sa_entry
; 
2600         llt
->llt_free_entry 
= in_lltable_free_entry
; 
2601         llt
->llt_match_prefix 
= in_lltable_match_prefix
; 
2608 inifa_ifpwithflag(struct ifnet 
* ifp
, uint32_t flag
) 
2612         ifnet_lock_shared(ifp
); 
2613         TAILQ_FOREACH(ifa
, &ifp
->if_addrlist
, ifa_link
) 
2616                 if (ifa
->ifa_addr
->sa_family 
!= AF_INET
) { 
2620                 if ((((struct in_ifaddr 
*)ifa
)->ia_flags 
& flag
) == flag
) { 
2621                         IFA_ADDREF_LOCKED(ifa
); 
2627         ifnet_lock_done(ifp
); 
2629         return ((struct in_ifaddr 
*)ifa
); 
2633 inifa_ifpclatv4(struct ifnet 
* ifp
) 
2637         ifnet_lock_shared(ifp
); 
2638         TAILQ_FOREACH(ifa
, &ifp
->if_addrlist
, ifa_link
) 
2642                 if (ifa
->ifa_addr
->sa_family 
!= AF_INET
) { 
2647                 addr 
= ntohl(SIN(ifa
->ifa_addr
)->sin_addr
.s_addr
); 
2648                 if (!IN_LINKLOCAL(addr
) && 
2649                     !IN_LOOPBACK(addr
)) { 
2650                         IFA_ADDREF_LOCKED(ifa
); 
2656         ifnet_lock_done(ifp
); 
2658         return ((struct in_ifaddr 
*)ifa
);