]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/in.c
5f464c32581ca93a7415dbfde0f22901051a1ecf
[apple/xnu.git] / bsd / netinet / in.c
1 /*
2 * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (c) 1982, 1986, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
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.
47 *
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
58 * SUCH DAMAGE.
59 *
60 * @(#)in.c 8.4 (Berkeley) 1/9/95
61 */
62
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>
68 #include <sys/proc.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>
76 #include <sys/file.h>
77
78 #include <kern/zalloc.h>
79 #include <pexpert/pexpert.h>
80
81 #include <net/if.h>
82 #include <net/if_types.h>
83 #include <net/route.h>
84 #include <net/kpi_protocol.h>
85 #include <net/dlil.h>
86 #include <net/if_llatbl.h>
87 #include <net/if_arp.h>
88 #if PF
89 #include <net/pfvar.h>
90 #endif /* PF */
91
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>
101
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,
109 struct ifreq *);
110 static int inctl_ifdstaddr(struct ifnet *, struct in_ifaddr *, u_long,
111 struct ifreq *);
112 static int inctl_ifbrdaddr(struct ifnet *, struct in_ifaddr *, u_long,
113 struct ifreq *);
114 static int inctl_ifnetmask(struct ifnet *, struct in_ifaddr *, u_long,
115 struct ifreq *);
116
117 static void in_socktrim(struct sockaddr_in *);
118 static int in_ifinit(struct ifnet *, struct in_ifaddr *,
119 struct sockaddr_in *, int);
120
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; \
124 }
125
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))
129
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);
138
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);
141
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);
159
160 static int subnetsarelocal = 0;
161 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local,
162 CTLFLAG_RW | CTLFLAG_LOCKED, &subnetsarelocal, 0, "");
163
164 /* Track whether or not the SIOCARPIPLL ioctl has been called */
165 u_int32_t ipv4_ll_arp_aware = 0;
166
167 #define INIFA_TRACE_HIST_SIZE 32 /* size of trace history */
168
169 /* For gdb */
170 __private_extern__ unsigned int inifa_trace_hist_size = INIFA_TRACE_HIST_SIZE;
171
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 */
177 /*
178 * Alloc and free callers.
179 */
180 ctrace_t inifa_alloc;
181 ctrace_t inifa_free;
182 /*
183 * Circular lists of IFA_ADDREF and IFA_REMREF callers.
184 */
185 ctrace_t inifa_refhold[INIFA_TRACE_HIST_SIZE];
186 ctrace_t inifa_refrele[INIFA_TRACE_HIST_SIZE];
187 /*
188 * Trash list linkage
189 */
190 TAILQ_ENTRY(in_ifaddr_dbg) inifa_trash_link;
191 };
192
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);
196
197 #if DEBUG
198 static unsigned int inifa_debug = 1; /* debugging (enabled) */
199 #else
200 static unsigned int inifa_debug; /* debugging (disabled) */
201 #endif /* !DEBUG */
202 static unsigned int inifa_size; /* size of zone element */
203 static struct zone *inifa_zone; /* zone for in_ifaddr */
204
205 #define INIFA_ZONE_MAX 64 /* maximum elements in zone */
206 #define INIFA_ZONE_NAME "in_ifaddr" /* zone name */
207
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);
211
212 /*
213 * Return 1 if the address is
214 * - loopback
215 * - unicast or multicast link local
216 * - routed via a link level gateway
217 * - belongs to a directly connected (sub)net
218 */
219 int
220 inaddr_local(struct in_addr in)
221 {
222 struct rtentry *rt;
223 struct sockaddr_in sin;
224 int local = 0;
225
226 if (ntohl(in.s_addr) == INADDR_LOOPBACK ||
227 IN_LINKLOCAL(ntohl(in.s_addr))) {
228 local = 1;
229 } else if (ntohl(in.s_addr) >= INADDR_UNSPEC_GROUP &&
230 ntohl(in.s_addr) <= INADDR_MAX_LOCAL_GROUP) {
231 local = 1;
232 } else {
233 sin.sin_family = AF_INET;
234 sin.sin_len = sizeof(sin);
235 sin.sin_addr = in;
236 rt = rtalloc1((struct sockaddr *)&sin, 0, 0);
237
238 if (rt != NULL) {
239 RT_LOCK_SPIN(rt);
240 if (rt->rt_gateway->sa_family == AF_LINK ||
241 (rt->rt_ifp->if_flags & IFF_LOOPBACK)) {
242 local = 1;
243 }
244 RT_UNLOCK(rt);
245 rtfree(rt);
246 } else {
247 local = in_localaddr(in);
248 }
249 }
250 return local;
251 }
252
253 /*
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.
259 */
260 int
261 in_localaddr(struct in_addr in)
262 {
263 u_int32_t i = ntohl(in.s_addr);
264 struct in_ifaddr *ia;
265
266 if (IN_LINKLOCAL(i)) {
267 return 1;
268 }
269
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);
278 return 1;
279 }
280 IFA_UNLOCK(&ia->ia_ifa);
281 }
282 lck_rw_done(in_ifaddr_rwlock);
283 } else {
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);
291 return 1;
292 }
293 IFA_UNLOCK(&ia->ia_ifa);
294 }
295 lck_rw_done(in_ifaddr_rwlock);
296 }
297 return 0;
298 }
299
300 /*
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
303 * may be forwarded.
304 */
305 boolean_t
306 in_canforward(struct in_addr in)
307 {
308 u_int32_t i = ntohl(in.s_addr);
309 u_int32_t net;
310
311 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) {
312 return FALSE;
313 }
314 if (IN_CLASSA(i)) {
315 net = i & IN_CLASSA_NET;
316 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) {
317 return FALSE;
318 }
319 }
320 return TRUE;
321 }
322
323 /*
324 * Trim a mask in a sockaddr
325 */
326 static void
327 in_socktrim(struct sockaddr_in *ap)
328 {
329 char *cplim = (char *)&ap->sin_addr;
330 char *cp = (char *)(&ap->sin_addr + 1);
331
332 ap->sin_len = 0;
333 while (--cp >= cplim) {
334 if (*cp) {
335 (ap)->sin_len = cp - (char *)(ap) + 1;
336 break;
337 }
338 }
339 }
340
341 static int in_interfaces; /* number of external internet interfaces */
342
343 static int
344 in_domifattach(struct ifnet *ifp)
345 {
346 int error;
347
348 VERIFY(ifp != NULL);
349
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) {
354 void **pbuf, *base;
355 struct in_ifextra *ext;
356 int errorx;
357
358 if ((ext = (struct in_ifextra *)_MALLOC(in_extra_bufsize,
359 M_IFADDR, M_WAITOK | M_ZERO)) == NULL) {
360 error = ENOMEM;
361 errorx = proto_unplumb(PF_INET, ifp);
362 if (errorx != 0) {
363 log(LOG_ERR,
364 "%s: proto_unplumb returned %d if=%s%d\n",
365 __func__, errorx, ifp->if_name,
366 ifp->if_unit);
367 }
368 goto done;
369 }
370
371 /* Align on 64-bit boundary */
372 base = (void *)P2ROUNDUP((intptr_t)ext + sizeof(uint64_t),
373 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 *));
377 *pbuf = ext;
378 ifp->if_inetdata = base;
379 IN_IFEXTRA(ifp)->ii_llt = in_lltattach(ifp);
380 VERIFY(IS_P2ALIGNED(ifp->if_inetdata, sizeof(uint64_t)));
381 }
382 done:
383 if (error == 0 && ifp->if_inetdata != NULL) {
384 /*
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.
389 */
390 bzero(ifp->if_inetdata, in_extra_size);
391 }
392 return error;
393 }
394
395 static __attribute__((noinline)) int
396 inctl_associd(struct socket *so, u_long cmd, caddr_t data)
397 {
398 int error = 0;
399 union {
400 struct so_aidreq32 a32;
401 struct so_aidreq64 a64;
402 } u;
403
404 VERIFY(so != NULL);
405
406 switch (cmd) {
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);
410 if (error == 0) {
411 bcopy(&u.a32, data, sizeof(u.a32));
412 }
413 break;
414
415 case SIOCGASSOCIDS64: /* struct so_aidreq64 */
416 bcopy(data, &u.a64, sizeof(u.a64));
417 error = in_getassocids(so, &u.a64.sar_cnt, u.a64.sar_aidp);
418 if (error == 0) {
419 bcopy(&u.a64, data, sizeof(u.a64));
420 }
421 break;
422
423 default:
424 VERIFY(0);
425 /* NOTREACHED */
426 }
427
428 return error;
429 }
430
431 static __attribute__((noinline)) int
432 inctl_connid(struct socket *so, u_long cmd, caddr_t data)
433 {
434 int error = 0;
435 union {
436 struct so_cidreq32 c32;
437 struct so_cidreq64 c64;
438 } u;
439
440 VERIFY(so != NULL);
441
442 switch (cmd) {
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,
446 u.c32.scr_cidp);
447 if (error == 0) {
448 bcopy(&u.c32, data, sizeof(u.c32));
449 }
450 break;
451
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 u.c64.scr_cidp);
456 if (error == 0) {
457 bcopy(&u.c64, data, sizeof(u.c64));
458 }
459 break;
460
461 default:
462 VERIFY(0);
463 /* NOTREACHED */
464 }
465
466 return error;
467 }
468
469 static __attribute__((noinline)) int
470 inctl_conninfo(struct socket *so, u_long cmd, caddr_t data)
471 {
472 int error = 0;
473 union {
474 struct so_cinforeq32 ci32;
475 struct so_cinforeq64 ci64;
476 } u;
477
478 VERIFY(so != NULL);
479
480 switch (cmd) {
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);
488 if (error == 0) {
489 bcopy(&u.ci32, data, sizeof(u.ci32));
490 }
491 break;
492
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, u.ci64.scir_src,
497 &u.ci64.scir_src_len, u.ci64.scir_dst, &u.ci64.scir_dst_len,
498 &u.ci64.scir_aux_type, u.ci64.scir_aux_data,
499 &u.ci64.scir_aux_len);
500 if (error == 0) {
501 bcopy(&u.ci64, data, sizeof(u.ci64));
502 }
503 break;
504
505 default:
506 VERIFY(0);
507 /* NOTREACHED */
508 }
509
510 return error;
511 }
512
513 /*
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
516 * memory accesses.
517 */
518 static __attribute__((noinline)) int
519 inctl_autoaddr(struct ifnet *ifp, struct ifreq *ifr)
520 {
521 int error = 0, intval;
522
523 VERIFY(ifp != NULL);
524
525 bcopy(&ifr->ifr_intval, &intval, sizeof(intval));
526
527 ifnet_lock_exclusive(ifp);
528 if (intval) {
529 /*
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.
534 */
535 if (ifp->if_eflags & IFEF_IPV4_ROUTER) {
536 intval = 0; /* be safe; clear flag if set */
537 error = EBUSY;
538 } else {
539 ifp->if_eflags |= IFEF_AUTOCONFIGURING;
540 }
541 }
542 if (!intval) {
543 ifp->if_eflags &= ~IFEF_AUTOCONFIGURING;
544 }
545 ifnet_lock_done(ifp);
546
547 return error;
548 }
549
550 /*
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
553 * memory accesses.
554 */
555 static __attribute__((noinline)) int
556 inctl_arpipll(struct ifnet *ifp, struct ifreq *ifr)
557 {
558 int error = 0, intval;
559
560 VERIFY(ifp != NULL);
561
562 bcopy(&ifr->ifr_intval, &intval, sizeof(intval));
563 ipv4_ll_arp_aware = 1;
564
565 ifnet_lock_exclusive(ifp);
566 if (intval) {
567 /*
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.
572 */
573 if (ifp->if_eflags & IFEF_IPV4_ROUTER) {
574 intval = 0; /* be safe; clear flag if set */
575 error = EBUSY;
576 } else {
577 ifp->if_eflags |= IFEF_ARPLL;
578 }
579 }
580 if (!intval) {
581 ifp->if_eflags &= ~IFEF_ARPLL;
582 }
583 ifnet_lock_done(ifp);
584
585 return error;
586 }
587
588 /*
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
594 * on the interface.
595 *
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
598 * memory accesses.
599 */
600 static __attribute__((noinline)) int
601 inctl_setrouter(struct ifnet *ifp, struct ifreq *ifr)
602 {
603 int error = 0, intval;
604
605 VERIFY(ifp != NULL);
606
607 /* Router mode isn't valid for loopback */
608 if (ifp->if_flags & IFF_LOOPBACK) {
609 return ENODEV;
610 }
611
612 bcopy(&ifr->ifr_intval, &intval, sizeof(intval));
613
614 ifnet_lock_exclusive(ifp);
615 if (intval) {
616 ifp->if_eflags |= IFEF_IPV4_ROUTER;
617 ifp->if_eflags &= ~(IFEF_ARPLL | IFEF_AUTOCONFIGURING);
618 } else {
619 ifp->if_eflags &= ~IFEF_IPV4_ROUTER;
620 }
621 ifnet_lock_done(ifp);
622
623 /* purge all IPv4 addresses configured on this interface */
624 in_purgeaddrs(ifp);
625
626 return error;
627 }
628
629 /*
630 * Caller passes in the ioctl data pointer directly via "ifr", with the
631 * expectation that this routine always uses bcopy() or other byte-aligned
632 * memory accesses.
633 */
634 static __attribute__((noinline)) int
635 inctl_ifaddr(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
636 struct ifreq *ifr)
637 {
638 struct kev_in_data in_event_data;
639 struct kev_msg ev_msg;
640 struct sockaddr_in addr;
641 struct ifaddr *ifa;
642 int error = 0;
643
644 VERIFY(ifp != NULL);
645
646 bzero(&in_event_data, sizeof(struct kev_in_data));
647 bzero(&ev_msg, sizeof(struct kev_msg));
648
649 switch (cmd) {
650 case SIOCGIFADDR: /* struct ifreq */
651 if (ia == NULL) {
652 error = EADDRNOTAVAIL;
653 break;
654 }
655 IFA_LOCK(&ia->ia_ifa);
656 bcopy(&ia->ia_addr, &ifr->ifr_addr, sizeof(addr));
657 IFA_UNLOCK(&ia->ia_ifa);
658 break;
659
660 case SIOCSIFADDR: /* struct ifreq */
661 VERIFY(ia != NULL);
662 bcopy(&ifr->ifr_addr, &addr, sizeof(addr));
663 /*
664 * If this is a new address, the reference count for the
665 * hash table has been taken at creation time above.
666 */
667 error = in_ifinit(ifp, ia, &addr, 1);
668 if (error == 0) {
669 (void) ifnet_notify_address(ifp, AF_INET);
670 }
671 break;
672
673 case SIOCAIFADDR: { /* struct {if,in_}aliasreq */
674 struct in_aliasreq *ifra = (struct in_aliasreq *)ifr;
675 struct sockaddr_in broadaddr, mask;
676 int hostIsNew, maskIsNew;
677
678 VERIFY(ia != NULL);
679 bcopy(&ifra->ifra_addr, &addr, sizeof(addr));
680 bcopy(&ifra->ifra_broadaddr, &broadaddr, sizeof(broadaddr));
681 bcopy(&ifra->ifra_mask, &mask, sizeof(mask));
682
683 maskIsNew = 0;
684 hostIsNew = 1;
685 error = 0;
686
687 IFA_LOCK(&ia->ia_ifa);
688 if (ia->ia_addr.sin_family == AF_INET) {
689 if (addr.sin_len == 0) {
690 addr = ia->ia_addr;
691 hostIsNew = 0;
692 } else if (addr.sin_addr.s_addr ==
693 ia->ia_addr.sin_addr.s_addr) {
694 hostIsNew = 0;
695 }
696 }
697 if (mask.sin_len) {
698 IFA_UNLOCK(&ia->ia_ifa);
699 in_ifscrub(ifp, ia, 0);
700 IFA_LOCK(&ia->ia_ifa);
701 ia->ia_sockmask = mask;
702 ia->ia_subnetmask =
703 ntohl(ia->ia_sockmask.sin_addr.s_addr);
704 maskIsNew = 1;
705 }
706 if ((ifp->if_flags & IFF_POINTOPOINT) &&
707 (broadaddr.sin_family == AF_INET)) {
708 IFA_UNLOCK(&ia->ia_ifa);
709 in_ifscrub(ifp, ia, 0);
710 IFA_LOCK(&ia->ia_ifa);
711 ia->ia_dstaddr = broadaddr;
712 ia->ia_dstaddr.sin_len = sizeof(struct sockaddr_in);
713 maskIsNew = 1; /* We lie; but the effect's the same */
714 }
715 if (addr.sin_family == AF_INET && (hostIsNew || maskIsNew)) {
716 IFA_UNLOCK(&ia->ia_ifa);
717 error = in_ifinit(ifp, ia, &addr, 0);
718 } else {
719 IFA_UNLOCK(&ia->ia_ifa);
720 }
721 if (error == 0) {
722 (void) ifnet_notify_address(ifp, AF_INET);
723 }
724 IFA_LOCK(&ia->ia_ifa);
725 if ((ifp->if_flags & IFF_BROADCAST) &&
726 (broadaddr.sin_family == AF_INET)) {
727 ia->ia_broadaddr = broadaddr;
728 }
729
730 /*
731 * Report event.
732 */
733 if ((error == 0) || (error == EEXIST)) {
734 ev_msg.vendor_code = KEV_VENDOR_APPLE;
735 ev_msg.kev_class = KEV_NETWORK_CLASS;
736 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
737
738 if (hostIsNew) {
739 ev_msg.event_code = KEV_INET_NEW_ADDR;
740 } else {
741 ev_msg.event_code = KEV_INET_CHANGED_ADDR;
742 }
743
744 if (ia->ia_ifa.ifa_dstaddr) {
745 in_event_data.ia_dstaddr =
746 ((struct sockaddr_in *)(void *)ia->
747 ia_ifa.ifa_dstaddr)->sin_addr;
748 } else {
749 in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
750 }
751 in_event_data.ia_addr = ia->ia_addr.sin_addr;
752 in_event_data.ia_net = ia->ia_net;
753 in_event_data.ia_netmask = ia->ia_netmask;
754 in_event_data.ia_subnet = ia->ia_subnet;
755 in_event_data.ia_subnetmask = ia->ia_subnetmask;
756 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
757 IFA_UNLOCK(&ia->ia_ifa);
758 (void) strlcpy(&in_event_data.link_data.if_name[0],
759 ifp->if_name, IFNAMSIZ);
760 in_event_data.link_data.if_family = ifp->if_family;
761 in_event_data.link_data.if_unit = ifp->if_unit;
762
763 ev_msg.dv[0].data_ptr = &in_event_data;
764 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
765 ev_msg.dv[1].data_length = 0;
766
767 dlil_post_complete_msg(ifp, &ev_msg);
768 } else {
769 IFA_UNLOCK(&ia->ia_ifa);
770 }
771 break;
772 }
773
774 case SIOCDIFADDR: /* struct ifreq */
775 VERIFY(ia != NULL);
776 error = ifnet_ioctl(ifp, PF_INET, SIOCDIFADDR, ia);
777 if (error == EOPNOTSUPP) {
778 error = 0;
779 }
780 if (error != 0) {
781 /* Reset the detaching flag */
782 IFA_LOCK(&ia->ia_ifa);
783 ia->ia_ifa.ifa_debug &= ~IFD_DETACHING;
784 IFA_UNLOCK(&ia->ia_ifa);
785 break;
786 }
787
788 /* Fill out the kernel event information */
789 ev_msg.vendor_code = KEV_VENDOR_APPLE;
790 ev_msg.kev_class = KEV_NETWORK_CLASS;
791 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
792
793 ev_msg.event_code = KEV_INET_ADDR_DELETED;
794
795 IFA_LOCK(&ia->ia_ifa);
796 if (ia->ia_ifa.ifa_dstaddr) {
797 in_event_data.ia_dstaddr = ((struct sockaddr_in *)
798 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
799 } else {
800 in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
801 }
802 in_event_data.ia_addr = ia->ia_addr.sin_addr;
803 in_event_data.ia_net = ia->ia_net;
804 in_event_data.ia_netmask = ia->ia_netmask;
805 in_event_data.ia_subnet = ia->ia_subnet;
806 in_event_data.ia_subnetmask = ia->ia_subnetmask;
807 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
808 IFA_UNLOCK(&ia->ia_ifa);
809 (void) strlcpy(&in_event_data.link_data.if_name[0],
810 ifp->if_name, IFNAMSIZ);
811 in_event_data.link_data.if_family = ifp->if_family;
812 in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
813
814 ev_msg.dv[0].data_ptr = &in_event_data;
815 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
816 ev_msg.dv[1].data_length = 0;
817
818 ifa = &ia->ia_ifa;
819 lck_rw_lock_exclusive(in_ifaddr_rwlock);
820 /* Release ia_link reference */
821 IFA_REMREF(ifa);
822 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link);
823 IFA_LOCK(ifa);
824 if (IA_IS_HASHED(ia)) {
825 in_iahash_remove(ia);
826 }
827 IFA_UNLOCK(ifa);
828 lck_rw_done(in_ifaddr_rwlock);
829
830 /*
831 * in_ifscrub kills the interface route.
832 */
833 in_ifscrub(ifp, ia, 0);
834 ifnet_lock_exclusive(ifp);
835 IFA_LOCK(ifa);
836 /* if_detach_ifa() releases ifa_link reference */
837 if_detach_ifa(ifp, ifa);
838 /* Our reference to this address is dropped at the bottom */
839 IFA_UNLOCK(ifa);
840
841 /* invalidate route caches */
842 routegenid_inet_update();
843
844 /*
845 * If the interface supports multicast, and no address is left,
846 * remove the "all hosts" multicast group from that interface.
847 */
848 if ((ifp->if_flags & IFF_MULTICAST) ||
849 ifp->if_allhostsinm != NULL) {
850 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
851 IFA_LOCK(ifa);
852 if (ifa->ifa_addr->sa_family == AF_INET) {
853 IFA_UNLOCK(ifa);
854 break;
855 }
856 IFA_UNLOCK(ifa);
857 }
858 ifnet_lock_done(ifp);
859
860 lck_mtx_lock(&ifp->if_addrconfig_lock);
861 if (ifa == NULL && ifp->if_allhostsinm != NULL) {
862 struct in_multi *inm = ifp->if_allhostsinm;
863 ifp->if_allhostsinm = NULL;
864
865 in_delmulti(inm);
866 /* release the reference for allhostsinm */
867 INM_REMREF(inm);
868 }
869 lck_mtx_unlock(&ifp->if_addrconfig_lock);
870 } else {
871 ifnet_lock_done(ifp);
872 }
873
874 /* Post the kernel event */
875 dlil_post_complete_msg(ifp, &ev_msg);
876
877 /*
878 * See if there is any IPV4 address left and if so,
879 * reconfigure KDP to use current primary address.
880 */
881 ifa = ifa_ifpgetprimary(ifp, AF_INET);
882 if (ifa != NULL) {
883 /*
884 * NOTE: SIOCSIFADDR is defined with struct ifreq
885 * as parameter, but here we are sending it down
886 * to the interface with a pointer to struct ifaddr,
887 * for legacy reasons.
888 */
889 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa);
890 if (error == EOPNOTSUPP) {
891 error = 0;
892 }
893
894 /* Release reference from ifa_ifpgetprimary() */
895 IFA_REMREF(ifa);
896 }
897 (void) ifnet_notify_address(ifp, AF_INET);
898 break;
899
900 default:
901 VERIFY(0);
902 /* NOTREACHED */
903 }
904
905 return error;
906 }
907
908 /*
909 * Caller passes in the ioctl data pointer directly via "ifr", with the
910 * expectation that this routine always uses bcopy() or other byte-aligned
911 * memory accesses.
912 */
913 static __attribute__((noinline)) int
914 inctl_ifdstaddr(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
915 struct ifreq *ifr)
916 {
917 struct kev_in_data in_event_data;
918 struct kev_msg ev_msg;
919 struct sockaddr_in dstaddr;
920 int error = 0;
921
922 VERIFY(ifp != NULL);
923
924 if (!(ifp->if_flags & IFF_POINTOPOINT)) {
925 return EINVAL;
926 }
927
928 bzero(&in_event_data, sizeof(struct kev_in_data));
929 bzero(&ev_msg, sizeof(struct kev_msg));
930
931 switch (cmd) {
932 case SIOCGIFDSTADDR: /* struct ifreq */
933 if (ia == NULL) {
934 error = EADDRNOTAVAIL;
935 break;
936 }
937 IFA_LOCK(&ia->ia_ifa);
938 bcopy(&ia->ia_dstaddr, &ifr->ifr_dstaddr, sizeof(dstaddr));
939 IFA_UNLOCK(&ia->ia_ifa);
940 break;
941
942 case SIOCSIFDSTADDR: /* struct ifreq */
943 VERIFY(ia != NULL);
944 IFA_LOCK(&ia->ia_ifa);
945 dstaddr = ia->ia_dstaddr;
946 bcopy(&ifr->ifr_dstaddr, &ia->ia_dstaddr, sizeof(dstaddr));
947 if (ia->ia_dstaddr.sin_family == AF_INET) {
948 ia->ia_dstaddr.sin_len = sizeof(struct sockaddr_in);
949 }
950 IFA_UNLOCK(&ia->ia_ifa);
951 /*
952 * NOTE: SIOCSIFDSTADDR is defined with struct ifreq
953 * as parameter, but here we are sending it down
954 * to the interface with a pointer to struct ifaddr,
955 * for legacy reasons.
956 */
957 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFDSTADDR, ia);
958 IFA_LOCK(&ia->ia_ifa);
959 if (error == EOPNOTSUPP) {
960 error = 0;
961 }
962 if (error != 0) {
963 ia->ia_dstaddr = dstaddr;
964 IFA_UNLOCK(&ia->ia_ifa);
965 break;
966 }
967 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
968
969 ev_msg.vendor_code = KEV_VENDOR_APPLE;
970 ev_msg.kev_class = KEV_NETWORK_CLASS;
971 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
972
973 ev_msg.event_code = KEV_INET_SIFDSTADDR;
974
975 if (ia->ia_ifa.ifa_dstaddr) {
976 in_event_data.ia_dstaddr = ((struct sockaddr_in *)
977 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
978 } else {
979 in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
980 }
981
982 in_event_data.ia_addr = ia->ia_addr.sin_addr;
983 in_event_data.ia_net = ia->ia_net;
984 in_event_data.ia_netmask = ia->ia_netmask;
985 in_event_data.ia_subnet = ia->ia_subnet;
986 in_event_data.ia_subnetmask = ia->ia_subnetmask;
987 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
988 IFA_UNLOCK(&ia->ia_ifa);
989 (void) strlcpy(&in_event_data.link_data.if_name[0],
990 ifp->if_name, IFNAMSIZ);
991 in_event_data.link_data.if_family = ifp->if_family;
992 in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
993
994 ev_msg.dv[0].data_ptr = &in_event_data;
995 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
996 ev_msg.dv[1].data_length = 0;
997
998 dlil_post_complete_msg(ifp, &ev_msg);
999
1000 lck_mtx_lock(rnh_lock);
1001 IFA_LOCK(&ia->ia_ifa);
1002 if (ia->ia_flags & IFA_ROUTE) {
1003 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&dstaddr;
1004 IFA_UNLOCK(&ia->ia_ifa);
1005 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1006 IFA_LOCK(&ia->ia_ifa);
1007 ia->ia_ifa.ifa_dstaddr =
1008 (struct sockaddr *)&ia->ia_dstaddr;
1009 IFA_UNLOCK(&ia->ia_ifa);
1010 rtinit_locked(&(ia->ia_ifa), (int)RTM_ADD,
1011 RTF_HOST | RTF_UP);
1012 } else {
1013 IFA_UNLOCK(&ia->ia_ifa);
1014 }
1015 lck_mtx_unlock(rnh_lock);
1016 break;
1017
1018
1019
1020 default:
1021 VERIFY(0);
1022 /* NOTREACHED */
1023 }
1024
1025 return error;
1026 }
1027
1028 /*
1029 * Caller passes in the ioctl data pointer directly via "ifr", with the
1030 * expectation that this routine always uses bcopy() or other byte-aligned
1031 * memory accesses.
1032 */
1033 static __attribute__((noinline)) int
1034 inctl_ifbrdaddr(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
1035 struct ifreq *ifr)
1036 {
1037 struct kev_in_data in_event_data;
1038 struct kev_msg ev_msg;
1039 int error = 0;
1040
1041 VERIFY(ifp != NULL);
1042
1043 if (ia == NULL) {
1044 return EADDRNOTAVAIL;
1045 }
1046
1047 if (!(ifp->if_flags & IFF_BROADCAST)) {
1048 return EINVAL;
1049 }
1050
1051 bzero(&in_event_data, sizeof(struct kev_in_data));
1052 bzero(&ev_msg, sizeof(struct kev_msg));
1053
1054 switch (cmd) {
1055 case SIOCGIFBRDADDR: /* struct ifreq */
1056 IFA_LOCK(&ia->ia_ifa);
1057 bcopy(&ia->ia_broadaddr, &ifr->ifr_broadaddr,
1058 sizeof(struct sockaddr_in));
1059 IFA_UNLOCK(&ia->ia_ifa);
1060 break;
1061
1062 case SIOCSIFBRDADDR: /* struct ifreq */
1063 IFA_LOCK(&ia->ia_ifa);
1064 bcopy(&ifr->ifr_broadaddr, &ia->ia_broadaddr,
1065 sizeof(struct sockaddr_in));
1066
1067 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1068 ev_msg.kev_class = KEV_NETWORK_CLASS;
1069 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
1070
1071 ev_msg.event_code = KEV_INET_SIFBRDADDR;
1072
1073 if (ia->ia_ifa.ifa_dstaddr) {
1074 in_event_data.ia_dstaddr = ((struct sockaddr_in *)
1075 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
1076 } else {
1077 in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
1078 }
1079 in_event_data.ia_addr = ia->ia_addr.sin_addr;
1080 in_event_data.ia_net = ia->ia_net;
1081 in_event_data.ia_netmask = ia->ia_netmask;
1082 in_event_data.ia_subnet = ia->ia_subnet;
1083 in_event_data.ia_subnetmask = ia->ia_subnetmask;
1084 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
1085 IFA_UNLOCK(&ia->ia_ifa);
1086 (void) strlcpy(&in_event_data.link_data.if_name[0],
1087 ifp->if_name, IFNAMSIZ);
1088 in_event_data.link_data.if_family = ifp->if_family;
1089 in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
1090
1091 ev_msg.dv[0].data_ptr = &in_event_data;
1092 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
1093 ev_msg.dv[1].data_length = 0;
1094
1095 dlil_post_complete_msg(ifp, &ev_msg);
1096 break;
1097
1098 default:
1099 VERIFY(0);
1100 /* NOTREACHED */
1101 }
1102
1103 return error;
1104 }
1105
1106 /*
1107 * Caller passes in the ioctl data pointer directly via "ifr", with the
1108 * expectation that this routine always uses bcopy() or other byte-aligned
1109 * memory accesses.
1110 */
1111 static __attribute__((noinline)) int
1112 inctl_ifnetmask(struct ifnet *ifp, struct in_ifaddr *ia, u_long cmd,
1113 struct ifreq *ifr)
1114 {
1115 struct kev_in_data in_event_data;
1116 struct kev_msg ev_msg;
1117 struct sockaddr_in mask;
1118 int error = 0;
1119
1120 VERIFY(ifp != NULL);
1121
1122 bzero(&in_event_data, sizeof(struct kev_in_data));
1123 bzero(&ev_msg, sizeof(struct kev_msg));
1124
1125 switch (cmd) {
1126 case SIOCGIFNETMASK: /* struct ifreq */
1127 if (ia == NULL) {
1128 error = EADDRNOTAVAIL;
1129 break;
1130 }
1131 IFA_LOCK(&ia->ia_ifa);
1132 bcopy(&ia->ia_sockmask, &ifr->ifr_addr, sizeof(mask));
1133 IFA_UNLOCK(&ia->ia_ifa);
1134 break;
1135
1136 case SIOCSIFNETMASK: { /* struct ifreq */
1137 in_addr_t i;
1138
1139 bcopy(&ifr->ifr_addr, &mask, sizeof(mask));
1140 i = mask.sin_addr.s_addr;
1141
1142 VERIFY(ia != NULL);
1143 IFA_LOCK(&ia->ia_ifa);
1144 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
1145 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1146 ev_msg.kev_class = KEV_NETWORK_CLASS;
1147 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
1148
1149 ev_msg.event_code = KEV_INET_SIFNETMASK;
1150
1151 if (ia->ia_ifa.ifa_dstaddr) {
1152 in_event_data.ia_dstaddr = ((struct sockaddr_in *)
1153 (void *)ia->ia_ifa.ifa_dstaddr)->sin_addr;
1154 } else {
1155 in_event_data.ia_dstaddr.s_addr = INADDR_ANY;
1156 }
1157 in_event_data.ia_addr = ia->ia_addr.sin_addr;
1158 in_event_data.ia_net = ia->ia_net;
1159 in_event_data.ia_netmask = ia->ia_netmask;
1160 in_event_data.ia_subnet = ia->ia_subnet;
1161 in_event_data.ia_subnetmask = ia->ia_subnetmask;
1162 in_event_data.ia_netbroadcast = ia->ia_netbroadcast;
1163 IFA_UNLOCK(&ia->ia_ifa);
1164 (void) strlcpy(&in_event_data.link_data.if_name[0],
1165 ifp->if_name, IFNAMSIZ);
1166 in_event_data.link_data.if_family = ifp->if_family;
1167 in_event_data.link_data.if_unit = (u_int32_t)ifp->if_unit;
1168
1169 ev_msg.dv[0].data_ptr = &in_event_data;
1170 ev_msg.dv[0].data_length = sizeof(struct kev_in_data);
1171 ev_msg.dv[1].data_length = 0;
1172
1173 dlil_post_complete_msg(ifp, &ev_msg);
1174 break;
1175 }
1176
1177 default:
1178 VERIFY(0);
1179 /* NOTREACHED */
1180 }
1181
1182 return error;
1183 }
1184
1185 /*
1186 * Generic INET control operations (ioctl's).
1187 *
1188 * ifp is NULL if not an interface-specific ioctl.
1189 *
1190 * Most of the routines called to handle the ioctls would end up being
1191 * tail-call optimized, which unfortunately causes this routine to
1192 * consume too much stack space; this is the reason for the "noinline"
1193 * attribute used on those routines.
1194 *
1195 * If called directly from within the networking stack (as opposed to via
1196 * pru_control), the socket parameter may be NULL.
1197 */
1198 int
1199 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
1200 struct proc *p)
1201 {
1202 struct ifreq *ifr = (struct ifreq *)(void *)data;
1203 struct sockaddr_in addr, dstaddr;
1204 struct sockaddr_in sin, *sa = NULL;
1205 boolean_t privileged = (proc_suser(p) == 0);
1206 boolean_t so_unlocked = FALSE;
1207 struct in_ifaddr *ia = NULL;
1208 struct ifaddr *ifa;
1209 int error = 0;
1210
1211 /* In case it's NULL, make sure it came from the kernel */
1212 VERIFY(so != NULL || p == kernproc);
1213
1214 /*
1215 * ioctls which don't require ifp, but require socket.
1216 */
1217 switch (cmd) {
1218 case SIOCGASSOCIDS32: /* struct so_aidreq32 */
1219 case SIOCGASSOCIDS64: /* struct so_aidreq64 */
1220 return inctl_associd(so, cmd, data);
1221 /* NOTREACHED */
1222
1223 case SIOCGCONNIDS32: /* struct so_cidreq32 */
1224 case SIOCGCONNIDS64: /* struct so_cidreq64 */
1225 return inctl_connid(so, cmd, data);
1226 /* NOTREACHED */
1227
1228 case SIOCGCONNINFO32: /* struct so_cinforeq32 */
1229 case SIOCGCONNINFO64: /* struct so_cinforeq64 */
1230 return inctl_conninfo(so, cmd, data);
1231 /* NOTREACHED */
1232 }
1233
1234 /*
1235 * The rest of ioctls require ifp; reject if we don't have one;
1236 * return ENXIO to be consistent with ifioctl().
1237 */
1238 if (ifp == NULL) {
1239 return ENXIO;
1240 }
1241
1242 /*
1243 * ioctls which require ifp but not interface address.
1244 */
1245 switch (cmd) {
1246 case SIOCAUTOADDR: /* struct ifreq */
1247 if (!privileged) {
1248 return EPERM;
1249 }
1250 return inctl_autoaddr(ifp, ifr);
1251 /* NOTREACHED */
1252
1253 case SIOCARPIPLL: /* struct ifreq */
1254 if (!privileged) {
1255 return EPERM;
1256 }
1257 return inctl_arpipll(ifp, ifr);
1258 /* NOTREACHED */
1259
1260 case SIOCSETROUTERMODE: /* struct ifreq */
1261 if (!privileged) {
1262 return EPERM;
1263 }
1264 return inctl_setrouter(ifp, ifr);
1265 /* NOTREACHED */
1266
1267 case SIOCPROTOATTACH: /* struct ifreq */
1268 if (!privileged) {
1269 return EPERM;
1270 }
1271 return in_domifattach(ifp);
1272 /* NOTREACHED */
1273
1274 case SIOCPROTODETACH: /* struct ifreq */
1275 if (!privileged) {
1276 return EPERM;
1277 }
1278
1279 /*
1280 * If an IPv4 address is still present, refuse to detach.
1281 */
1282 ifnet_lock_shared(ifp);
1283 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1284 IFA_LOCK(ifa);
1285 if (ifa->ifa_addr->sa_family == AF_INET) {
1286 IFA_UNLOCK(ifa);
1287 break;
1288 }
1289 IFA_UNLOCK(ifa);
1290 }
1291 ifnet_lock_done(ifp);
1292 return (ifa == NULL) ? proto_unplumb(PF_INET, ifp) : EBUSY;
1293 /* NOTREACHED */
1294 }
1295
1296 /*
1297 * ioctls which require interface address; obtain sockaddr_in.
1298 */
1299 switch (cmd) {
1300 case SIOCAIFADDR: /* struct {if,in_}aliasreq */
1301 if (!privileged) {
1302 return EPERM;
1303 }
1304 bcopy(&((struct in_aliasreq *)(void *)data)->ifra_addr,
1305 &sin, sizeof(sin));
1306 sa = &sin;
1307 break;
1308
1309 case SIOCDIFADDR: /* struct ifreq */
1310 case SIOCSIFADDR: /* struct ifreq */
1311 case SIOCSIFDSTADDR: /* struct ifreq */
1312 case SIOCSIFNETMASK: /* struct ifreq */
1313 case SIOCSIFBRDADDR: /* struct ifreq */
1314 if (!privileged) {
1315 return EPERM;
1316 }
1317 /* FALLTHRU */
1318 case SIOCGIFADDR: /* struct ifreq */
1319 case SIOCGIFDSTADDR: /* struct ifreq */
1320 case SIOCGIFNETMASK: /* struct ifreq */
1321 case SIOCGIFBRDADDR: /* struct ifreq */
1322 bcopy(&ifr->ifr_addr, &sin, sizeof(sin));
1323 sa = &sin;
1324 break;
1325 }
1326
1327 /*
1328 * Find address for this interface, if it exists.
1329 *
1330 * If an alias address was specified, find that one instead of
1331 * the first one on the interface, if possible.
1332 */
1333 VERIFY(ia == NULL);
1334 if (sa != NULL) {
1335 struct in_ifaddr *iap;
1336
1337 /*
1338 * Any failures from this point on must take into account
1339 * a non-NULL "ia" with an outstanding reference count, and
1340 * therefore requires IFA_REMREF. Jump to "done" label
1341 * instead of calling return if "ia" is valid.
1342 */
1343 lck_rw_lock_shared(in_ifaddr_rwlock);
1344 TAILQ_FOREACH(iap, INADDR_HASH(sa->sin_addr.s_addr), ia_hash) {
1345 IFA_LOCK(&iap->ia_ifa);
1346 if (iap->ia_ifp == ifp &&
1347 iap->ia_addr.sin_addr.s_addr ==
1348 sa->sin_addr.s_addr) {
1349 /*
1350 * Avoid the race condition seen when two
1351 * threads process SIOCDIFADDR command
1352 * at the same time (radar 28942007)
1353 */
1354 if (cmd == SIOCDIFADDR) {
1355 if (iap->ia_ifa.ifa_debug &
1356 IFD_DETACHING) {
1357 IFA_UNLOCK(&iap->ia_ifa);
1358 continue;
1359 } else {
1360 iap->ia_ifa.ifa_debug |=
1361 IFD_DETACHING;
1362 }
1363 }
1364 ia = iap;
1365 IFA_ADDREF_LOCKED(&iap->ia_ifa);
1366 IFA_UNLOCK(&iap->ia_ifa);
1367 break;
1368 }
1369 IFA_UNLOCK(&iap->ia_ifa);
1370 }
1371 lck_rw_done(in_ifaddr_rwlock);
1372
1373 if (ia == NULL) {
1374 ifnet_lock_shared(ifp);
1375 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1376 iap = ifatoia(ifa);
1377 IFA_LOCK(&iap->ia_ifa);
1378 if (iap->ia_addr.sin_family == AF_INET) {
1379 ia = iap;
1380 IFA_UNLOCK(&iap->ia_ifa);
1381 break;
1382 }
1383 IFA_UNLOCK(&iap->ia_ifa);
1384 }
1385 /* take a reference on ia before releasing lock */
1386 if (ia != NULL) {
1387 IFA_ADDREF(&ia->ia_ifa);
1388 }
1389 ifnet_lock_done(ifp);
1390 }
1391 }
1392
1393 /*
1394 * Unlock the socket since ifnet_ioctl() may be invoked by
1395 * one of the ioctl handlers below. Socket will be re-locked
1396 * prior to returning.
1397 */
1398 if (so != NULL) {
1399 socket_unlock(so, 0);
1400 so_unlocked = TRUE;
1401 }
1402
1403 switch (cmd) {
1404 case SIOCAIFADDR: /* struct {if,in_}aliasreq */
1405 case SIOCDIFADDR: /* struct ifreq */
1406 if (cmd == SIOCAIFADDR) {
1407 bcopy(&((struct in_aliasreq *)(void *)data)->
1408 ifra_addr, &addr, sizeof(addr));
1409 bcopy(&((struct in_aliasreq *)(void *)data)->
1410 ifra_dstaddr, &dstaddr, sizeof(dstaddr));
1411 } else {
1412 VERIFY(cmd == SIOCDIFADDR);
1413 bcopy(&((struct ifreq *)(void *)data)->ifr_addr,
1414 &addr, sizeof(addr));
1415 bzero(&dstaddr, sizeof(dstaddr));
1416 }
1417
1418 if (addr.sin_family == AF_INET) {
1419 struct in_ifaddr *oia;
1420
1421 lck_rw_lock_shared(in_ifaddr_rwlock);
1422 for (oia = ia; ia; ia = ia->ia_link.tqe_next) {
1423 IFA_LOCK(&ia->ia_ifa);
1424 if (ia->ia_ifp == ifp &&
1425 ia->ia_addr.sin_addr.s_addr ==
1426 addr.sin_addr.s_addr) {
1427 IFA_ADDREF_LOCKED(&ia->ia_ifa);
1428 IFA_UNLOCK(&ia->ia_ifa);
1429 break;
1430 }
1431 IFA_UNLOCK(&ia->ia_ifa);
1432 }
1433 lck_rw_done(in_ifaddr_rwlock);
1434 if (oia != NULL) {
1435 IFA_REMREF(&oia->ia_ifa);
1436 }
1437 if ((ifp->if_flags & IFF_POINTOPOINT) &&
1438 (cmd == SIOCAIFADDR) &&
1439 (dstaddr.sin_addr.s_addr == INADDR_ANY)) {
1440 error = EDESTADDRREQ;
1441 goto done;
1442 }
1443 } else if (cmd == SIOCAIFADDR) {
1444 error = EINVAL;
1445 goto done;
1446 }
1447 if (cmd == SIOCDIFADDR && ia == NULL) {
1448 error = EADDRNOTAVAIL;
1449 goto done;
1450 }
1451 /* FALLTHROUGH */
1452 case SIOCSIFADDR: /* struct ifreq */
1453 case SIOCSIFDSTADDR: /* struct ifreq */
1454 case SIOCSIFNETMASK: /* struct ifreq */
1455 if (cmd == SIOCAIFADDR) {
1456 /* fell thru from above; just repeat it */
1457 bcopy(&((struct in_aliasreq *)(void *)data)->
1458 ifra_addr, &addr, sizeof(addr));
1459 } else {
1460 VERIFY(cmd == SIOCDIFADDR || cmd == SIOCSIFADDR ||
1461 cmd == SIOCSIFNETMASK || cmd == SIOCSIFDSTADDR);
1462 bcopy(&((struct ifreq *)(void *)data)->ifr_addr,
1463 &addr, sizeof(addr));
1464 }
1465
1466 if (addr.sin_family != AF_INET && cmd == SIOCSIFADDR) {
1467 error = EINVAL;
1468 goto done;
1469 }
1470 if (ia == NULL) {
1471 ia = in_ifaddr_alloc(M_WAITOK);
1472 if (ia == NULL) {
1473 error = ENOBUFS;
1474 goto done;
1475 }
1476 ifnet_lock_exclusive(ifp);
1477 ifa = &ia->ia_ifa;
1478 IFA_LOCK(ifa);
1479 /* Hold a reference for this routine */
1480 IFA_ADDREF_LOCKED(ifa);
1481 IA_HASH_INIT(ia);
1482 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr;
1483 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr;
1484 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask;
1485 ia->ia_sockmask.sin_len = 8;
1486 if (ifp->if_flags & IFF_BROADCAST) {
1487 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
1488 ia->ia_broadaddr.sin_family = AF_INET;
1489 }
1490 ia->ia_ifp = ifp;
1491 if (!(ifp->if_flags & IFF_LOOPBACK)) {
1492 in_interfaces++;
1493 }
1494 /* if_attach_ifa() holds a reference for ifa_link */
1495 if_attach_ifa(ifp, ifa);
1496 /*
1497 * If we have to go through in_ifinit(), make sure
1498 * to avoid installing route(s) based on this address
1499 * via PFC_IFUP event, before the link resolver (ARP)
1500 * initializes it.
1501 */
1502 if (cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) {
1503 ifa->ifa_debug |= IFD_NOTREADY;
1504 }
1505 IFA_UNLOCK(ifa);
1506 ifnet_lock_done(ifp);
1507 lck_rw_lock_exclusive(in_ifaddr_rwlock);
1508 /* Hold a reference for ia_link */
1509 IFA_ADDREF(ifa);
1510 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link);
1511 lck_rw_done(in_ifaddr_rwlock);
1512 /* discard error */
1513 (void) in_domifattach(ifp);
1514 error = 0;
1515 }
1516 break;
1517 }
1518
1519 switch (cmd) {
1520 case SIOCGIFDSTADDR: /* struct ifreq */
1521 case SIOCSIFDSTADDR: /* struct ifreq */
1522 error = inctl_ifdstaddr(ifp, ia, cmd, ifr);
1523 break;
1524
1525 case SIOCGIFBRDADDR: /* struct ifreq */
1526 case SIOCSIFBRDADDR: /* struct ifreq */
1527 error = inctl_ifbrdaddr(ifp, ia, cmd, ifr);
1528 break;
1529
1530 case SIOCGIFNETMASK: /* struct ifreq */
1531 case SIOCSIFNETMASK: /* struct ifreq */
1532 error = inctl_ifnetmask(ifp, ia, cmd, ifr);
1533 break;
1534
1535 case SIOCGIFADDR: /* struct ifreq */
1536 case SIOCSIFADDR: /* struct ifreq */
1537 case SIOCAIFADDR: /* struct {if,in_}aliasreq */
1538 case SIOCDIFADDR: /* struct ifreq */
1539 error = inctl_ifaddr(ifp, ia, cmd, ifr);
1540 break;
1541
1542 default:
1543 error = EOPNOTSUPP;
1544 break;
1545 }
1546 done:
1547 if (ia != NULL) {
1548 IFA_REMREF(&ia->ia_ifa);
1549 }
1550 if (so_unlocked) {
1551 socket_lock(so, 0);
1552 }
1553
1554 return error;
1555 }
1556
1557 /*
1558 * Delete any existing route for an interface.
1559 */
1560 void
1561 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia, int locked)
1562 {
1563 IFA_LOCK(&ia->ia_ifa);
1564 if ((ia->ia_flags & IFA_ROUTE) == 0) {
1565 IFA_UNLOCK(&ia->ia_ifa);
1566 return;
1567 }
1568 IFA_UNLOCK(&ia->ia_ifa);
1569 if (!locked) {
1570 lck_mtx_lock(rnh_lock);
1571 }
1572 if (ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) {
1573 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
1574 } else {
1575 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, 0);
1576 }
1577 IFA_LOCK(&ia->ia_ifa);
1578 ia->ia_flags &= ~IFA_ROUTE;
1579 IFA_UNLOCK(&ia->ia_ifa);
1580 if (!locked) {
1581 lck_mtx_unlock(rnh_lock);
1582 }
1583 }
1584
1585 /*
1586 * Caller must hold in_ifaddr_rwlock as writer.
1587 */
1588 static void
1589 in_iahash_remove(struct in_ifaddr *ia)
1590 {
1591 LCK_RW_ASSERT(in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1592 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1593
1594 if (!IA_IS_HASHED(ia)) {
1595 panic("attempt to remove wrong ia %p from hash table\n", ia);
1596 /* NOTREACHED */
1597 }
1598 TAILQ_REMOVE(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash);
1599 IA_HASH_INIT(ia);
1600 if (IFA_REMREF_LOCKED(&ia->ia_ifa) == NULL) {
1601 panic("%s: unexpected (missing) refcnt ifa=%p", __func__,
1602 &ia->ia_ifa);
1603 /* NOTREACHED */
1604 }
1605 }
1606
1607 /*
1608 * Caller must hold in_ifaddr_rwlock as writer.
1609 */
1610 static void
1611 in_iahash_insert(struct in_ifaddr *ia)
1612 {
1613 LCK_RW_ASSERT(in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1614 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1615
1616 if (ia->ia_addr.sin_family != AF_INET) {
1617 panic("attempt to insert wrong ia %p into hash table\n", ia);
1618 /* NOTREACHED */
1619 } else if (IA_IS_HASHED(ia)) {
1620 panic("attempt to double-insert ia %p into hash table\n", ia);
1621 /* NOTREACHED */
1622 }
1623 TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1624 ia, ia_hash);
1625 IFA_ADDREF_LOCKED(&ia->ia_ifa);
1626 }
1627
1628 /*
1629 * Some point to point interfaces that are tunnels borrow the address from
1630 * an underlying interface (e.g. VPN server). In order for source address
1631 * selection logic to find the underlying interface first, we add the address
1632 * of borrowing point to point interfaces at the end of the list.
1633 * (see rdar://6733789)
1634 *
1635 * Caller must hold in_ifaddr_rwlock as writer.
1636 */
1637 static void
1638 in_iahash_insert_ptp(struct in_ifaddr *ia)
1639 {
1640 struct in_ifaddr *tmp_ifa;
1641 struct ifnet *tmp_ifp;
1642
1643 LCK_RW_ASSERT(in_ifaddr_rwlock, LCK_RW_ASSERT_EXCLUSIVE);
1644 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1645
1646 if (ia->ia_addr.sin_family != AF_INET) {
1647 panic("attempt to insert wrong ia %p into hash table\n", ia);
1648 /* NOTREACHED */
1649 } else if (IA_IS_HASHED(ia)) {
1650 panic("attempt to double-insert ia %p into hash table\n", ia);
1651 /* NOTREACHED */
1652 }
1653 IFA_UNLOCK(&ia->ia_ifa);
1654 TAILQ_FOREACH(tmp_ifa, INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1655 ia_hash) {
1656 IFA_LOCK(&tmp_ifa->ia_ifa);
1657 /* ia->ia_addr won't change, so check without lock */
1658 if (IA_SIN(tmp_ifa)->sin_addr.s_addr ==
1659 ia->ia_addr.sin_addr.s_addr) {
1660 IFA_UNLOCK(&tmp_ifa->ia_ifa);
1661 break;
1662 }
1663 IFA_UNLOCK(&tmp_ifa->ia_ifa);
1664 }
1665 tmp_ifp = (tmp_ifa == NULL) ? NULL : tmp_ifa->ia_ifp;
1666
1667 IFA_LOCK(&ia->ia_ifa);
1668 if (tmp_ifp == NULL) {
1669 TAILQ_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1670 ia, ia_hash);
1671 } else {
1672 TAILQ_INSERT_TAIL(INADDR_HASH(ia->ia_addr.sin_addr.s_addr),
1673 ia, ia_hash);
1674 }
1675 IFA_ADDREF_LOCKED(&ia->ia_ifa);
1676 }
1677
1678 /*
1679 * Initialize an interface's internet address
1680 * and routing table entry.
1681 */
1682 static int
1683 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
1684 int scrub)
1685 {
1686 u_int32_t i = ntohl(sin->sin_addr.s_addr);
1687 struct sockaddr_in oldaddr;
1688 int flags = RTF_UP, error;
1689 struct ifaddr *ifa0;
1690 unsigned int cmd;
1691 int oldremoved = 0;
1692
1693 /* Take an extra reference for this routine */
1694 IFA_ADDREF(&ia->ia_ifa);
1695
1696 lck_rw_lock_exclusive(in_ifaddr_rwlock);
1697 IFA_LOCK(&ia->ia_ifa);
1698 oldaddr = ia->ia_addr;
1699 if (IA_IS_HASHED(ia)) {
1700 oldremoved = 1;
1701 in_iahash_remove(ia);
1702 }
1703 ia->ia_addr = *sin;
1704 /*
1705 * Interface addresses should not contain port or sin_zero information.
1706 */
1707 SIN(&ia->ia_addr)->sin_family = AF_INET;
1708 SIN(&ia->ia_addr)->sin_len = sizeof(struct sockaddr_in);
1709 SIN(&ia->ia_addr)->sin_port = 0;
1710 bzero(&SIN(&ia->ia_addr)->sin_zero, sizeof(sin->sin_zero));
1711 if ((ifp->if_flags & IFF_POINTOPOINT)) {
1712 in_iahash_insert_ptp(ia);
1713 } else {
1714 in_iahash_insert(ia);
1715 }
1716 IFA_UNLOCK(&ia->ia_ifa);
1717 lck_rw_done(in_ifaddr_rwlock);
1718
1719 /*
1720 * Give the interface a chance to initialize if this is its first
1721 * address, and to validate the address if necessary. Send down
1722 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es).
1723 * We find the first IPV4 address assigned to it and check if this
1724 * is the same as the one passed into this routine.
1725 */
1726 ifa0 = ifa_ifpgetprimary(ifp, AF_INET);
1727 cmd = (&ia->ia_ifa == ifa0) ? SIOCSIFADDR : SIOCAIFADDR;
1728 error = ifnet_ioctl(ifp, PF_INET, cmd, ia);
1729 if (error == EOPNOTSUPP) {
1730 error = 0;
1731 }
1732 /*
1733 * If we've just sent down SIOCAIFADDR, send another ioctl down
1734 * for SIOCSIFADDR for the first IPV4 address of the interface,
1735 * because an address change on one of the addresses will result
1736 * in the removal of the previous first IPV4 address. KDP needs
1737 * be reconfigured with the current primary IPV4 address.
1738 */
1739 if (error == 0 && cmd == SIOCAIFADDR) {
1740 /*
1741 * NOTE: SIOCSIFADDR is defined with struct ifreq
1742 * as parameter, but here we are sending it down
1743 * to the interface with a pointer to struct ifaddr,
1744 * for legacy reasons.
1745 */
1746 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa0);
1747 if (error == EOPNOTSUPP) {
1748 error = 0;
1749 }
1750 }
1751
1752 /* Release reference from ifa_ifpgetprimary() */
1753 IFA_REMREF(ifa0);
1754
1755 if (error) {
1756 lck_rw_lock_exclusive(in_ifaddr_rwlock);
1757 IFA_LOCK(&ia->ia_ifa);
1758 if (IA_IS_HASHED(ia)) {
1759 in_iahash_remove(ia);
1760 }
1761 ia->ia_addr = oldaddr;
1762 if (oldremoved) {
1763 if ((ifp->if_flags & IFF_POINTOPOINT)) {
1764 in_iahash_insert_ptp(ia);
1765 } else {
1766 in_iahash_insert(ia);
1767 }
1768 }
1769 IFA_UNLOCK(&ia->ia_ifa);
1770 lck_rw_done(in_ifaddr_rwlock);
1771 /* Release extra reference taken above */
1772 IFA_REMREF(&ia->ia_ifa);
1773 return error;
1774 }
1775 lck_mtx_lock(rnh_lock);
1776 IFA_LOCK(&ia->ia_ifa);
1777 /*
1778 * Address has been initialized by the link resolver (ARP)
1779 * via ifnet_ioctl() above; it may now generate route(s).
1780 */
1781 ia->ia_ifa.ifa_debug &= ~IFD_NOTREADY;
1782 if (scrub) {
1783 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
1784 IFA_UNLOCK(&ia->ia_ifa);
1785 in_ifscrub(ifp, ia, 1);
1786 IFA_LOCK(&ia->ia_ifa);
1787 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
1788 }
1789 IFA_LOCK_ASSERT_HELD(&ia->ia_ifa);
1790 if (IN_CLASSA(i)) {
1791 ia->ia_netmask = IN_CLASSA_NET;
1792 } else if (IN_CLASSB(i)) {
1793 ia->ia_netmask = IN_CLASSB_NET;
1794 } else {
1795 ia->ia_netmask = IN_CLASSC_NET;
1796 }
1797 /*
1798 * The subnet mask usually includes at least the standard network part,
1799 * but may may be smaller in the case of supernetting.
1800 * If it is set, we believe it.
1801 */
1802 if (ia->ia_subnetmask == 0) {
1803 ia->ia_subnetmask = ia->ia_netmask;
1804 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
1805 } else {
1806 ia->ia_netmask &= ia->ia_subnetmask;
1807 }
1808 ia->ia_net = i & ia->ia_netmask;
1809 ia->ia_subnet = i & ia->ia_subnetmask;
1810 in_socktrim(&ia->ia_sockmask);
1811 /*
1812 * Add route for the network.
1813 */
1814 ia->ia_ifa.ifa_metric = ifp->if_metric;
1815 if (ifp->if_flags & IFF_BROADCAST) {
1816 ia->ia_broadaddr.sin_addr.s_addr =
1817 htonl(ia->ia_subnet | ~ia->ia_subnetmask);
1818 ia->ia_netbroadcast.s_addr =
1819 htonl(ia->ia_net | ~ia->ia_netmask);
1820 } else if (ifp->if_flags & IFF_LOOPBACK) {
1821 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
1822 flags |= RTF_HOST;
1823 } else if (ifp->if_flags & IFF_POINTOPOINT) {
1824 if (ia->ia_dstaddr.sin_family != AF_INET) {
1825 IFA_UNLOCK(&ia->ia_ifa);
1826 lck_mtx_unlock(rnh_lock);
1827 /* Release extra reference taken above */
1828 IFA_REMREF(&ia->ia_ifa);
1829 return 0;
1830 }
1831 ia->ia_dstaddr.sin_len = sizeof(struct sockaddr_in);
1832 flags |= RTF_HOST;
1833 }
1834 IFA_UNLOCK(&ia->ia_ifa);
1835
1836 if ((error = rtinit_locked(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0) {
1837 IFA_LOCK(&ia->ia_ifa);
1838 ia->ia_flags |= IFA_ROUTE;
1839 IFA_UNLOCK(&ia->ia_ifa);
1840 }
1841 lck_mtx_unlock(rnh_lock);
1842
1843 /* XXX check if the subnet route points to the same interface */
1844 if (error == EEXIST) {
1845 error = 0;
1846 }
1847
1848 /*
1849 * If the interface supports multicast, join the "all hosts"
1850 * multicast group on that interface.
1851 */
1852 if (ifp->if_flags & IFF_MULTICAST) {
1853 struct in_addr addr;
1854
1855 lck_mtx_lock(&ifp->if_addrconfig_lock);
1856 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
1857 if (ifp->if_allhostsinm == NULL) {
1858 struct in_multi *inm;
1859 inm = in_addmulti(&addr, ifp);
1860
1861 if (inm != NULL) {
1862 /*
1863 * Keep the reference on inm added by
1864 * in_addmulti above for storing the
1865 * pointer in allhostsinm.
1866 */
1867 ifp->if_allhostsinm = inm;
1868 } else {
1869 printf("%s: failed to add membership to "
1870 "all-hosts multicast address on %s\n",
1871 __func__, if_name(ifp));
1872 }
1873 }
1874 lck_mtx_unlock(&ifp->if_addrconfig_lock);
1875 }
1876
1877 /* Release extra reference taken above */
1878 IFA_REMREF(&ia->ia_ifa);
1879
1880 if (error == 0) {
1881 /* invalidate route caches */
1882 routegenid_inet_update();
1883 }
1884
1885 return error;
1886 }
1887
1888 /*
1889 * Return TRUE if the address might be a local broadcast address.
1890 */
1891 boolean_t
1892 in_broadcast(struct in_addr in, struct ifnet *ifp)
1893 {
1894 struct ifaddr *ifa;
1895 u_int32_t t;
1896
1897 if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY) {
1898 return TRUE;
1899 }
1900 if (!(ifp->if_flags & IFF_BROADCAST)) {
1901 return FALSE;
1902 }
1903 t = ntohl(in.s_addr);
1904
1905 /*
1906 * Look through the list of addresses for a match
1907 * with a broadcast address.
1908 */
1909 #define ia ((struct in_ifaddr *)ifa)
1910 ifnet_lock_shared(ifp);
1911 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1912 IFA_LOCK(ifa);
1913 if (ifa->ifa_addr->sa_family == AF_INET &&
1914 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
1915 in.s_addr == ia->ia_netbroadcast.s_addr ||
1916 /*
1917 * Check for old-style (host 0) broadcast.
1918 */
1919 t == ia->ia_subnet || t == ia->ia_net) &&
1920 /*
1921 * Check for an all one subnetmask. These
1922 * only exist when an interface gets a secondary
1923 * address.
1924 */
1925 ia->ia_subnetmask != (u_int32_t)0xffffffff) {
1926 IFA_UNLOCK(ifa);
1927 ifnet_lock_done(ifp);
1928 return TRUE;
1929 }
1930 IFA_UNLOCK(ifa);
1931 }
1932 ifnet_lock_done(ifp);
1933 return FALSE;
1934 #undef ia
1935 }
1936
1937 void
1938 in_purgeaddrs(struct ifnet *ifp)
1939 {
1940 struct ifaddr **ifap;
1941 int err, i;
1942
1943 VERIFY(ifp != NULL);
1944
1945 /*
1946 * Be nice, and try the civilized way first. If we can't get
1947 * rid of them this way, then do it the rough way. We must
1948 * only get here during detach time, after the ifnet has been
1949 * removed from the global list and arrays.
1950 */
1951 err = ifnet_get_address_list_family_internal(ifp, &ifap, AF_INET, 1,
1952 M_WAITOK, 0);
1953 if (err == 0 && ifap != NULL) {
1954 struct ifreq ifr;
1955
1956 bzero(&ifr, sizeof(ifr));
1957 (void) snprintf(ifr.ifr_name, sizeof(ifr.ifr_name),
1958 "%s", if_name(ifp));
1959
1960 for (i = 0; ifap[i] != NULL; i++) {
1961 struct ifaddr *ifa;
1962
1963 ifa = ifap[i];
1964 IFA_LOCK(ifa);
1965 bcopy(ifa->ifa_addr, &ifr.ifr_addr,
1966 sizeof(struct sockaddr_in));
1967 IFA_UNLOCK(ifa);
1968 err = in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp,
1969 kernproc);
1970 /* if we lost the race, ignore it */
1971 if (err == EADDRNOTAVAIL) {
1972 err = 0;
1973 }
1974 if (err != 0) {
1975 char s_addr[MAX_IPv4_STR_LEN];
1976 char s_dstaddr[MAX_IPv4_STR_LEN];
1977 struct in_addr *s, *d;
1978
1979 IFA_LOCK(ifa);
1980 s = &((struct sockaddr_in *)
1981 (void *)ifa->ifa_addr)->sin_addr;
1982 d = &((struct sockaddr_in *)
1983 (void *)ifa->ifa_dstaddr)->sin_addr;
1984 (void) inet_ntop(AF_INET, &s->s_addr, s_addr,
1985 sizeof(s_addr));
1986 (void) inet_ntop(AF_INET, &d->s_addr, s_dstaddr,
1987 sizeof(s_dstaddr));
1988 IFA_UNLOCK(ifa);
1989
1990 printf("%s: SIOCDIFADDR ifp=%s ifa_addr=%s "
1991 "ifa_dstaddr=%s (err=%d)\n", __func__,
1992 ifp->if_xname, s_addr, s_dstaddr, err);
1993 }
1994 }
1995 ifnet_free_address_list(ifap);
1996 } else if (err != 0 && err != ENXIO) {
1997 printf("%s: error retrieving list of AF_INET addresses for "
1998 "ifp=%s (err=%d)\n", __func__, ifp->if_xname, err);
1999 }
2000 }
2001
2002 /*
2003 * Called as part of ip_init
2004 */
2005 void
2006 in_ifaddr_init(void)
2007 {
2008 in_multi_init();
2009
2010 PE_parse_boot_argn("ifa_debug", &inifa_debug, sizeof(inifa_debug));
2011
2012 inifa_size = (inifa_debug == 0) ? sizeof(struct in_ifaddr) :
2013 sizeof(struct in_ifaddr_dbg);
2014
2015 inifa_zone = zinit(inifa_size, INIFA_ZONE_MAX * inifa_size,
2016 0, INIFA_ZONE_NAME);
2017 if (inifa_zone == NULL) {
2018 panic("%s: failed allocating %s", __func__, INIFA_ZONE_NAME);
2019 /* NOTREACHED */
2020 }
2021 zone_change(inifa_zone, Z_EXPAND, TRUE);
2022 zone_change(inifa_zone, Z_CALLERACCT, FALSE);
2023
2024 lck_mtx_init(&inifa_trash_lock, ifa_mtx_grp, ifa_mtx_attr);
2025 TAILQ_INIT(&inifa_trash_head);
2026 }
2027
2028 static struct in_ifaddr *
2029 in_ifaddr_alloc(int how)
2030 {
2031 struct in_ifaddr *inifa;
2032
2033 inifa = (how == M_WAITOK) ? zalloc(inifa_zone) :
2034 zalloc_noblock(inifa_zone);
2035 if (inifa != NULL) {
2036 bzero(inifa, inifa_size);
2037 inifa->ia_ifa.ifa_free = in_ifaddr_free;
2038 inifa->ia_ifa.ifa_debug |= IFD_ALLOC;
2039 ifa_lock_init(&inifa->ia_ifa);
2040 if (inifa_debug != 0) {
2041 struct in_ifaddr_dbg *inifa_dbg =
2042 (struct in_ifaddr_dbg *)inifa;
2043 inifa->ia_ifa.ifa_debug |= IFD_DEBUG;
2044 inifa->ia_ifa.ifa_trace = in_ifaddr_trace;
2045 inifa->ia_ifa.ifa_attached = in_ifaddr_attached;
2046 inifa->ia_ifa.ifa_detached = in_ifaddr_detached;
2047 ctrace_record(&inifa_dbg->inifa_alloc);
2048 }
2049 }
2050 return inifa;
2051 }
2052
2053 static void
2054 in_ifaddr_free(struct ifaddr *ifa)
2055 {
2056 IFA_LOCK_ASSERT_HELD(ifa);
2057
2058 if (ifa->ifa_refcnt != 0) {
2059 panic("%s: ifa %p bad ref cnt", __func__, ifa);
2060 /* NOTREACHED */
2061 }
2062 if (!(ifa->ifa_debug & IFD_ALLOC)) {
2063 panic("%s: ifa %p cannot be freed", __func__, ifa);
2064 /* NOTREACHED */
2065 }
2066 if (ifa->ifa_debug & IFD_DEBUG) {
2067 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa;
2068 ctrace_record(&inifa_dbg->inifa_free);
2069 bcopy(&inifa_dbg->inifa, &inifa_dbg->inifa_old,
2070 sizeof(struct in_ifaddr));
2071 if (ifa->ifa_debug & IFD_TRASHED) {
2072 /* Become a regular mutex, just in case */
2073 IFA_CONVERT_LOCK(ifa);
2074 lck_mtx_lock(&inifa_trash_lock);
2075 TAILQ_REMOVE(&inifa_trash_head, inifa_dbg,
2076 inifa_trash_link);
2077 lck_mtx_unlock(&inifa_trash_lock);
2078 ifa->ifa_debug &= ~IFD_TRASHED;
2079 }
2080 }
2081 IFA_UNLOCK(ifa);
2082 ifa_lock_destroy(ifa);
2083 bzero(ifa, sizeof(struct in_ifaddr));
2084 zfree(inifa_zone, ifa);
2085 }
2086
2087 static void
2088 in_ifaddr_attached(struct ifaddr *ifa)
2089 {
2090 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa;
2091
2092 IFA_LOCK_ASSERT_HELD(ifa);
2093
2094 if (!(ifa->ifa_debug & IFD_DEBUG)) {
2095 panic("%s: ifa %p has no debug structure", __func__, ifa);
2096 /* NOTREACHED */
2097 }
2098 if (ifa->ifa_debug & IFD_TRASHED) {
2099 /* Become a regular mutex, just in case */
2100 IFA_CONVERT_LOCK(ifa);
2101 lck_mtx_lock(&inifa_trash_lock);
2102 TAILQ_REMOVE(&inifa_trash_head, inifa_dbg, inifa_trash_link);
2103 lck_mtx_unlock(&inifa_trash_lock);
2104 ifa->ifa_debug &= ~IFD_TRASHED;
2105 }
2106 }
2107
2108 static void
2109 in_ifaddr_detached(struct ifaddr *ifa)
2110 {
2111 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa;
2112
2113 IFA_LOCK_ASSERT_HELD(ifa);
2114
2115 if (!(ifa->ifa_debug & IFD_DEBUG)) {
2116 panic("%s: ifa %p has no debug structure", __func__, ifa);
2117 /* NOTREACHED */
2118 } else if (ifa->ifa_debug & IFD_TRASHED) {
2119 panic("%s: ifa %p is already in trash list", __func__, ifa);
2120 /* NOTREACHED */
2121 }
2122 ifa->ifa_debug |= IFD_TRASHED;
2123 /* Become a regular mutex, just in case */
2124 IFA_CONVERT_LOCK(ifa);
2125 lck_mtx_lock(&inifa_trash_lock);
2126 TAILQ_INSERT_TAIL(&inifa_trash_head, inifa_dbg, inifa_trash_link);
2127 lck_mtx_unlock(&inifa_trash_lock);
2128 }
2129
2130 static void
2131 in_ifaddr_trace(struct ifaddr *ifa, int refhold)
2132 {
2133 struct in_ifaddr_dbg *inifa_dbg = (struct in_ifaddr_dbg *)ifa;
2134 ctrace_t *tr;
2135 u_int32_t idx;
2136 u_int16_t *cnt;
2137
2138 if (!(ifa->ifa_debug & IFD_DEBUG)) {
2139 panic("%s: ifa %p has no debug structure", __func__, ifa);
2140 /* NOTREACHED */
2141 }
2142 if (refhold) {
2143 cnt = &inifa_dbg->inifa_refhold_cnt;
2144 tr = inifa_dbg->inifa_refhold;
2145 } else {
2146 cnt = &inifa_dbg->inifa_refrele_cnt;
2147 tr = inifa_dbg->inifa_refrele;
2148 }
2149
2150 idx = atomic_add_16_ov(cnt, 1) % INIFA_TRACE_HIST_SIZE;
2151 ctrace_record(&tr[idx]);
2152 }
2153
2154 /*
2155 * Handle SIOCGASSOCIDS ioctl for PF_INET domain.
2156 */
2157 static int
2158 in_getassocids(struct socket *so, uint32_t *cnt, user_addr_t aidp)
2159 {
2160 struct inpcb *inp = sotoinpcb(so);
2161 sae_associd_t aid;
2162
2163 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD) {
2164 return EINVAL;
2165 }
2166
2167 /* INPCB has no concept of association */
2168 aid = SAE_ASSOCID_ANY;
2169 *cnt = 0;
2170
2171 /* just asking how many there are? */
2172 if (aidp == USER_ADDR_NULL) {
2173 return 0;
2174 }
2175
2176 return copyout(&aid, aidp, sizeof(aid));
2177 }
2178
2179 /*
2180 * Handle SIOCGCONNIDS ioctl for PF_INET domain.
2181 */
2182 static int
2183 in_getconnids(struct socket *so, sae_associd_t aid, uint32_t *cnt,
2184 user_addr_t cidp)
2185 {
2186 struct inpcb *inp = sotoinpcb(so);
2187 sae_connid_t cid;
2188
2189 if (inp == NULL || inp->inp_state == INPCB_STATE_DEAD) {
2190 return EINVAL;
2191 }
2192
2193 if (aid != SAE_ASSOCID_ANY && aid != SAE_ASSOCID_ALL) {
2194 return EINVAL;
2195 }
2196
2197 /* if connected, return 1 connection count */
2198 *cnt = ((so->so_state & SS_ISCONNECTED) ? 1 : 0);
2199
2200 /* just asking how many there are? */
2201 if (cidp == USER_ADDR_NULL) {
2202 return 0;
2203 }
2204
2205 /* if INPCB is connected, assign it connid 1 */
2206 cid = ((*cnt != 0) ? 1 : SAE_CONNID_ANY);
2207
2208 return copyout(&cid, cidp, sizeof(cid));
2209 }
2210
2211 /*
2212 * Handle SIOCGCONNINFO ioctl for PF_INET domain.
2213 */
2214 int
2215 in_getconninfo(struct socket *so, sae_connid_t cid, uint32_t *flags,
2216 uint32_t *ifindex, int32_t *soerror, user_addr_t src, socklen_t *src_len,
2217 user_addr_t dst, socklen_t *dst_len, uint32_t *aux_type,
2218 user_addr_t aux_data, uint32_t *aux_len)
2219 {
2220 struct inpcb *inp = sotoinpcb(so);
2221 struct sockaddr_in sin;
2222 struct ifnet *ifp = NULL;
2223 int error = 0;
2224 u_int32_t copy_len = 0;
2225
2226 /*
2227 * Don't test for INPCB_STATE_DEAD since this may be called
2228 * after SOF_PCBCLEARING is set, e.g. after tcp_close().
2229 */
2230 if (inp == NULL) {
2231 error = EINVAL;
2232 goto out;
2233 }
2234
2235 if (cid != SAE_CONNID_ANY && cid != SAE_CONNID_ALL && cid != 1) {
2236 error = EINVAL;
2237 goto out;
2238 }
2239
2240 ifp = inp->inp_last_outifp;
2241 *ifindex = ((ifp != NULL) ? ifp->if_index : 0);
2242 *soerror = so->so_error;
2243 *flags = 0;
2244 if (so->so_state & SS_ISCONNECTED) {
2245 *flags |= (CIF_CONNECTED | CIF_PREFERRED);
2246 }
2247 if (inp->inp_flags & INP_BOUND_IF) {
2248 *flags |= CIF_BOUND_IF;
2249 }
2250 if (!(inp->inp_flags & INP_INADDR_ANY)) {
2251 *flags |= CIF_BOUND_IP;
2252 }
2253 if (!(inp->inp_flags & INP_ANONPORT)) {
2254 *flags |= CIF_BOUND_PORT;
2255 }
2256
2257 bzero(&sin, sizeof(sin));
2258 sin.sin_len = sizeof(sin);
2259 sin.sin_family = AF_INET;
2260
2261 /* source address and port */
2262 sin.sin_port = inp->inp_lport;
2263 sin.sin_addr.s_addr = inp->inp_laddr.s_addr;
2264 if (*src_len == 0) {
2265 *src_len = sin.sin_len;
2266 } else {
2267 if (src != USER_ADDR_NULL) {
2268 copy_len = min(*src_len, sizeof(sin));
2269 error = copyout(&sin, src, copy_len);
2270 if (error != 0) {
2271 goto out;
2272 }
2273 *src_len = copy_len;
2274 }
2275 }
2276
2277 /* destination address and port */
2278 sin.sin_port = inp->inp_fport;
2279 sin.sin_addr.s_addr = inp->inp_faddr.s_addr;
2280 if (*dst_len == 0) {
2281 *dst_len = sin.sin_len;
2282 } else {
2283 if (dst != USER_ADDR_NULL) {
2284 copy_len = min(*dst_len, sizeof(sin));
2285 error = copyout(&sin, dst, copy_len);
2286 if (error != 0) {
2287 goto out;
2288 }
2289 *dst_len = copy_len;
2290 }
2291 }
2292
2293 if (SOCK_PROTO(so) == IPPROTO_TCP) {
2294 struct conninfo_tcp tcp_ci;
2295
2296 *aux_type = CIAUX_TCP;
2297 if (*aux_len == 0) {
2298 *aux_len = sizeof(tcp_ci);
2299 } else {
2300 if (aux_data != USER_ADDR_NULL) {
2301 copy_len = min(*aux_len, sizeof(tcp_ci));
2302 bzero(&tcp_ci, sizeof(tcp_ci));
2303 tcp_getconninfo(so, &tcp_ci);
2304 error = copyout(&tcp_ci, aux_data, copy_len);
2305 if (error != 0) {
2306 goto out;
2307 }
2308 *aux_len = copy_len;
2309 }
2310 }
2311 } else {
2312 *aux_type = 0;
2313 *aux_len = 0;
2314 }
2315
2316 out:
2317 return error;
2318 }
2319
2320 struct in_llentry {
2321 struct llentry base;
2322 };
2323
2324 #define IN_LLTBL_DEFAULT_HSIZE 32
2325 #define IN_LLTBL_HASH(k, h) \
2326 ((((((((k) >> 8) ^ (k)) >> 8) ^ (k)) >> 8) ^ (k)) & ((h) - 1))
2327
2328 /*
2329 * Do actual deallocation of @lle.
2330 */
2331 static void
2332 in_lltable_destroy_lle_unlocked(struct llentry *lle)
2333 {
2334 LLE_LOCK_DESTROY(lle);
2335 LLE_REQ_DESTROY(lle);
2336 FREE(lle, M_LLTABLE);
2337 }
2338
2339 /*
2340 * Called by LLE_FREE_LOCKED when number of references
2341 * drops to zero.
2342 */
2343 static void
2344 in_lltable_destroy_lle(struct llentry *lle)
2345 {
2346 LLE_WUNLOCK(lle);
2347 in_lltable_destroy_lle_unlocked(lle);
2348 }
2349
2350 static struct llentry *
2351 in_lltable_new(struct in_addr addr4, u_int flags)
2352 {
2353 #pragma unused(flags)
2354 struct in_llentry *lle;
2355
2356 MALLOC(lle, struct in_llentry *, sizeof(struct in_llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
2357 if (lle == NULL) { /* NB: caller generates msg */
2358 return NULL;
2359 }
2360
2361 /*
2362 * For IPv4 this will trigger "arpresolve" to generate
2363 * an ARP request.
2364 */
2365 lle->base.la_expire = net_uptime(); /* mark expired */
2366 lle->base.r_l3addr.addr4 = addr4;
2367 lle->base.lle_refcnt = 1;
2368 lle->base.lle_free = in_lltable_destroy_lle;
2369
2370 LLE_LOCK_INIT(&lle->base);
2371 LLE_REQ_INIT(&lle->base);
2372 //callout_init(&lle->base.lle_timer, 1);
2373
2374 return &lle->base;
2375 }
2376
2377 #define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
2378 ((((d).s_addr ^ (a).s_addr) & (m).s_addr)) == 0 )
2379
2380 static int
2381 in_lltable_match_prefix(const struct sockaddr *saddr,
2382 const struct sockaddr *smask, u_int flags, struct llentry *lle)
2383 {
2384 struct in_addr addr, mask, lle_addr;
2385
2386 addr = ((const struct sockaddr_in *)(const void *)saddr)->sin_addr;
2387 mask = ((const struct sockaddr_in *)(const void *)smask)->sin_addr;
2388 lle_addr.s_addr = ntohl(lle->r_l3addr.addr4.s_addr);
2389
2390 if (IN_ARE_MASKED_ADDR_EQUAL(lle_addr, addr, mask) == 0) {
2391 return 0;
2392 }
2393
2394 if (lle->la_flags & LLE_IFADDR) {
2395 /*
2396 * Delete LLE_IFADDR records IFF address & flag matches.
2397 * Note that addr is the interface address within prefix
2398 * being matched.
2399 * Note also we should handle 'ifdown' cases without removing
2400 * ifaddr macs.
2401 */
2402 if (addr.s_addr == lle_addr.s_addr && (flags & LLE_STATIC) != 0) {
2403 return 1;
2404 }
2405 return 0;
2406 }
2407
2408 /* flags & LLE_STATIC means deleting both dynamic and static entries */
2409 if ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)) {
2410 return 1;
2411 }
2412
2413 return 0;
2414 }
2415
2416 static void
2417 in_lltable_free_entry(struct lltable *llt, struct llentry *lle)
2418 {
2419 struct ifnet *ifp;
2420 size_t pkts_dropped;
2421
2422 LLE_WLOCK_ASSERT(lle);
2423 KASSERT(llt != NULL, ("lltable is NULL"));
2424
2425 /* Unlink entry from table if not already */
2426 if ((lle->la_flags & LLE_LINKED) != 0) {
2427 ifp = llt->llt_ifp;
2428 IF_AFDATA_WLOCK_ASSERT(ifp, llt->llt_af);
2429 lltable_unlink_entry(llt, lle);
2430 }
2431
2432 #if 0
2433 /* cancel timer */
2434 if (callout_stop(&lle->lle_timer) > 0) {
2435 LLE_REMREF(lle);
2436 }
2437 #endif
2438 /* Drop hold queue */
2439 pkts_dropped = llentry_free(lle);
2440 arpstat.dropped += pkts_dropped;
2441 }
2442
2443
2444 static int
2445 in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
2446 {
2447 #pragma unused(flags)
2448 struct rtentry *rt;
2449
2450 KASSERT(l3addr->sa_family == AF_INET,
2451 ("sin_family %d", l3addr->sa_family));
2452
2453 /* XXX rtalloc1 should take a const param */
2454 rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0);
2455 if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) {
2456 log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
2457 inet_ntoa(((const struct sockaddr_in *)(const void *)l3addr)->sin_addr));
2458 if (rt != NULL) {
2459 rtfree_locked(rt);
2460 }
2461 return EINVAL;
2462 }
2463 rtfree_locked(rt);
2464 return 0;
2465 }
2466
2467 static inline uint32_t
2468 in_lltable_hash_dst(const struct in_addr dst, uint32_t hsize)
2469 {
2470 return IN_LLTBL_HASH(dst.s_addr, hsize);
2471 }
2472
2473 static uint32_t
2474 in_lltable_hash(const struct llentry *lle, uint32_t hsize)
2475 {
2476 return in_lltable_hash_dst(lle->r_l3addr.addr4, hsize);
2477 }
2478
2479
2480 static void
2481 in_lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
2482 {
2483 struct sockaddr_in *sin;
2484
2485 sin = (struct sockaddr_in *)(void *)sa;
2486 bzero(sin, sizeof(*sin));
2487 sin->sin_family = AF_INET;
2488 sin->sin_len = sizeof(*sin);
2489 sin->sin_addr = lle->r_l3addr.addr4;
2490 }
2491
2492 static inline struct llentry *
2493 in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
2494 {
2495 struct llentry *lle;
2496 struct llentries *lleh;
2497 u_int hashidx;
2498
2499 hashidx = in_lltable_hash_dst(dst, llt->llt_hsize);
2500 lleh = &llt->lle_head[hashidx];
2501 LIST_FOREACH(lle, lleh, lle_next) {
2502 if (lle->la_flags & LLE_DELETED) {
2503 continue;
2504 }
2505 if (lle->r_l3addr.addr4.s_addr == dst.s_addr) {
2506 break;
2507 }
2508 }
2509
2510 return lle;
2511 }
2512
2513 static void
2514 in_lltable_delete_entry(struct lltable *llt, struct llentry *lle)
2515 {
2516 #pragma unused(llt)
2517 lle->la_flags |= LLE_DELETED;
2518 //EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
2519 #ifdef DIAGNOSTIC
2520 log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
2521 #endif
2522 llentry_free(lle);
2523 }
2524
2525 static struct llentry *
2526 in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
2527 {
2528 const struct sockaddr_in *sin = (const struct sockaddr_in *) (const void *)l3addr;
2529 struct ifnet *ifp = llt->llt_ifp;
2530 struct llentry *lle;
2531
2532 KASSERT(l3addr->sa_family == AF_INET,
2533 ("sin_family %d", l3addr->sa_family));
2534
2535 /*
2536 * A route that covers the given address must have
2537 * been installed 1st because we are doing a resolution,
2538 * verify this.
2539 */
2540 if (!(flags & LLE_IFADDR) &&
2541 in_lltable_rtcheck(ifp, flags, l3addr) != 0) {
2542 return NULL;
2543 }
2544
2545 lle = in_lltable_new(sin->sin_addr, flags);
2546 if (lle == NULL) {
2547 log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
2548 return NULL;
2549 }
2550 lle->la_flags = flags & ~LLE_CREATE;
2551 if (flags & LLE_STATIC) {
2552 lle->r_flags |= RLLE_VALID;
2553 }
2554 if ((flags & LLE_IFADDR) == LLE_IFADDR) {
2555 lltable_set_entry_addr(ifp, lle, LLADDR(SDL(ifp->if_lladdr->ifa_addr)));
2556 lle->la_flags |= LLE_STATIC;
2557 lle->r_flags |= (RLLE_VALID | RLLE_IFADDR);
2558 }
2559 return lle;
2560 }
2561
2562 /*
2563 * Return NULL if not found or marked for deletion.
2564 * If found return lle read locked.
2565 */
2566 static struct llentry *
2567 in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
2568 {
2569 const struct sockaddr_in *sin = (const struct sockaddr_in *)(const void *)l3addr;
2570 struct llentry *lle;
2571
2572 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp, llt->llt_af);
2573
2574 KASSERT(l3addr->sa_family == AF_INET,
2575 ("sin_family %d", l3addr->sa_family));
2576 lle = in_lltable_find_dst(llt, sin->sin_addr);
2577
2578 if (lle == NULL) {
2579 return NULL;
2580 }
2581
2582 KASSERT((flags & (LLE_UNLOCKED | LLE_EXCLUSIVE)) !=
2583 (LLE_UNLOCKED | LLE_EXCLUSIVE), ("wrong lle request flags: 0x%X",
2584 flags));
2585
2586 if (flags & LLE_UNLOCKED) {
2587 return lle;
2588 }
2589
2590 if (flags & LLE_EXCLUSIVE) {
2591 LLE_WLOCK(lle);
2592 } else {
2593 LLE_RLOCK(lle);
2594 }
2595
2596 return lle;
2597 }
2598
2599 static int
2600 in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
2601 struct sysctl_req *wr)
2602 {
2603 struct ifnet *ifp = llt->llt_ifp;
2604 /* XXX stack use */
2605 struct {
2606 struct rt_msghdr rtm;
2607 struct sockaddr_in sin;
2608 struct sockaddr_dl sdl;
2609 } arpc;
2610 struct sockaddr_dl *sdl;
2611 int error;
2612
2613 bzero(&arpc, sizeof(arpc));
2614 /* skip deleted entries */
2615 if ((lle->la_flags & LLE_DELETED) == LLE_DELETED) {
2616 return 0;
2617 }
2618 /* Skip if jailed and not a valid IP of the prison. */
2619 lltable_fill_sa_entry(lle, (struct sockaddr *)&arpc.sin);
2620 /*
2621 * produce a msg made of:
2622 * struct rt_msghdr;
2623 * struct sockaddr_in; (IPv4)
2624 * struct sockaddr_dl;
2625 */
2626 arpc.rtm.rtm_msglen = sizeof(arpc);
2627 arpc.rtm.rtm_version = RTM_VERSION;
2628 arpc.rtm.rtm_type = RTM_GET;
2629 arpc.rtm.rtm_flags = RTF_UP;
2630 arpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
2631
2632 /* publish */
2633 if (lle->la_flags & LLE_PUB) {
2634 arpc.rtm.rtm_flags |= RTF_ANNOUNCE;
2635 }
2636
2637 sdl = &arpc.sdl;
2638 sdl->sdl_family = AF_LINK;
2639 sdl->sdl_len = sizeof(*sdl);
2640 sdl->sdl_index = ifp->if_index;
2641 sdl->sdl_type = ifp->if_type;
2642 if ((lle->la_flags & LLE_VALID) == LLE_VALID) {
2643 sdl->sdl_alen = ifp->if_addrlen;
2644 bcopy(&lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
2645 } else {
2646 sdl->sdl_alen = 0;
2647 bzero(LLADDR(sdl), ifp->if_addrlen);
2648 }
2649
2650 arpc.rtm.rtm_rmx.rmx_expire =
2651 lle->la_flags & LLE_STATIC ? 0 : lle->la_expire;
2652 arpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
2653 if (lle->la_flags & LLE_STATIC) {
2654 arpc.rtm.rtm_flags |= RTF_STATIC;
2655 }
2656 if (lle->la_flags & LLE_IFADDR) {
2657 arpc.rtm.rtm_flags |= RTF_PINNED;
2658 }
2659 arpc.rtm.rtm_flags |= RTF_PINNED;
2660 arpc.rtm.rtm_index = ifp->if_index;
2661 error = SYSCTL_OUT(wr, &arpc, sizeof(arpc));
2662
2663 return error;
2664 }
2665
2666 static struct lltable *
2667 in_lltattach(struct ifnet *ifp)
2668 {
2669 struct lltable *llt;
2670
2671 llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
2672 llt->llt_af = AF_INET;
2673 llt->llt_ifp = ifp;
2674
2675 llt->llt_lookup = in_lltable_lookup;
2676 llt->llt_alloc_entry = in_lltable_alloc;
2677 llt->llt_delete_entry = in_lltable_delete_entry;
2678 llt->llt_dump_entry = in_lltable_dump_entry;
2679 llt->llt_hash = in_lltable_hash;
2680 llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
2681 llt->llt_free_entry = in_lltable_free_entry;
2682 llt->llt_match_prefix = in_lltable_match_prefix;
2683 lltable_link(llt);
2684
2685 return llt;
2686 }
2687
2688 struct in_ifaddr*
2689 inifa_ifpwithflag(struct ifnet * ifp, uint32_t flag)
2690 {
2691 struct ifaddr *ifa;
2692
2693 ifnet_lock_shared(ifp);
2694 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_link)
2695 {
2696 IFA_LOCK_SPIN(ifa);
2697 if (ifa->ifa_addr->sa_family != AF_INET) {
2698 IFA_UNLOCK(ifa);
2699 continue;
2700 }
2701 if ((((struct in_ifaddr *)ifa)->ia_flags & flag) == flag) {
2702 IFA_ADDREF_LOCKED(ifa);
2703 IFA_UNLOCK(ifa);
2704 break;
2705 }
2706 IFA_UNLOCK(ifa);
2707 }
2708 ifnet_lock_done(ifp);
2709
2710 return (struct in_ifaddr *)ifa;
2711 }
2712
2713 struct in_ifaddr *
2714 inifa_ifpclatv4(struct ifnet * ifp)
2715 {
2716 struct ifaddr *ifa;
2717
2718 ifnet_lock_shared(ifp);
2719 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_link)
2720 {
2721 uint32_t addr = 0;
2722 IFA_LOCK_SPIN(ifa);
2723 if (ifa->ifa_addr->sa_family != AF_INET) {
2724 IFA_UNLOCK(ifa);
2725 continue;
2726 }
2727
2728 addr = ntohl(SIN(ifa->ifa_addr)->sin_addr.s_addr);
2729 if (!IN_LINKLOCAL(addr) &&
2730 !IN_LOOPBACK(addr)) {
2731 IFA_ADDREF_LOCKED(ifa);
2732 IFA_UNLOCK(ifa);
2733 break;
2734 }
2735 IFA_UNLOCK(ifa);
2736 }
2737 ifnet_lock_done(ifp);
2738
2739 return (struct in_ifaddr *)ifa;
2740 }