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