1/* $NetBSD: in.c,v 1.188 2016/11/18 10:38:55 knakahara Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright (c) 1998 The NetBSD Foundation, Inc.
34 * All rights reserved.
35 *
36 * This code is derived from software contributed to The NetBSD Foundation
37 * by Public Access Networks Corporation ("Panix"). It was developed under
38 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 * POSSIBILITY OF SUCH DAMAGE.
60 */
61
62/*
63 * Copyright (c) 1982, 1986, 1991, 1993
64 * The Regents of the University of California. All rights reserved.
65 *
66 * Redistribution and use in source and binary forms, with or without
67 * modification, are permitted provided that the following conditions
68 * are met:
69 * 1. Redistributions of source code must retain the above copyright
70 * notice, this list of conditions and the following disclaimer.
71 * 2. Redistributions in binary form must reproduce the above copyright
72 * notice, this list of conditions and the following disclaimer in the
73 * documentation and/or other materials provided with the distribution.
74 * 3. Neither the name of the University nor the names of its contributors
75 * may be used to endorse or promote products derived from this software
76 * without specific prior written permission.
77 *
78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88 * SUCH DAMAGE.
89 *
90 * @(#)in.c 8.4 (Berkeley) 1/9/95
91 */
92
93#include <sys/cdefs.h>
94__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.188 2016/11/18 10:38:55 knakahara Exp $");
95
96#include "arp.h"
97
98#ifdef _KERNEL_OPT
99#include "opt_inet.h"
100#include "opt_inet_conf.h"
101#include "opt_mrouting.h"
102#include "opt_net_mpsafe.h"
103#endif
104
105#include <sys/param.h>
106#include <sys/ioctl.h>
107#include <sys/errno.h>
108#include <sys/kernel.h>
109#include <sys/malloc.h>
110#include <sys/socket.h>
111#include <sys/socketvar.h>
112#include <sys/sysctl.h>
113#include <sys/systm.h>
114#include <sys/proc.h>
115#include <sys/syslog.h>
116#include <sys/kauth.h>
117#include <sys/kmem.h>
118
119#include <sys/cprng.h>
120
121#include <net/if.h>
122#include <net/route.h>
123#include <net/pfil.h>
124
125#include <net/if_arp.h>
126#include <net/if_ether.h>
127#include <net/if_types.h>
128#include <net/if_llatbl.h>
129#include <net/if_dl.h>
130
131#include <netinet/in_systm.h>
132#include <netinet/in.h>
133#include <netinet/in_var.h>
134#include <netinet/ip.h>
135#include <netinet/ip_var.h>
136#include <netinet/in_ifattach.h>
137#include <netinet/in_pcb.h>
138#include <netinet/in_selsrc.h>
139#include <netinet/if_inarp.h>
140#include <netinet/ip_mroute.h>
141#include <netinet/igmp_var.h>
142
143#ifdef IPSELSRC
144#include <netinet/in_selsrc.h>
145#endif
146
147static u_int in_mask2len(struct in_addr *);
148static void in_len2mask(struct in_addr *, u_int);
149static int in_lifaddr_ioctl(struct socket *, u_long, void *,
150 struct ifnet *);
151
152static int in_addprefix(struct in_ifaddr *, int);
153static void in_scrubaddr(struct in_ifaddr *);
154static int in_scrubprefix(struct in_ifaddr *);
155static void in_sysctl_init(struct sysctllog **);
156
157#ifndef SUBNETSARELOCAL
158#define SUBNETSARELOCAL 1
159#endif
160
161#ifndef HOSTZEROBROADCAST
162#define HOSTZEROBROADCAST 0
163#endif
164
165/* Note: 61, 127, 251, 509, 1021, 2039 are good. */
166#ifndef IN_MULTI_HASH_SIZE
167#define IN_MULTI_HASH_SIZE 509
168#endif
169
170static int subnetsarelocal = SUBNETSARELOCAL;
171static int hostzeroisbroadcast = HOSTZEROBROADCAST;
172
173/*
174 * This list is used to keep track of in_multi chains which belong to
175 * deleted interface addresses. We use in_ifaddr so that a chain head
176 * won't be deallocated until all multicast address record are deleted.
177 */
178
179LIST_HEAD(in_multihashhead, in_multi); /* Type of the hash head */
180
181static struct pool inmulti_pool;
182static u_int in_multientries;
183static struct in_multihashhead *in_multihashtbl;
184static u_long in_multihash;
185static krwlock_t in_multilock;
186
187#define IN_MULTI_HASH(x, ifp) \
188 (in_multihashtbl[(u_long)((x) ^ (ifp->if_index)) % IN_MULTI_HASH_SIZE])
189
190/* XXX DEPRECATED. Keep them to avoid breaking kvm(3) users. */
191struct in_ifaddrhashhead * in_ifaddrhashtbl;
192u_long in_ifaddrhash;
193struct in_ifaddrhead in_ifaddrhead;
194static kmutex_t in_ifaddr_lock;
195
196pserialize_t in_ifaddrhash_psz;
197struct pslist_head * in_ifaddrhashtbl_pslist;
198u_long in_ifaddrhash_pslist;
199struct pslist_head in_ifaddrhead_pslist;
200
201void
202in_init(void)
203{
204 pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl",
205 NULL, IPL_SOFTNET);
206 TAILQ_INIT(&in_ifaddrhead);
207 PSLIST_INIT(&in_ifaddrhead_pslist);
208
209 in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
210 &in_ifaddrhash);
211
212 in_ifaddrhash_psz = pserialize_create();
213 in_ifaddrhashtbl_pslist = hashinit(IN_IFADDR_HASH_SIZE, HASH_PSLIST,
214 true, &in_ifaddrhash_pslist);
215 mutex_init(&in_ifaddr_lock, MUTEX_DEFAULT, IPL_NONE);
216
217 in_multihashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
218 &in_multihash);
219 rw_init(&in_multilock);
220
221 in_sysctl_init(NULL);
222}
223
224/*
225 * Return 1 if an internet address is for a ``local'' host
226 * (one to which we have a connection). If subnetsarelocal
227 * is true, this includes other subnets of the local net.
228 * Otherwise, it includes only the directly-connected (sub)nets.
229 */
230int
231in_localaddr(struct in_addr in)
232{
233 struct in_ifaddr *ia;
234 int localaddr = 0;
235 int s = pserialize_read_enter();
236
237 if (subnetsarelocal) {
238 IN_ADDRLIST_READER_FOREACH(ia) {
239 if ((in.s_addr & ia->ia_netmask) == ia->ia_net) {
240 localaddr = 1;
241 break;
242 }
243 }
244 } else {
245 IN_ADDRLIST_READER_FOREACH(ia) {
246 if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet) {
247 localaddr = 1;
248 break;
249 }
250 }
251 }
252 pserialize_read_exit(s);
253
254 return localaddr;
255}
256
257/*
258 * Determine whether an IP address is in a reserved set of addresses
259 * that may not be forwarded, or whether datagrams to that destination
260 * may be forwarded.
261 */
262int
263in_canforward(struct in_addr in)
264{
265 u_int32_t net;
266
267 if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr))
268 return (0);
269 if (IN_CLASSA(in.s_addr)) {
270 net = in.s_addr & IN_CLASSA_NET;
271 if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
272 return (0);
273 }
274 return (1);
275}
276
277/*
278 * Trim a mask in a sockaddr
279 */
280void
281in_socktrim(struct sockaddr_in *ap)
282{
283 char *cplim = (char *) &ap->sin_addr;
284 char *cp = (char *) (&ap->sin_addr + 1);
285
286 ap->sin_len = 0;
287 while (--cp >= cplim)
288 if (*cp) {
289 (ap)->sin_len = cp - (char *) (ap) + 1;
290 break;
291 }
292}
293
294/*
295 * Routine to take an Internet address and convert into a
296 * "dotted quad" representation for printing.
297 */
298const char *
299in_fmtaddr(struct in_addr addr)
300{
301 static char buf[sizeof("123.456.789.123")];
302
303 addr.s_addr = ntohl(addr.s_addr);
304
305 snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
306 (addr.s_addr >> 24) & 0xFF,
307 (addr.s_addr >> 16) & 0xFF,
308 (addr.s_addr >> 8) & 0xFF,
309 (addr.s_addr >> 0) & 0xFF);
310 return buf;
311}
312
313/*
314 * Maintain the "in_maxmtu" variable, which is the largest
315 * mtu for non-local interfaces with AF_INET addresses assigned
316 * to them that are up.
317 */
318unsigned long in_maxmtu;
319
320void
321in_setmaxmtu(void)
322{
323 struct in_ifaddr *ia;
324 struct ifnet *ifp;
325 unsigned long maxmtu = 0;
326 int s = pserialize_read_enter();
327
328 IN_ADDRLIST_READER_FOREACH(ia) {
329 if ((ifp = ia->ia_ifp) == 0)
330 continue;
331 if ((ifp->if_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP)
332 continue;
333 if (ifp->if_mtu > maxmtu)
334 maxmtu = ifp->if_mtu;
335 }
336 if (maxmtu)
337 in_maxmtu = maxmtu;
338 pserialize_read_exit(s);
339}
340
341static u_int
342in_mask2len(struct in_addr *mask)
343{
344 u_int x, y;
345 u_char *p;
346
347 p = (u_char *)mask;
348 for (x = 0; x < sizeof(*mask); x++) {
349 if (p[x] != 0xff)
350 break;
351 }
352 y = 0;
353 if (x < sizeof(*mask)) {
354 for (y = 0; y < NBBY; y++) {
355 if ((p[x] & (0x80 >> y)) == 0)
356 break;
357 }
358 }
359 return x * NBBY + y;
360}
361
362static void
363in_len2mask(struct in_addr *mask, u_int len)
364{
365 u_int i;
366 u_char *p;
367
368 p = (u_char *)mask;
369 memset(mask, 0, sizeof(*mask));
370 for (i = 0; i < len / NBBY; i++)
371 p[i] = 0xff;
372 if (len % NBBY)
373 p[i] = (0xff00 >> (len % NBBY)) & 0xff;
374}
375
376/*
377 * Generic internet control operations (ioctl's).
378 * Ifp is 0 if not an interface-specific ioctl.
379 */
380/* ARGSUSED */
381static int
382in_control0(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
383{
384 struct ifreq *ifr = (struct ifreq *)data;
385 struct in_ifaddr *ia = NULL;
386 struct in_aliasreq *ifra = (struct in_aliasreq *)data;
387 struct sockaddr_in oldaddr, *new_dstaddr;
388 int error, hostIsNew, maskIsNew;
389 int newifaddr = 0;
390 bool run_hook = false;
391 bool need_reinsert = false;
392 struct psref psref;
393 int bound;
394
395 switch (cmd) {
396 case SIOCALIFADDR:
397 case SIOCDLIFADDR:
398 case SIOCGLIFADDR:
399 if (ifp == NULL)
400 return EINVAL;
401 return in_lifaddr_ioctl(so, cmd, data, ifp);
402 case SIOCGIFADDRPREF:
403 case SIOCSIFADDRPREF:
404 if (ifp == NULL)
405 return EINVAL;
406 return ifaddrpref_ioctl(so, cmd, data, ifp);
407 }
408
409 bound = curlwp_bind();
410 /*
411 * Find address for this interface, if it exists.
412 */
413 if (ifp != NULL)
414 ia = in_get_ia_from_ifp_psref(ifp, &psref);
415
416 hostIsNew = 1; /* moved here to appease gcc */
417 switch (cmd) {
418 case SIOCAIFADDR:
419 case SIOCDIFADDR:
420 case SIOCGIFALIAS:
421 case SIOCGIFAFLAG_IN:
422 if (ifra->ifra_addr.sin_family == AF_INET) {
423 int s;
424
425 if (ia != NULL)
426 ia4_release(ia, &psref);
427 s = pserialize_read_enter();
428 IN_ADDRHASH_READER_FOREACH(ia,
429 ifra->ifra_addr.sin_addr.s_addr) {
430 if (ia->ia_ifp == ifp &&
431 in_hosteq(ia->ia_addr.sin_addr,
432 ifra->ifra_addr.sin_addr))
433 break;
434 }
435 if (ia != NULL)
436 ia4_acquire(ia, &psref);
437 pserialize_read_exit(s);
438 }
439 if ((cmd == SIOCDIFADDR ||
440 cmd == SIOCGIFALIAS ||
441 cmd == SIOCGIFAFLAG_IN) &&
442 ia == NULL) {
443 error = EADDRNOTAVAIL;
444 goto out;
445 }
446
447 if (cmd == SIOCDIFADDR &&
448 ifra->ifra_addr.sin_family == AF_UNSPEC) {
449 ifra->ifra_addr.sin_family = AF_INET;
450 }
451 /* FALLTHROUGH */
452 case SIOCSIFADDR:
453 if (ia == NULL || ia->ia_addr.sin_family != AF_INET)
454 ;
455 else if (ifra->ifra_addr.sin_len == 0) {
456 ifra->ifra_addr = ia->ia_addr;
457 hostIsNew = 0;
458 } else if (in_hosteq(ia->ia_addr.sin_addr,
459 ifra->ifra_addr.sin_addr))
460 hostIsNew = 0;
461 /* FALLTHROUGH */
462 case SIOCSIFDSTADDR:
463 if (ifra->ifra_addr.sin_family != AF_INET) {
464 error = EAFNOSUPPORT;
465 goto out;
466 }
467 /* FALLTHROUGH */
468 case SIOCSIFNETMASK:
469 if (ifp == NULL)
470 panic("in_control");
471
472 if (cmd == SIOCGIFALIAS || cmd == SIOCGIFAFLAG_IN)
473 break;
474
475 if (ia == NULL &&
476 (cmd == SIOCSIFNETMASK || cmd == SIOCSIFDSTADDR)) {
477 error = EADDRNOTAVAIL;
478 goto out;
479 }
480
481 if (kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_INTERFACE,
482 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
483 NULL) != 0) {
484 error = EPERM;
485 goto out;
486 }
487
488 if (ia == NULL) {
489 ia = malloc(sizeof(*ia), M_IFADDR, M_WAITOK|M_ZERO);
490 if (ia == NULL) {
491 error = ENOBUFS;
492 goto out;
493 }
494 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
495 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
496 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask);
497#ifdef IPSELSRC
498 ia->ia_ifa.ifa_getifa = in_getifa;
499#else /* IPSELSRC */
500 ia->ia_ifa.ifa_getifa = NULL;
501#endif /* IPSELSRC */
502 ia->ia_sockmask.sin_len = 8;
503 ia->ia_sockmask.sin_family = AF_INET;
504 if (ifp->if_flags & IFF_BROADCAST) {
505 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
506 ia->ia_broadaddr.sin_family = AF_INET;
507 }
508 ia->ia_ifp = ifp;
509 ia->ia_idsalt = cprng_fast32() % 65535;
510 LIST_INIT(&ia->ia_multiaddrs);
511 IN_ADDRHASH_ENTRY_INIT(ia);
512 IN_ADDRLIST_ENTRY_INIT(ia);
513 ifa_psref_init(&ia->ia_ifa);
514
515 newifaddr = 1;
516 }
517 break;
518
519 case SIOCSIFBRDADDR:
520 if (kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_INTERFACE,
521 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
522 NULL) != 0) {
523 error = EPERM;
524 goto out;
525 }
526 /* FALLTHROUGH */
527
528 case SIOCGIFADDR:
529 case SIOCGIFNETMASK:
530 case SIOCGIFDSTADDR:
531 case SIOCGIFBRDADDR:
532 if (ia == NULL) {
533 error = EADDRNOTAVAIL;
534 goto out;
535 }
536 break;
537 }
538 error = 0;
539 switch (cmd) {
540
541 case SIOCGIFADDR:
542 ifreq_setaddr(cmd, ifr, sintocsa(&ia->ia_addr));
543 break;
544
545 case SIOCGIFBRDADDR:
546 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
547 error = EINVAL;
548 goto out;
549 }
550 ifreq_setdstaddr(cmd, ifr, sintocsa(&ia->ia_broadaddr));
551 break;
552
553 case SIOCGIFDSTADDR:
554 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
555 error = EINVAL;
556 goto out;
557 }
558 ifreq_setdstaddr(cmd, ifr, sintocsa(&ia->ia_dstaddr));
559 break;
560
561 case SIOCGIFNETMASK:
562 /*
563 * We keep the number of trailing zero bytes the sin_len field
564 * of ia_sockmask, so we fix this before we pass it back to
565 * userland.
566 */
567 oldaddr = ia->ia_sockmask;
568 oldaddr.sin_len = sizeof(struct sockaddr_in);
569 ifreq_setaddr(cmd, ifr, (const void *)&oldaddr);
570 break;
571
572 case SIOCSIFDSTADDR:
573 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
574 error = EINVAL;
575 goto out;
576 }
577 oldaddr = ia->ia_dstaddr;
578 ia->ia_dstaddr = *satocsin(ifreq_getdstaddr(cmd, ifr));
579 if ((error = if_addr_init(ifp, &ia->ia_ifa, false)) != 0) {
580 ia->ia_dstaddr = oldaddr;
581 goto out;
582 }
583 if (ia->ia_flags & IFA_ROUTE) {
584 ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr);
585 rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST);
586 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
587 rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST|RTF_UP);
588 }
589 break;
590
591 case SIOCSIFBRDADDR:
592 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
593 error = EINVAL;
594 goto out;
595 }
596 ia->ia_broadaddr = *satocsin(ifreq_getbroadaddr(cmd, ifr));
597 break;
598
599 case SIOCSIFADDR:
600 if (!newifaddr) {
601 mutex_enter(&in_ifaddr_lock);
602 LIST_REMOVE(ia, ia_hash);
603 IN_ADDRHASH_WRITER_REMOVE(ia);
604 mutex_exit(&in_ifaddr_lock);
605#ifdef NET_MPSAFE
606 pserialize_perform(in_ifaddrhash_psz);
607#endif
608 IN_ADDRHASH_ENTRY_DESTROY(ia);
609 need_reinsert = true;
610 }
611 error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),
612 NULL, 1);
613
614 run_hook = true;
615 break;
616
617 case SIOCSIFNETMASK:
618 in_scrubprefix(ia);
619 ia->ia_sockmask = *satocsin(ifreq_getaddr(cmd, ifr));
620 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
621 if (!newifaddr) {
622 mutex_enter(&in_ifaddr_lock);
623 LIST_REMOVE(ia, ia_hash);
624 IN_ADDRHASH_WRITER_REMOVE(ia);
625 mutex_exit(&in_ifaddr_lock);
626#ifdef NET_MPSAFE
627 pserialize_perform(in_ifaddrhash_psz);
628#endif
629 IN_ADDRHASH_ENTRY_DESTROY(ia);
630 need_reinsert = true;
631 }
632 error = in_ifinit(ifp, ia, NULL, NULL, 0);
633 break;
634
635 case SIOCAIFADDR:
636 maskIsNew = 0;
637 if (ifra->ifra_mask.sin_len) {
638 in_scrubprefix(ia);
639 ia->ia_sockmask = ifra->ifra_mask;
640 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
641 maskIsNew = 1;
642 }
643 if ((ifp->if_flags & IFF_POINTOPOINT) &&
644 (ifra->ifra_dstaddr.sin_family == AF_INET)) {
645 new_dstaddr = &ifra->ifra_dstaddr;
646 maskIsNew = 1; /* We lie; but the effect's the same */
647 } else
648 new_dstaddr = NULL;
649 if (ifra->ifra_addr.sin_family == AF_INET &&
650 (hostIsNew || maskIsNew)) {
651 if (!newifaddr) {
652 mutex_enter(&in_ifaddr_lock);
653 LIST_REMOVE(ia, ia_hash);
654 IN_ADDRHASH_WRITER_REMOVE(ia);
655 mutex_exit(&in_ifaddr_lock);
656#ifdef NET_MPSAFE
657 pserialize_perform(in_ifaddrhash_psz);
658#endif
659 IN_ADDRHASH_ENTRY_DESTROY(ia);
660 need_reinsert = true;
661 }
662 error = in_ifinit(ifp, ia, &ifra->ifra_addr,
663 new_dstaddr, 0);
664 }
665 if ((ifp->if_flags & IFF_BROADCAST) &&
666 (ifra->ifra_broadaddr.sin_family == AF_INET))
667 ia->ia_broadaddr = ifra->ifra_broadaddr;
668 run_hook = true;
669 break;
670
671 case SIOCGIFALIAS:
672 ifra->ifra_mask = ia->ia_sockmask;
673 if ((ifp->if_flags & IFF_POINTOPOINT) &&
674 (ia->ia_dstaddr.sin_family == AF_INET))
675 ifra->ifra_dstaddr = ia->ia_dstaddr;
676 else if ((ifp->if_flags & IFF_BROADCAST) &&
677 (ia->ia_broadaddr.sin_family == AF_INET))
678 ifra->ifra_broadaddr = ia->ia_broadaddr;
679 else
680 memset(&ifra->ifra_broadaddr, 0,
681 sizeof(ifra->ifra_broadaddr));
682 break;
683
684 case SIOCGIFAFLAG_IN:
685 ifr->ifr_addrflags = ia->ia4_flags;
686 break;
687
688 case SIOCDIFADDR:
689 ia4_release(ia, &psref);
690 in_purgeaddr(&ia->ia_ifa);
691 ia = NULL;
692 run_hook = true;
693 break;
694
695#ifdef MROUTING
696 case SIOCGETVIFCNT:
697 case SIOCGETSGCNT:
698 error = mrt_ioctl(so, cmd, data);
699 break;
700#endif /* MROUTING */
701
702 default:
703 error = ENOTTY;
704 goto out;
705 }
706
707 /*
708 * XXX insert regardless of error to make in_purgeaddr below work.
709 * Need to improve.
710 */
711 if (newifaddr) {
712 ifaref(&ia->ia_ifa);
713 ifa_insert(ifp, &ia->ia_ifa);
714
715 mutex_enter(&in_ifaddr_lock);
716 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_list);
717 IN_ADDRLIST_WRITER_INSERT_TAIL(ia);
718 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
719 ia, ia_hash);
720 IN_ADDRHASH_WRITER_INSERT_HEAD(ia);
721 mutex_exit(&in_ifaddr_lock);
722 } else if (need_reinsert) {
723 mutex_enter(&in_ifaddr_lock);
724 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr),
725 ia, ia_hash);
726 IN_ADDRHASH_ENTRY_INIT(ia);
727 IN_ADDRHASH_WRITER_INSERT_HEAD(ia);
728 mutex_exit(&in_ifaddr_lock);
729 }
730
731 if (error == 0) {
732 if (run_hook)
733 (void)pfil_run_hooks(if_pfil,
734 (struct mbuf **)cmd, ifp, PFIL_IFADDR);
735 } else if (newifaddr) {
736 KASSERT(ia != NULL);
737 in_purgeaddr(&ia->ia_ifa);
738 ia = NULL;
739 }
740
741out:
742 if (!newifaddr && ia != NULL)
743 ia4_release(ia, &psref);
744 curlwp_bindx(bound);
745 return error;
746}
747
748int
749in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp)
750{
751 int error;
752
753#ifndef NET_MPSAFE
754 mutex_enter(softnet_lock);
755#endif
756 error = in_control0(so, cmd, data, ifp);
757#ifndef NET_MPSAFE
758 mutex_exit(softnet_lock);
759#endif
760
761 return error;
762}
763
764/* Add ownaddr as loopback rtentry. */
765static void
766in_ifaddlocal(struct ifaddr *ifa)
767{
768 struct in_ifaddr *ia;
769
770 ia = (struct in_ifaddr *)ifa;
771 if (ia->ia_addr.sin_addr.s_addr == INADDR_ANY ||
772 (ia->ia_ifp->if_flags & IFF_POINTOPOINT &&
773 in_hosteq(ia->ia_dstaddr.sin_addr, ia->ia_addr.sin_addr)))
774 {
775 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
776 return;
777 }
778
779 rt_ifa_addlocal(ifa);
780}
781
782/* Remove loopback entry of ownaddr */
783static void
784in_ifremlocal(struct ifaddr *ifa)
785{
786 struct in_ifaddr *ia, *p;
787 struct ifaddr *alt_ifa = NULL;
788 int ia_count = 0;
789 int s;
790 struct psref psref;
791 int bound = curlwp_bind();
792
793 ia = (struct in_ifaddr *)ifa;
794 /* Delete the entry if exactly one ifaddr matches the
795 * address, ifa->ifa_addr. */
796 s = pserialize_read_enter();
797 IN_ADDRLIST_READER_FOREACH(p) {
798 if (!in_hosteq(p->ia_addr.sin_addr, ia->ia_addr.sin_addr))
799 continue;
800 if (p->ia_ifp != ia->ia_ifp)
801 alt_ifa = &p->ia_ifa;
802 if (++ia_count > 1 && alt_ifa != NULL)
803 break;
804 }
805 if (alt_ifa != NULL && ia_count > 1)
806 ifa_acquire(alt_ifa, &psref);
807 pserialize_read_exit(s);
808
809 if (ia_count == 0)
810 goto out;
811
812 rt_ifa_remlocal(ifa, ia_count == 1 ? NULL : alt_ifa);
813 if (alt_ifa != NULL && ia_count > 1)
814 ifa_release(alt_ifa, &psref);
815out:
816 curlwp_bindx(bound);
817}
818
819static void
820in_scrubaddr(struct in_ifaddr *ia)
821{
822
823 /* stop DAD processing */
824 if (ia->ia_dad_stop != NULL)
825 ia->ia_dad_stop(&ia->ia_ifa);
826
827 in_scrubprefix(ia);
828 in_ifremlocal(&ia->ia_ifa);
829
830 if (ia->ia_allhosts != NULL) {
831 in_delmulti(ia->ia_allhosts);
832 ia->ia_allhosts = NULL;
833 }
834}
835
836/*
837 * Depends on it isn't called in concurrent. It should be guaranteed
838 * by ifa->ifa_ifp's ioctl lock. The possible callers are in_control
839 * and if_purgeaddrs; the former is called iva ifa->ifa_ifp's ioctl
840 * and the latter is called via ifa->ifa_ifp's if_detach. The functions
841 * never be executed in concurrent.
842 */
843void
844in_purgeaddr(struct ifaddr *ifa)
845{
846 struct in_ifaddr *ia = (void *) ifa;
847 struct ifnet *ifp = ifa->ifa_ifp;
848
849 KASSERT(!ifa_held(ifa));
850
851 in_scrubaddr(ia);
852
853 mutex_enter(&in_ifaddr_lock);
854 LIST_REMOVE(ia, ia_hash);
855 IN_ADDRHASH_WRITER_REMOVE(ia);
856 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_list);
857 IN_ADDRLIST_WRITER_REMOVE(ia);
858 ifa_remove(ifp, &ia->ia_ifa);
859 mutex_exit(&in_ifaddr_lock);
860
861#ifdef NET_MPSAFE
862 pserialize_perform(in_ifaddrhash_psz);
863#endif
864 IN_ADDRHASH_ENTRY_DESTROY(ia);
865 IN_ADDRLIST_ENTRY_DESTROY(ia);
866 ifafree(&ia->ia_ifa);
867 in_setmaxmtu();
868}
869
870void
871in_purgeif(struct ifnet *ifp) /* MUST be called at splsoftnet() */
872{
873 if_purgeaddrs(ifp, AF_INET, in_purgeaddr);
874 igmp_purgeif(ifp); /* manipulates pools */
875#ifdef MROUTING
876 ip_mrouter_detach(ifp);
877#endif
878}
879
880/*
881 * SIOC[GAD]LIFADDR.
882 * SIOCGLIFADDR: get first address. (???)
883 * SIOCGLIFADDR with IFLR_PREFIX:
884 * get first address that matches the specified prefix.
885 * SIOCALIFADDR: add the specified address.
886 * SIOCALIFADDR with IFLR_PREFIX:
887 * EINVAL since we can't deduce hostid part of the address.
888 * SIOCDLIFADDR: delete the specified address.
889 * SIOCDLIFADDR with IFLR_PREFIX:
890 * delete the first address that matches the specified prefix.
891 * return values:
892 * EINVAL on invalid parameters
893 * EADDRNOTAVAIL on prefix match failed/specified address not found
894 * other values may be returned from in_ioctl()
895 */
896static int
897in_lifaddr_ioctl(struct socket *so, u_long cmd, void *data,
898 struct ifnet *ifp)
899{
900 struct if_laddrreq *iflr = (struct if_laddrreq *)data;
901 struct ifaddr *ifa;
902 struct sockaddr *sa;
903
904 /* sanity checks */
905 if (data == NULL || ifp == NULL) {
906 panic("invalid argument to in_lifaddr_ioctl");
907 /*NOTRECHED*/
908 }
909
910 switch (cmd) {
911 case SIOCGLIFADDR:
912 /* address must be specified on GET with IFLR_PREFIX */
913 if ((iflr->flags & IFLR_PREFIX) == 0)
914 break;
915 /*FALLTHROUGH*/
916 case SIOCALIFADDR:
917 case SIOCDLIFADDR:
918 /* address must be specified on ADD and DELETE */
919 sa = (struct sockaddr *)&iflr->addr;
920 if (sa->sa_family != AF_INET)
921 return EINVAL;
922 if (sa->sa_len != sizeof(struct sockaddr_in))
923 return EINVAL;
924 /* XXX need improvement */
925 sa = (struct sockaddr *)&iflr->dstaddr;
926 if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET)
927 return EINVAL;
928 if (sa->sa_len != 0 && sa->sa_len != sizeof(struct sockaddr_in))
929 return EINVAL;
930 break;
931 default: /*shouldn't happen*/
932#if 0
933 panic("invalid cmd to in_lifaddr_ioctl");
934 /*NOTREACHED*/
935#else
936 return EOPNOTSUPP;
937#endif
938 }
939 if (sizeof(struct in_addr) * NBBY < iflr->prefixlen)
940 return EINVAL;
941
942 switch (cmd) {
943 case SIOCALIFADDR:
944 {
945 struct in_aliasreq ifra;
946
947 if (iflr->flags & IFLR_PREFIX)
948 return EINVAL;
949
950 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */
951 memset(&ifra, 0, sizeof(ifra));
952 memcpy(ifra.ifra_name, iflr->iflr_name,
953 sizeof(ifra.ifra_name));
954
955 memcpy(&ifra.ifra_addr, &iflr->addr,
956 ((struct sockaddr *)&iflr->addr)->sa_len);
957
958 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/
959 memcpy(&ifra.ifra_dstaddr, &iflr->dstaddr,
960 ((struct sockaddr *)&iflr->dstaddr)->sa_len);
961 }
962
963 ifra.ifra_mask.sin_family = AF_INET;
964 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in);
965 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen);
966
967 return in_control(so, SIOCAIFADDR, &ifra, ifp);
968 }
969 case SIOCGLIFADDR:
970 case SIOCDLIFADDR:
971 {
972 struct in_ifaddr *ia;
973 struct in_addr mask, candidate, match;
974 struct sockaddr_in *sin;
975 int cmp, s;
976
977 memset(&mask, 0, sizeof(mask));
978 memset(&match, 0, sizeof(match)); /* XXX gcc */
979 if (iflr->flags & IFLR_PREFIX) {
980 /* lookup a prefix rather than address. */
981 in_len2mask(&mask, iflr->prefixlen);
982
983 sin = (struct sockaddr_in *)&iflr->addr;
984 match.s_addr = sin->sin_addr.s_addr;
985 match.s_addr &= mask.s_addr;
986
987 /* if you set extra bits, that's wrong */
988 if (match.s_addr != sin->sin_addr.s_addr)
989 return EINVAL;
990
991 cmp = 1;
992 } else {
993 if (cmd == SIOCGLIFADDR) {
994 /* on getting an address, take the 1st match */
995 cmp = 0; /*XXX*/
996 } else {
997 /* on deleting an address, do exact match */
998 in_len2mask(&mask, 32);
999 sin = (struct sockaddr_in *)&iflr->addr;
1000 match.s_addr = sin->sin_addr.s_addr;
1001
1002 cmp = 1;
1003 }
1004 }
1005
1006 s = pserialize_read_enter();
1007 IFADDR_READER_FOREACH(ifa, ifp) {
1008 if (ifa->ifa_addr->sa_family != AF_INET)
1009 continue;
1010 if (cmp == 0)
1011 break;
1012 candidate.s_addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
1013 candidate.s_addr &= mask.s_addr;
1014 if (candidate.s_addr == match.s_addr)
1015 break;
1016 }
1017 if (ifa == NULL) {
1018 pserialize_read_exit(s);
1019 return EADDRNOTAVAIL;
1020 }
1021 ia = (struct in_ifaddr *)ifa;
1022
1023 if (cmd == SIOCGLIFADDR) {
1024 /* fill in the if_laddrreq structure */
1025 memcpy(&iflr->addr, &ia->ia_addr, ia->ia_addr.sin_len);
1026
1027 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1028 memcpy(&iflr->dstaddr, &ia->ia_dstaddr,
1029 ia->ia_dstaddr.sin_len);
1030 } else
1031 memset(&iflr->dstaddr, 0, sizeof(iflr->dstaddr));
1032
1033 iflr->prefixlen =
1034 in_mask2len(&ia->ia_sockmask.sin_addr);
1035
1036 iflr->flags = 0; /*XXX*/
1037 pserialize_read_exit(s);
1038
1039 return 0;
1040 } else {
1041 struct in_aliasreq ifra;
1042
1043 /* fill in_aliasreq and do ioctl(SIOCDIFADDR) */
1044 memset(&ifra, 0, sizeof(ifra));
1045 memcpy(ifra.ifra_name, iflr->iflr_name,
1046 sizeof(ifra.ifra_name));
1047
1048 memcpy(&ifra.ifra_addr, &ia->ia_addr,
1049 ia->ia_addr.sin_len);
1050 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
1051 memcpy(&ifra.ifra_dstaddr, &ia->ia_dstaddr,
1052 ia->ia_dstaddr.sin_len);
1053 }
1054 memcpy(&ifra.ifra_dstaddr, &ia->ia_sockmask,
1055 ia->ia_sockmask.sin_len);
1056 pserialize_read_exit(s);
1057
1058 return in_control(so, SIOCDIFADDR, &ifra, ifp);
1059 }
1060 }
1061 }
1062
1063 return EOPNOTSUPP; /*just for safety*/
1064}
1065
1066/*
1067 * Initialize an interface's internet address
1068 * and routing table entry.
1069 */
1070int
1071in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia,
1072 const struct sockaddr_in *sin, const struct sockaddr_in *dst, int scrub)
1073{
1074 u_int32_t i;
1075 struct sockaddr_in oldaddr, olddst;
1076 int s, oldflags, flags = RTF_UP, error, hostIsNew;
1077
1078 if (sin == NULL)
1079 sin = &ia->ia_addr;
1080 if (dst == NULL)
1081 dst = &ia->ia_dstaddr;
1082
1083 /*
1084 * Set up new addresses.
1085 */
1086 oldaddr = ia->ia_addr;
1087 olddst = ia->ia_dstaddr;
1088 oldflags = ia->ia4_flags;
1089 ia->ia_addr = *sin;
1090 ia->ia_dstaddr = *dst;
1091 hostIsNew = oldaddr.sin_family != AF_INET ||
1092 !in_hosteq(ia->ia_addr.sin_addr, oldaddr.sin_addr);
1093 if (!scrub)
1094 scrub = oldaddr.sin_family != ia->ia_dstaddr.sin_family ||
1095 !in_hosteq(ia->ia_dstaddr.sin_addr, olddst.sin_addr);
1096
1097 /*
1098 * Configure address flags.
1099 * We need to do this early because they maybe adjusted
1100 * by if_addr_init depending on the address.
1101 */
1102 if (ia->ia4_flags & IN_IFF_DUPLICATED) {
1103 ia->ia4_flags &= ~IN_IFF_DUPLICATED;
1104 hostIsNew = 1;
1105 }
1106 if (ifp->if_link_state == LINK_STATE_DOWN) {
1107 ia->ia4_flags |= IN_IFF_DETACHED;
1108 ia->ia4_flags &= ~IN_IFF_TENTATIVE;
1109 } else if (hostIsNew && if_do_dad(ifp))
1110 ia->ia4_flags |= IN_IFF_TRYTENTATIVE;
1111
1112 /*
1113 * Give the interface a chance to initialize
1114 * if this is its first address,
1115 * and to validate the address if necessary.
1116 */
1117 s = splnet();
1118 error = if_addr_init(ifp, &ia->ia_ifa, true);
1119 splx(s);
1120 /* Now clear the try tentative flag, it's job is done. */
1121 ia->ia4_flags &= ~IN_IFF_TRYTENTATIVE;
1122 if (error != 0) {
1123 ia->ia_addr = oldaddr;
1124 ia->ia_dstaddr = olddst;
1125 ia->ia4_flags = oldflags;
1126 return error;
1127 }
1128
1129 if (scrub || hostIsNew) {
1130 int newflags = ia->ia4_flags;
1131
1132 ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
1133 ia->ia_ifa.ifa_dstaddr = sintosa(&olddst);
1134 ia->ia4_flags = oldflags;
1135 if (hostIsNew)
1136 in_scrubaddr(ia);
1137 else if (scrub)
1138 in_scrubprefix(ia);
1139 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
1140 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
1141 ia->ia4_flags = newflags;
1142 }
1143
1144 /* Add the local route to the address */
1145 in_ifaddlocal(&ia->ia_ifa);
1146
1147 i = ia->ia_addr.sin_addr.s_addr;
1148 if (ifp->if_flags & IFF_POINTOPOINT)
1149 ia->ia_netmask = INADDR_BROADCAST; /* default to /32 */
1150 else if (IN_CLASSA(i))
1151 ia->ia_netmask = IN_CLASSA_NET;
1152 else if (IN_CLASSB(i))
1153 ia->ia_netmask = IN_CLASSB_NET;
1154 else
1155 ia->ia_netmask = IN_CLASSC_NET;
1156 /*
1157 * The subnet mask usually includes at least the standard network part,
1158 * but may may be smaller in the case of supernetting.
1159 * If it is set, we believe it.
1160 */
1161 if (ia->ia_subnetmask == 0) {
1162 ia->ia_subnetmask = ia->ia_netmask;
1163 ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask;
1164 } else
1165 ia->ia_netmask &= ia->ia_subnetmask;
1166
1167 ia->ia_net = i & ia->ia_netmask;
1168 ia->ia_subnet = i & ia->ia_subnetmask;
1169 in_socktrim(&ia->ia_sockmask);
1170 /* re-calculate the "in_maxmtu" value */
1171 in_setmaxmtu();
1172 /*
1173 * Add route for the network.
1174 */
1175 ia->ia_ifa.ifa_metric = ifp->if_metric;
1176 if (ifp->if_flags & IFF_BROADCAST) {
1177 ia->ia_broadaddr.sin_addr.s_addr =
1178 ia->ia_subnet | ~ia->ia_subnetmask;
1179 ia->ia_netbroadcast.s_addr =
1180 ia->ia_net | ~ia->ia_netmask;
1181 } else if (ifp->if_flags & IFF_LOOPBACK) {
1182 ia->ia_dstaddr = ia->ia_addr;
1183 flags |= RTF_HOST;
1184 } else if (ifp->if_flags & IFF_POINTOPOINT) {
1185 if (ia->ia_dstaddr.sin_family != AF_INET)
1186 return (0);
1187 flags |= RTF_HOST;
1188 }
1189 error = in_addprefix(ia, flags);
1190 /*
1191 * If the interface supports multicast, join the "all hosts"
1192 * multicast group on that interface.
1193 */
1194 if ((ifp->if_flags & IFF_MULTICAST) != 0 && ia->ia_allhosts == NULL) {
1195 struct in_addr addr;
1196
1197 addr.s_addr = INADDR_ALLHOSTS_GROUP;
1198 ia->ia_allhosts = in_addmulti(&addr, ifp);
1199 }
1200
1201 if (hostIsNew &&
1202 ia->ia4_flags & IN_IFF_TENTATIVE &&
1203 if_do_dad(ifp))
1204 ia->ia_dad_start((struct ifaddr *)ia);
1205
1206 return error;
1207}
1208
1209#define rtinitflags(x) \
1210 ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \
1211 ? RTF_HOST : 0)
1212
1213/*
1214 * add a route to prefix ("connected route" in cisco terminology).
1215 * does nothing if there's some interface address with the same prefix already.
1216 */
1217static int
1218in_addprefix(struct in_ifaddr *target, int flags)
1219{
1220 struct in_ifaddr *ia;
1221 struct in_addr prefix, mask, p;
1222 int error;
1223 int s;
1224
1225 if ((flags & RTF_HOST) != 0)
1226 prefix = target->ia_dstaddr.sin_addr;
1227 else {
1228 prefix = target->ia_addr.sin_addr;
1229 mask = target->ia_sockmask.sin_addr;
1230 prefix.s_addr &= mask.s_addr;
1231 }
1232
1233 s = pserialize_read_enter();
1234 IN_ADDRLIST_READER_FOREACH(ia) {
1235 if (rtinitflags(ia))
1236 p = ia->ia_dstaddr.sin_addr;
1237 else {
1238 p = ia->ia_addr.sin_addr;
1239 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
1240 }
1241
1242 if (prefix.s_addr != p.s_addr)
1243 continue;
1244
1245 /*
1246 * if we got a matching prefix route inserted by other
1247 * interface address, we don't need to bother
1248 *
1249 * XXX RADIX_MPATH implications here? -dyoung
1250 */
1251 if (ia->ia_flags & IFA_ROUTE) {
1252 pserialize_read_exit(s);
1253 return 0;
1254 }
1255 }
1256 pserialize_read_exit(s);
1257
1258 /*
1259 * noone seem to have prefix route. insert it.
1260 */
1261 error = rtinit(&target->ia_ifa, RTM_ADD, flags);
1262 if (error == 0)
1263 target->ia_flags |= IFA_ROUTE;
1264 else if (error == EEXIST) {
1265 /*
1266 * the fact the route already exists is not an error.
1267 */
1268 error = 0;
1269 }
1270 return error;
1271}
1272
1273/*
1274 * remove a route to prefix ("connected route" in cisco terminology).
1275 * re-installs the route by using another interface address, if there's one
1276 * with the same prefix (otherwise we lose the route mistakenly).
1277 */
1278static int
1279in_scrubprefix(struct in_ifaddr *target)
1280{
1281 struct in_ifaddr *ia;
1282 struct in_addr prefix, mask, p;
1283 int error;
1284 int s;
1285
1286 /* If we don't have IFA_ROUTE we have nothing to do */
1287 if ((target->ia_flags & IFA_ROUTE) == 0)
1288 return 0;
1289
1290 if (rtinitflags(target))
1291 prefix = target->ia_dstaddr.sin_addr;
1292 else {
1293 prefix = target->ia_addr.sin_addr;
1294 mask = target->ia_sockmask.sin_addr;
1295 prefix.s_addr &= mask.s_addr;
1296 }
1297
1298 s = pserialize_read_enter();
1299 IN_ADDRLIST_READER_FOREACH(ia) {
1300 if (rtinitflags(ia))
1301 p = ia->ia_dstaddr.sin_addr;
1302 else {
1303 p = ia->ia_addr.sin_addr;
1304 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr;
1305 }
1306
1307 if (prefix.s_addr != p.s_addr)
1308 continue;
1309
1310 /*
1311 * if we got a matching prefix route, move IFA_ROUTE to him
1312 */
1313 if ((ia->ia_flags & IFA_ROUTE) == 0) {
1314 struct psref psref;
1315 int bound = curlwp_bind();
1316
1317 ia4_acquire(ia, &psref);
1318 pserialize_read_exit(s);
1319
1320 rtinit(&target->ia_ifa, RTM_DELETE,
1321 rtinitflags(target));
1322 target->ia_flags &= ~IFA_ROUTE;
1323
1324 error = rtinit(&ia->ia_ifa, RTM_ADD,
1325 rtinitflags(ia) | RTF_UP);
1326 if (error == 0)
1327 ia->ia_flags |= IFA_ROUTE;
1328
1329 ia4_release(ia, &psref);
1330 curlwp_bindx(bound);
1331
1332 return error;
1333 }
1334 }
1335 pserialize_read_exit(s);
1336
1337 /*
1338 * noone seem to have prefix route. remove it.
1339 */
1340 rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target));
1341 target->ia_flags &= ~IFA_ROUTE;
1342 return 0;
1343}
1344
1345#undef rtinitflags
1346
1347/*
1348 * Return 1 if the address might be a local broadcast address.
1349 */
1350int
1351in_broadcast(struct in_addr in, struct ifnet *ifp)
1352{
1353 struct ifaddr *ifa;
1354 int s;
1355
1356 KASSERT(ifp != NULL);
1357
1358 if (in.s_addr == INADDR_BROADCAST ||
1359 in_nullhost(in))
1360 return 1;
1361 if ((ifp->if_flags & IFF_BROADCAST) == 0)
1362 return 0;
1363 /*
1364 * Look through the list of addresses for a match
1365 * with a broadcast address.
1366 */
1367#define ia (ifatoia(ifa))
1368 s = pserialize_read_enter();
1369 IFADDR_READER_FOREACH(ifa, ifp) {
1370 if (ifa->ifa_addr->sa_family == AF_INET &&
1371 !in_hosteq(in, ia->ia_addr.sin_addr) &&
1372 (in_hosteq(in, ia->ia_broadaddr.sin_addr) ||
1373 in_hosteq(in, ia->ia_netbroadcast) ||
1374 (hostzeroisbroadcast &&
1375 /*
1376 * Check for old-style (host 0) broadcast.
1377 */
1378 (in.s_addr == ia->ia_subnet ||
1379 in.s_addr == ia->ia_net)))) {
1380 pserialize_read_exit(s);
1381 return 1;
1382 }
1383 }
1384 pserialize_read_exit(s);
1385 return (0);
1386#undef ia
1387}
1388
1389/*
1390 * perform DAD when interface becomes IFF_UP.
1391 */
1392void
1393in_if_link_up(struct ifnet *ifp)
1394{
1395 struct ifaddr *ifa;
1396 struct in_ifaddr *ia;
1397 int s, bound;
1398
1399 /* Ensure it's sane to run DAD */
1400 if (ifp->if_link_state == LINK_STATE_DOWN)
1401 return;
1402 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
1403 return;
1404
1405 bound = curlwp_bind();
1406 s = pserialize_read_enter();
1407 IFADDR_READER_FOREACH(ifa, ifp) {
1408 struct psref psref;
1409
1410 if (ifa->ifa_addr->sa_family != AF_INET)
1411 continue;
1412 ifa_acquire(ifa, &psref);
1413 pserialize_read_exit(s);
1414
1415 ia = (struct in_ifaddr *)ifa;
1416
1417 /* If detached then mark as tentative */
1418 if (ia->ia4_flags & IN_IFF_DETACHED) {
1419 ia->ia4_flags &= ~IN_IFF_DETACHED;
1420 if (if_do_dad(ifp) && ia->ia_dad_start != NULL)
1421 ia->ia4_flags |= IN_IFF_TENTATIVE;
1422 else if ((ia->ia4_flags & IN_IFF_TENTATIVE) == 0)
1423 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1424 }
1425
1426 if (ia->ia4_flags & IN_IFF_TENTATIVE) {
1427 /* Clear the duplicated flag as we're starting DAD. */
1428 ia->ia4_flags &= ~IN_IFF_DUPLICATED;
1429 ia->ia_dad_start(ifa);
1430 }
1431
1432 s = pserialize_read_enter();
1433 ifa_release(ifa, &psref);
1434 }
1435 pserialize_read_exit(s);
1436 curlwp_bindx(bound);
1437}
1438
1439void
1440in_if_up(struct ifnet *ifp)
1441{
1442
1443 /* interface may not support link state, so bring it up also */
1444 in_if_link_up(ifp);
1445}
1446
1447/*
1448 * Mark all addresses as detached.
1449 */
1450void
1451in_if_link_down(struct ifnet *ifp)
1452{
1453 struct ifaddr *ifa;
1454 struct in_ifaddr *ia;
1455 int s, bound;
1456
1457 bound = curlwp_bind();
1458 s = pserialize_read_enter();
1459 IFADDR_READER_FOREACH(ifa, ifp) {
1460 struct psref psref;
1461
1462 if (ifa->ifa_addr->sa_family != AF_INET)
1463 continue;
1464 ifa_acquire(ifa, &psref);
1465 pserialize_read_exit(s);
1466
1467 ia = (struct in_ifaddr *)ifa;
1468
1469 /* Stop DAD processing */
1470 if (ia->ia_dad_stop != NULL)
1471 ia->ia_dad_stop(ifa);
1472
1473 /*
1474 * Mark the address as detached.
1475 */
1476 if (!(ia->ia4_flags & IN_IFF_DETACHED)) {
1477 ia->ia4_flags |= IN_IFF_DETACHED;
1478 ia->ia4_flags &=
1479 ~(IN_IFF_TENTATIVE | IN_IFF_DUPLICATED);
1480 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1481 }
1482
1483 s = pserialize_read_enter();
1484 ifa_release(ifa, &psref);
1485 }
1486 pserialize_read_exit(s);
1487 curlwp_bindx(bound);
1488}
1489
1490void
1491in_if_down(struct ifnet *ifp)
1492{
1493
1494 in_if_link_down(ifp);
1495}
1496
1497void
1498in_if_link_state_change(struct ifnet *ifp, int link_state)
1499{
1500
1501 switch (link_state) {
1502 case LINK_STATE_DOWN:
1503 in_if_link_down(ifp);
1504 break;
1505 case LINK_STATE_UP:
1506 in_if_link_up(ifp);
1507 break;
1508 }
1509}
1510
1511/*
1512 * in_lookup_multi: look up the in_multi record for a given IP
1513 * multicast address on a given interface. If no matching record is
1514 * found, return NULL.
1515 */
1516struct in_multi *
1517in_lookup_multi(struct in_addr addr, ifnet_t *ifp)
1518{
1519 struct in_multi *inm;
1520
1521 KASSERT(rw_lock_held(&in_multilock));
1522
1523 LIST_FOREACH(inm, &IN_MULTI_HASH(addr.s_addr, ifp), inm_list) {
1524 if (in_hosteq(inm->inm_addr, addr) && inm->inm_ifp == ifp)
1525 break;
1526 }
1527 return inm;
1528}
1529
1530/*
1531 * in_multi_group: check whether the address belongs to an IP multicast
1532 * group we are joined on this interface. Returns true or false.
1533 */
1534bool
1535in_multi_group(struct in_addr addr, ifnet_t *ifp, int flags)
1536{
1537 bool ingroup;
1538
1539 if (__predict_true(flags & IP_IGMP_MCAST) == 0) {
1540 rw_enter(&in_multilock, RW_READER);
1541 ingroup = in_lookup_multi(addr, ifp) != NULL;
1542 rw_exit(&in_multilock);
1543 } else {
1544 /* XXX Recursive call from ip_output(). */
1545 KASSERT(rw_lock_held(&in_multilock));
1546 ingroup = in_lookup_multi(addr, ifp) != NULL;
1547 }
1548 return ingroup;
1549}
1550
1551/*
1552 * Add an address to the list of IP multicast addresses for a given interface.
1553 */
1554struct in_multi *
1555in_addmulti(struct in_addr *ap, ifnet_t *ifp)
1556{
1557 struct sockaddr_in sin;
1558 struct in_multi *inm;
1559
1560 /*
1561 * See if address already in list.
1562 */
1563 rw_enter(&in_multilock, RW_WRITER);
1564 inm = in_lookup_multi(*ap, ifp);
1565 if (inm != NULL) {
1566 /*
1567 * Found it; just increment the reference count.
1568 */
1569 inm->inm_refcount++;
1570 rw_exit(&in_multilock);
1571 return inm;
1572 }
1573
1574 /*
1575 * New address; allocate a new multicast record.
1576 */
1577 inm = pool_get(&inmulti_pool, PR_NOWAIT);
1578 if (inm == NULL) {
1579 rw_exit(&in_multilock);
1580 return NULL;
1581 }
1582 inm->inm_addr = *ap;
1583 inm->inm_ifp = ifp;
1584 inm->inm_refcount = 1;
1585
1586 /*
1587 * Ask the network driver to update its multicast reception
1588 * filter appropriately for the new address.
1589 */
1590 sockaddr_in_init(&sin, ap, 0);
1591 if (if_mcast_op(ifp, SIOCADDMULTI, sintosa(&sin)) != 0) {
1592 rw_exit(&in_multilock);
1593 pool_put(&inmulti_pool, inm);
1594 return NULL;
1595 }
1596
1597 /*
1598 * Let IGMP know that we have joined a new IP multicast group.
1599 */
1600 if (igmp_joingroup(inm) != 0) {
1601 rw_exit(&in_multilock);
1602 pool_put(&inmulti_pool, inm);
1603 return NULL;
1604 }
1605 LIST_INSERT_HEAD(
1606 &IN_MULTI_HASH(inm->inm_addr.s_addr, ifp),
1607 inm, inm_list);
1608 in_multientries++;
1609 rw_exit(&in_multilock);
1610
1611 return inm;
1612}
1613
1614/*
1615 * Delete a multicast address record.
1616 */
1617void
1618in_delmulti(struct in_multi *inm)
1619{
1620 struct sockaddr_in sin;
1621
1622 rw_enter(&in_multilock, RW_WRITER);
1623 if (--inm->inm_refcount > 0) {
1624 rw_exit(&in_multilock);
1625 return;
1626 }
1627
1628 /*
1629 * No remaining claims to this record; let IGMP know that
1630 * we are leaving the multicast group.
1631 */
1632 igmp_leavegroup(inm);
1633
1634 /*
1635 * Notify the network driver to update its multicast reception
1636 * filter.
1637 */
1638 sockaddr_in_init(&sin, &inm->inm_addr, 0);
1639 if_mcast_op(inm->inm_ifp, SIOCDELMULTI, sintosa(&sin));
1640
1641 /*
1642 * Unlink from list.
1643 */
1644 LIST_REMOVE(inm, inm_list);
1645 in_multientries--;
1646 rw_exit(&in_multilock);
1647
1648 pool_put(&inmulti_pool, inm);
1649}
1650
1651/*
1652 * in_next_multi: step through all of the in_multi records, one at a time.
1653 * The current position is remembered in "step", which the caller must
1654 * provide. in_first_multi(), below, must be called to initialize "step"
1655 * and get the first record. Both macros return a NULL "inm" when there
1656 * are no remaining records.
1657 */
1658struct in_multi *
1659in_next_multi(struct in_multistep *step)
1660{
1661 struct in_multi *inm;
1662
1663 KASSERT(rw_lock_held(&in_multilock));
1664
1665 while (step->i_inm == NULL && step->i_n < IN_MULTI_HASH_SIZE) {
1666 step->i_inm = LIST_FIRST(&in_multihashtbl[++step->i_n]);
1667 }
1668 if ((inm = step->i_inm) != NULL) {
1669 step->i_inm = LIST_NEXT(inm, inm_list);
1670 }
1671 return inm;
1672}
1673
1674struct in_multi *
1675in_first_multi(struct in_multistep *step)
1676{
1677 KASSERT(rw_lock_held(&in_multilock));
1678
1679 step->i_n = 0;
1680 step->i_inm = LIST_FIRST(&in_multihashtbl[0]);
1681 return in_next_multi(step);
1682}
1683
1684void
1685in_multi_lock(int op)
1686{
1687 rw_enter(&in_multilock, op);
1688}
1689
1690void
1691in_multi_unlock(void)
1692{
1693 rw_exit(&in_multilock);
1694}
1695
1696int
1697in_multi_lock_held(void)
1698{
1699 return rw_lock_held(&in_multilock);
1700}
1701
1702struct in_ifaddr *
1703in_selectsrc(struct sockaddr_in *sin, struct route *ro,
1704 int soopts, struct ip_moptions *mopts, int *errorp, struct psref *psref)
1705{
1706 struct rtentry *rt = NULL;
1707 struct in_ifaddr *ia = NULL;
1708
1709 KASSERT(ISSET(curlwp->l_pflag, LP_BOUND));
1710 /*
1711 * If route is known or can be allocated now, take the
1712 * source address from the interface. Otherwise, punt.
1713 */
1714 if ((soopts & SO_DONTROUTE) != 0)
1715 rtcache_free(ro);
1716 else {
1717 union {
1718 struct sockaddr dst;
1719 struct sockaddr_in dst4;
1720 } u;
1721
1722 sockaddr_in_init(&u.dst4, &sin->sin_addr, 0);
1723 rt = rtcache_lookup(ro, &u.dst);
1724 }
1725 /*
1726 * If we found a route, use the address
1727 * corresponding to the outgoing interface
1728 * unless it is the loopback (in case a route
1729 * to our address on another net goes to loopback).
1730 *
1731 * XXX Is this still true? Do we care?
1732 */
1733 if (rt != NULL && (rt->rt_ifp->if_flags & IFF_LOOPBACK) == 0) {
1734 int s;
1735 struct ifaddr *ifa;
1736 /*
1737 * Just in case. May not need to do this workaround.
1738 * Revisit when working on rtentry MP-ification.
1739 */
1740 s = pserialize_read_enter();
1741 IFADDR_READER_FOREACH(ifa, rt->rt_ifp) {
1742 if (ifa == rt->rt_ifa)
1743 break;
1744 }
1745 if (ifa != NULL)
1746 ifa_acquire(ifa, psref);
1747 pserialize_read_exit(s);
1748
1749 ia = ifatoia(ifa);
1750 }
1751 if (ia == NULL) {
1752 u_int16_t fport = sin->sin_port;
1753 struct ifaddr *ifa;
1754 int s;
1755
1756 sin->sin_port = 0;
1757 ifa = ifa_ifwithladdr_psref(sintosa(sin), psref);
1758 sin->sin_port = fport;
1759 if (ifa == NULL) {
1760 /* Find 1st non-loopback AF_INET address */
1761 s = pserialize_read_enter();
1762 IN_ADDRLIST_READER_FOREACH(ia) {
1763 if (!(ia->ia_ifp->if_flags & IFF_LOOPBACK))
1764 break;
1765 }
1766 if (ia != NULL)
1767 ia4_acquire(ia, psref);
1768 pserialize_read_exit(s);
1769 } else {
1770 /* ia is already referenced by psref */
1771 ia = ifatoia(ifa);
1772 }
1773 if (ia == NULL) {
1774 *errorp = EADDRNOTAVAIL;
1775 return NULL;
1776 }
1777 }
1778 /*
1779 * If the destination address is multicast and an outgoing
1780 * interface has been set as a multicast option, use the
1781 * address of that interface as our source address.
1782 */
1783 if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) {
1784 struct ip_moptions *imo;
1785
1786 imo = mopts;
1787 if (imo->imo_multicast_if_index != 0) {
1788 struct ifnet *ifp;
1789 int s;
1790
1791 if (ia != NULL)
1792 ia4_release(ia, psref);
1793 s = pserialize_read_enter();
1794 ifp = if_byindex(imo->imo_multicast_if_index);
1795 if (ifp != NULL) {
1796 /* XXX */
1797 ia = in_get_ia_from_ifp_psref(ifp, psref);
1798 } else
1799 ia = NULL;
1800 if (ia == NULL || ia->ia4_flags & IN_IFF_NOTREADY) {
1801 pserialize_read_exit(s);
1802 if (ia != NULL)
1803 ia4_release(ia, psref);
1804 *errorp = EADDRNOTAVAIL;
1805 return NULL;
1806 }
1807 pserialize_read_exit(s);
1808 }
1809 }
1810 if (ia->ia_ifa.ifa_getifa != NULL) {
1811 ia = ifatoia((*ia->ia_ifa.ifa_getifa)(&ia->ia_ifa,
1812 sintosa(sin)));
1813 if (ia == NULL) {
1814 *errorp = EADDRNOTAVAIL;
1815 return NULL;
1816 }
1817 /* FIXME NOMPSAFE */
1818 ia4_acquire(ia, psref);
1819 }
1820#ifdef GETIFA_DEBUG
1821 else
1822 printf("%s: missing ifa_getifa\n", __func__);
1823#endif
1824 return ia;
1825}
1826
1827#if NARP > 0
1828
1829struct in_llentry {
1830 struct llentry base;
1831};
1832
1833#define IN_LLTBL_DEFAULT_HSIZE 32
1834#define IN_LLTBL_HASH(k, h) \
1835 (((((((k >> 8) ^ k) >> 8) ^ k) >> 8) ^ k) & ((h) - 1))
1836
1837/*
1838 * Do actual deallocation of @lle.
1839 * Called by LLE_FREE_LOCKED when number of references
1840 * drops to zero.
1841 */
1842static void
1843in_lltable_destroy_lle(struct llentry *lle)
1844{
1845
1846 LLE_WUNLOCK(lle);
1847 LLE_LOCK_DESTROY(lle);
1848 kmem_intr_free(lle, sizeof(*lle));
1849}
1850
1851static struct llentry *
1852in_lltable_new(struct in_addr addr4, u_int flags)
1853{
1854 struct in_llentry *lle;
1855
1856 lle = kmem_intr_zalloc(sizeof(*lle), KM_NOSLEEP);
1857 if (lle == NULL) /* NB: caller generates msg */
1858 return NULL;
1859
1860 /*
1861 * For IPv4 this will trigger "arpresolve" to generate
1862 * an ARP request.
1863 */
1864 lle->base.la_expire = time_uptime; /* mark expired */
1865 lle->base.r_l3addr.addr4 = addr4;
1866 lle->base.lle_refcnt = 1;
1867 lle->base.lle_free = in_lltable_destroy_lle;
1868 LLE_LOCK_INIT(&lle->base);
1869 callout_init(&lle->base.la_timer, CALLOUT_MPSAFE);
1870
1871 return (&lle->base);
1872}
1873
1874#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \
1875 (((ntohl((d).s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 )
1876
1877static int
1878in_lltable_match_prefix(const struct sockaddr *prefix,
1879 const struct sockaddr *mask, u_int flags, struct llentry *lle)
1880{
1881 const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix;
1882 const struct sockaddr_in *msk = (const struct sockaddr_in *)mask;
1883
1884 /*
1885 * (flags & LLE_STATIC) means deleting all entries
1886 * including static ARP entries.
1887 */
1888 if (IN_ARE_MASKED_ADDR_EQUAL(lle->r_l3addr.addr4, pfx, msk) &&
1889 ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
1890 return (1);
1891
1892 return (0);
1893}
1894
1895static void
1896in_lltable_free_entry(struct lltable *llt, struct llentry *lle)
1897{
1898 struct ifnet *ifp __diagused;
1899 size_t pkts_dropped;
1900
1901 LLE_WLOCK_ASSERT(lle);
1902 KASSERT(llt != NULL);
1903
1904 /* Unlink entry from table if not already */
1905 if ((lle->la_flags & LLE_LINKED) != 0) {
1906 ifp = llt->llt_ifp;
1907 IF_AFDATA_WLOCK_ASSERT(ifp);
1908 lltable_unlink_entry(llt, lle);
1909 }
1910
1911 /* cancel timer */
1912 if (callout_halt(&lle->lle_timer, &lle->lle_lock))
1913 LLE_REMREF(lle);
1914
1915 /* Drop hold queue */
1916 pkts_dropped = llentry_free(lle);
1917 arp_stat_add(ARP_STAT_DFRDROPPED, (uint64_t)pkts_dropped);
1918}
1919
1920static int
1921in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
1922{
1923 struct rtentry *rt;
1924 int error = EINVAL;
1925
1926 KASSERTMSG(l3addr->sa_family == AF_INET,
1927 "sin_family %d", l3addr->sa_family);
1928
1929 rt = rtalloc1(l3addr, 0);
1930 if (rt == NULL)
1931 return error;
1932
1933 /*
1934 * If the gateway for an existing host route matches the target L3
1935 * address, which is a special route inserted by some implementation
1936 * such as MANET, and the interface is of the correct type, then
1937 * allow for ARP to proceed.
1938 */
1939 if (rt->rt_flags & RTF_GATEWAY) {
1940 if (!(rt->rt_flags & RTF_HOST) || !rt->rt_ifp ||
1941 rt->rt_ifp->if_type != IFT_ETHER ||
1942#ifdef __FreeBSD__
1943 (rt->rt_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 ||
1944#else
1945 (rt->rt_ifp->if_flags & IFF_NOARP) != 0 ||
1946#endif
1947 memcmp(rt->rt_gateway->sa_data, l3addr->sa_data,
1948 sizeof(in_addr_t)) != 0) {
1949 goto error;
1950 }
1951 }
1952
1953 /*
1954 * Make sure that at least the destination address is covered
1955 * by the route. This is for handling the case where 2 or more
1956 * interfaces have the same prefix. An incoming packet arrives
1957 * on one interface and the corresponding outgoing packet leaves
1958 * another interface.
1959 */
1960 if (!(rt->rt_flags & RTF_HOST) && rt->rt_ifp != ifp) {
1961 const char *sa, *mask, *addr, *lim;
1962 int len;
1963
1964 mask = (const char *)rt_mask(rt);
1965 /*
1966 * Just being extra cautious to avoid some custom
1967 * code getting into trouble.
1968 */
1969 if (mask == NULL)
1970 goto error;
1971
1972 sa = (const char *)rt_getkey(rt);
1973 addr = (const char *)l3addr;
1974 len = ((const struct sockaddr_in *)l3addr)->sin_len;
1975 lim = addr + len;
1976
1977 for ( ; addr < lim; sa++, mask++, addr++) {
1978 if ((*sa ^ *addr) & *mask) {
1979#ifdef DIAGNOSTIC
1980 log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
1981 inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
1982#endif
1983 goto error;
1984 }
1985 }
1986 }
1987
1988 error = 0;
1989error:
1990 rtfree(rt);
1991 return error;
1992}
1993
1994static inline uint32_t
1995in_lltable_hash_dst(const struct in_addr dst, uint32_t hsize)
1996{
1997
1998 return (IN_LLTBL_HASH(dst.s_addr, hsize));
1999}
2000
2001static uint32_t
2002in_lltable_hash(const struct llentry *lle, uint32_t hsize)
2003{
2004
2005 return (in_lltable_hash_dst(lle->r_l3addr.addr4, hsize));
2006}
2007
2008static void
2009in_lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
2010{
2011 struct sockaddr_in *sin;
2012
2013 sin = (struct sockaddr_in *)sa;
2014 memset(sin, 0, sizeof(*sin));
2015 sin->sin_family = AF_INET;
2016 sin->sin_len = sizeof(*sin);
2017 sin->sin_addr = lle->r_l3addr.addr4;
2018}
2019
2020static inline struct llentry *
2021in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
2022{
2023 struct llentry *lle;
2024 struct llentries *lleh;
2025 u_int hashidx;
2026
2027 hashidx = in_lltable_hash_dst(dst, llt->llt_hsize);
2028 lleh = &llt->lle_head[hashidx];
2029 LIST_FOREACH(lle, lleh, lle_next) {
2030 if (lle->la_flags & LLE_DELETED)
2031 continue;
2032 if (lle->r_l3addr.addr4.s_addr == dst.s_addr)
2033 break;
2034 }
2035
2036 return (lle);
2037}
2038
2039static int
2040in_lltable_delete(struct lltable *llt, u_int flags,
2041 const struct sockaddr *l3addr)
2042{
2043 const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
2044 struct ifnet *ifp __diagused = llt->llt_ifp;
2045 struct llentry *lle;
2046
2047 IF_AFDATA_WLOCK_ASSERT(ifp);
2048 KASSERTMSG(l3addr->sa_family == AF_INET,
2049 "sin_family %d", l3addr->sa_family);
2050
2051 lle = in_lltable_find_dst(llt, sin->sin_addr);
2052 if (lle == NULL) {
2053#ifdef DIAGNOSTIC
2054 log(LOG_INFO, "interface address is missing from cache = %p in delete\n", lle);
2055#endif
2056 return (ENOENT);
2057 }
2058
2059 LLE_WLOCK(lle);
2060 lle->la_flags |= LLE_DELETED;
2061#ifdef DIAGNOSTIC
2062 log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
2063#endif
2064 if ((lle->la_flags & (LLE_STATIC | LLE_IFADDR)) == LLE_STATIC)
2065 llentry_free(lle);
2066 else
2067 LLE_WUNLOCK(lle);
2068
2069 return (0);
2070}
2071
2072static struct llentry *
2073in_lltable_create(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
2074{
2075 const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
2076 struct ifnet *ifp = llt->llt_ifp;
2077 struct llentry *lle;
2078
2079 IF_AFDATA_WLOCK_ASSERT(ifp);
2080 KASSERTMSG(l3addr->sa_family == AF_INET,
2081 "sin_family %d", l3addr->sa_family);
2082
2083 lle = in_lltable_find_dst(llt, sin->sin_addr);
2084
2085 if (lle != NULL) {
2086 LLE_WLOCK(lle);
2087 return (lle);
2088 }
2089
2090 /* no existing record, we need to create new one */
2091
2092 /*
2093 * A route that covers the given address must have
2094 * been installed 1st because we are doing a resolution,
2095 * verify this.
2096 */
2097 if (!(flags & LLE_IFADDR) &&
2098 in_lltable_rtcheck(ifp, flags, l3addr) != 0)
2099 return (NULL);
2100
2101 lle = in_lltable_new(sin->sin_addr, flags);
2102 if (lle == NULL) {
2103 log(LOG_INFO, "lla_lookup: new lle malloc failed\n");
2104 return (NULL);
2105 }
2106 lle->la_flags = flags;
2107 if ((flags & LLE_IFADDR) == LLE_IFADDR) {
2108 memcpy(&lle->ll_addr, CLLADDR(ifp->if_sadl), ifp->if_addrlen);
2109 lle->la_flags |= (LLE_VALID | LLE_STATIC);
2110 }
2111
2112 lltable_link_entry(llt, lle);
2113 LLE_WLOCK(lle);
2114
2115 return (lle);
2116}
2117
2118/*
2119 * Return NULL if not found or marked for deletion.
2120 * If found return lle read locked.
2121 */
2122static struct llentry *
2123in_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
2124{
2125 const struct sockaddr_in *sin = (const struct sockaddr_in *)l3addr;
2126 struct llentry *lle;
2127
2128 IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
2129 KASSERTMSG(l3addr->sa_family == AF_INET,
2130 "sin_family %d", l3addr->sa_family);
2131
2132 lle = in_lltable_find_dst(llt, sin->sin_addr);
2133
2134 if (lle == NULL)
2135 return NULL;
2136
2137 if (flags & LLE_EXCLUSIVE)
2138 LLE_WLOCK(lle);
2139 else
2140 LLE_RLOCK(lle);
2141
2142 return lle;
2143}
2144
2145static int
2146in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
2147 struct rt_walkarg *w)
2148{
2149 struct sockaddr_in sin;
2150
2151 LLTABLE_LOCK_ASSERT();
2152
2153 /* skip deleted entries */
2154 if (lle->la_flags & LLE_DELETED)
2155 return 0;
2156
2157 sockaddr_in_init(&sin, &lle->r_l3addr.addr4, 0);
2158
2159 return lltable_dump_entry(llt, lle, w, sintosa(&sin));
2160}
2161
2162#endif /* NARP > 0 */
2163
2164static int
2165in_multicast_sysctl(SYSCTLFN_ARGS)
2166{
2167 struct ifnet *ifp;
2168 struct ifaddr *ifa;
2169 struct in_ifaddr *ifa4;
2170 struct in_multi *inm;
2171 uint32_t tmp;
2172 int error;
2173 size_t written;
2174 struct psref psref;
2175 int bound;
2176
2177 if (namelen != 1)
2178 return EINVAL;
2179
2180 bound = curlwp_bind();
2181 ifp = if_get_byindex(name[0], &psref);
2182 if (ifp == NULL) {
2183 curlwp_bindx(bound);
2184 return ENODEV;
2185 }
2186
2187 if (oldp == NULL) {
2188 *oldlenp = 0;
2189 IFADDR_FOREACH(ifa, ifp) {
2190 if (ifa->ifa_addr->sa_family != AF_INET)
2191 continue;
2192 ifa4 = (void *)ifa;
2193 LIST_FOREACH(inm, &ifa4->ia_multiaddrs, inm_list) {
2194 *oldlenp += 2 * sizeof(struct in_addr) +
2195 sizeof(uint32_t);
2196 }
2197 }
2198 if_put(ifp, &psref);
2199 curlwp_bindx(bound);
2200 return 0;
2201 }
2202
2203 error = 0;
2204 written = 0;
2205 IFADDR_FOREACH(ifa, ifp) {
2206 if (ifa->ifa_addr->sa_family != AF_INET)
2207 continue;
2208 ifa4 = (void *)ifa;
2209 LIST_FOREACH(inm, &ifa4->ia_multiaddrs, inm_list) {
2210 if (written + 2 * sizeof(struct in_addr) +
2211 sizeof(uint32_t) > *oldlenp)
2212 goto done;
2213 error = sysctl_copyout(l, &ifa4->ia_addr.sin_addr,
2214 oldp, sizeof(struct in_addr));
2215 if (error)
2216 goto done;
2217 oldp = (char *)oldp + sizeof(struct in_addr);
2218 written += sizeof(struct in_addr);
2219 error = sysctl_copyout(l, &inm->inm_addr,
2220 oldp, sizeof(struct in_addr));
2221 if (error)
2222 goto done;
2223 oldp = (char *)oldp + sizeof(struct in_addr);
2224 written += sizeof(struct in_addr);
2225 tmp = inm->inm_refcount;
2226 error = sysctl_copyout(l, &tmp, oldp, sizeof(tmp));
2227 if (error)
2228 goto done;
2229 oldp = (char *)oldp + sizeof(tmp);
2230 written += sizeof(tmp);
2231 }
2232 }
2233done:
2234 if_put(ifp, &psref);
2235 curlwp_bindx(bound);
2236 *oldlenp = written;
2237 return error;
2238}
2239
2240static void
2241in_sysctl_init(struct sysctllog **clog)
2242{
2243 sysctl_createv(clog, 0, NULL, NULL,
2244 CTLFLAG_PERMANENT,
2245 CTLTYPE_NODE, "inet",
2246 SYSCTL_DESCR("PF_INET related settings"),
2247 NULL, 0, NULL, 0,
2248 CTL_NET, PF_INET, CTL_EOL);
2249 sysctl_createv(clog, 0, NULL, NULL,
2250 CTLFLAG_PERMANENT,
2251 CTLTYPE_NODE, "multicast",
2252 SYSCTL_DESCR("Multicast information"),
2253 in_multicast_sysctl, 0, NULL, 0,
2254 CTL_NET, PF_INET, CTL_CREATE, CTL_EOL);
2255 sysctl_createv(clog, 0, NULL, NULL,
2256 CTLFLAG_PERMANENT,
2257 CTLTYPE_NODE, "ip",
2258 SYSCTL_DESCR("IPv4 related settings"),
2259 NULL, 0, NULL, 0,
2260 CTL_NET, PF_INET, IPPROTO_IP, CTL_EOL);
2261
2262 sysctl_createv(clog, 0, NULL, NULL,
2263 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2264 CTLTYPE_INT, "subnetsarelocal",
2265 SYSCTL_DESCR("Whether logical subnets are considered "
2266 "local"),
2267 NULL, 0, &subnetsarelocal, 0,
2268 CTL_NET, PF_INET, IPPROTO_IP,
2269 IPCTL_SUBNETSARELOCAL, CTL_EOL);
2270 sysctl_createv(clog, 0, NULL, NULL,
2271 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2272 CTLTYPE_INT, "hostzerobroadcast",
2273 SYSCTL_DESCR("All zeroes address is broadcast address"),
2274 NULL, 0, &hostzeroisbroadcast, 0,
2275 CTL_NET, PF_INET, IPPROTO_IP,
2276 IPCTL_HOSTZEROBROADCAST, CTL_EOL);
2277}
2278
2279#if NARP > 0
2280
2281static struct lltable *
2282in_lltattach(struct ifnet *ifp)
2283{
2284 struct lltable *llt;
2285
2286 llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
2287 llt->llt_af = AF_INET;
2288 llt->llt_ifp = ifp;
2289
2290 llt->llt_lookup = in_lltable_lookup;
2291 llt->llt_create = in_lltable_create;
2292 llt->llt_delete = in_lltable_delete;
2293 llt->llt_dump_entry = in_lltable_dump_entry;
2294 llt->llt_hash = in_lltable_hash;
2295 llt->llt_fill_sa_entry = in_lltable_fill_sa_entry;
2296 llt->llt_free_entry = in_lltable_free_entry;
2297 llt->llt_match_prefix = in_lltable_match_prefix;
2298 lltable_link(llt);
2299
2300 return (llt);
2301}
2302
2303#endif /* NARP > 0 */
2304
2305void *
2306in_domifattach(struct ifnet *ifp)
2307{
2308 struct in_ifinfo *ii;
2309
2310 ii = kmem_zalloc(sizeof(struct in_ifinfo), KM_SLEEP);
2311 KASSERT(ii != NULL);
2312
2313#if NARP > 0
2314 ii->ii_llt = in_lltattach(ifp);
2315#endif
2316
2317#ifdef IPSELSRC
2318 ii->ii_selsrc = in_selsrc_domifattach(ifp);
2319 KASSERT(ii->ii_selsrc != NULL);
2320#endif
2321
2322 return ii;
2323}
2324
2325void
2326in_domifdetach(struct ifnet *ifp, void *aux)
2327{
2328 struct in_ifinfo *ii = aux;
2329
2330#ifdef IPSELSRC
2331 in_selsrc_domifdetach(ifp, ii->ii_selsrc);
2332#endif
2333#if NARP > 0
2334 lltable_free(ii->ii_llt);
2335#endif
2336 kmem_free(ii, sizeof(struct in_ifinfo));
2337}
2338