1/* 2 * Copyright (c) 2004-2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1982, 1989, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 */ 61 62#include <kern/debug.h> 63#include <netinet/in_arp.h> 64#include <sys/types.h> 65#include <sys/param.h> 66#include <sys/kernel_types.h> 67#include <sys/syslog.h> 68#include <sys/systm.h> 69#include <sys/time.h> 70#include <sys/kernel.h> 71#include <sys/mbuf.h> 72#include <sys/sysctl.h> 73#include <sys/mcache.h> 74#include <sys/protosw.h> 75#include <string.h> 76#include <net/if_arp.h> 77#include <net/if_dl.h> 78#include <net/dlil.h> 79#include <net/if_types.h> 80#include <net/if_llreach.h> 81#include <net/route.h> 82 83#include <netinet/if_ether.h> 84#include <netinet/in_var.h> 85#include <kern/zalloc.h> 86 87#define CONST_LLADDR(s) ((const u_char*)((s)->sdl_data + (s)->sdl_nlen)) 88 89static const size_t MAX_HW_LEN = 10; 90 91/* 92 * Synchronization notes: 93 * 94 * The global list of ARP entries are stored in llinfo_arp; an entry 95 * gets inserted into the list when the route is created and gets 96 * removed from the list when it is deleted; this is done as part 97 * of RTM_ADD/RTM_RESOLVE/RTM_DELETE in arp_rtrequest(). 98 * 99 * Because rnh_lock and rt_lock for the entry are held during those 100 * operations, the same locks (and thus lock ordering) must be used 101 * elsewhere to access the relevant data structure fields: 102 * 103 * la_le.{le_next,le_prev}, la_rt 104 * 105 * - Routing lock (rnh_lock) 106 * 107 * la_hold, la_asked, la_llreach, la_lastused, la_flags 108 * 109 * - Routing entry lock (rt_lock) 110 * 111 * Due to the dependency on rt_lock, llinfo_arp has the same lifetime 112 * as the route entry itself. When a route is deleted (RTM_DELETE), 113 * it is simply removed from the global list but the memory is not 114 * freed until the route itself is freed. 115 */ 116struct llinfo_arp { 117 /* 118 * The following are protected by rnh_lock 119 */ 120 LIST_ENTRY(llinfo_arp) la_le; 121 struct rtentry *la_rt; 122 /* 123 * The following are protected by rt_lock 124 */ 125 struct mbuf *la_hold; /* last packet until resolved/timeout */ 126 struct if_llreach *la_llreach; /* link-layer reachability record */ 127 u_int64_t la_lastused; /* last used timestamp */ 128 u_int32_t la_asked; /* # of requests sent */ 129 u_int32_t la_maxtries; /* retry limit */ 130 uint32_t la_flags; 131#define LLINFO_RTRFAIL_EVTSENT 0x1 /* sent an ARP event */ 132}; 133static LIST_HEAD(, llinfo_arp) llinfo_arp; 134 135static int arp_timeout_run; /* arp_timeout is scheduled to run */ 136static void arp_timeout(void *); 137static void arp_sched_timeout(struct timeval *); 138 139static void arptfree(struct llinfo_arp *, void *); 140static errno_t arp_lookup_route(const struct in_addr *, int, 141 int, route_t *, unsigned int); 142static int arp_getstat SYSCTL_HANDLER_ARGS; 143 144static struct llinfo_arp *arp_llinfo_alloc(int); 145static void arp_llinfo_free(void *); 146static void arp_llinfo_purge(struct rtentry *); 147static void arp_llinfo_get_ri(struct rtentry *, struct rt_reach_info *); 148static void arp_llinfo_get_iflri(struct rtentry *, struct ifnet_llreach_info *); 149 150static __inline void arp_llreach_use(struct llinfo_arp *); 151static __inline int arp_llreach_reachable(struct llinfo_arp *); 152static void arp_llreach_alloc(struct rtentry *, struct ifnet *, void *, 153 unsigned int, boolean_t); 154 155extern int tvtohz(struct timeval *); 156 157static int arpinit_done; 158 159SYSCTL_DECL(_net_link_ether); 160SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW|CTLFLAG_LOCKED, 0, ""); 161 162/* timer values */ 163static int arpt_prune = (5*60*1); /* walk list every 5 minutes */ 164SYSCTL_INT(_net_link_ether_inet, OID_AUTO, prune_intvl, 165 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_prune, 0, ""); 166 167static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 168SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_age, 169 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_keep, 0, ""); 170 171static int arpt_down = 20; /* once declared down, don't send for 20 sec */ 172SYSCTL_INT(_net_link_ether_inet, OID_AUTO, host_down_time, 173 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_down, 0, ""); 174 175static int arp_llreach_base = (LL_BASE_REACHABLE / 1000); /* seconds */ 176SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_llreach_base, 177 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_llreach_base, LL_BASE_REACHABLE, 178 "default ARP link-layer reachability max lifetime (in seconds)"); 179 180#define ARP_UNICAST_LIMIT 5 /* # of probes until ARP refresh broadcast */ 181static u_int32_t arp_unicast_lim = ARP_UNICAST_LIMIT; 182SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_unicast_lim, 183 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_unicast_lim, ARP_UNICAST_LIMIT, 184 "number of unicast ARP refresh probes before using broadcast"); 185 186static u_int32_t arp_maxtries = 5; 187SYSCTL_INT(_net_link_ether_inet, OID_AUTO, maxtries, 188 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_maxtries, 0, ""); 189 190static int useloopback = 1; /* use loopback interface for local traffic */ 191SYSCTL_INT(_net_link_ether_inet, OID_AUTO, useloopback, 192 CTLFLAG_RW | CTLFLAG_LOCKED, &useloopback, 0, ""); 193 194static int arp_proxyall = 0; 195SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, 196 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_proxyall, 0, ""); 197 198static int arp_sendllconflict = 0; 199SYSCTL_INT(_net_link_ether_inet, OID_AUTO, sendllconflict, 200 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_sendllconflict, 0, ""); 201 202static int log_arp_warnings = 0; /* Thread safe: no accumulated state */ 203SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_warnings, 204 CTLFLAG_RW | CTLFLAG_LOCKED, 205 &log_arp_warnings, 0, 206 "log arp warning messages"); 207 208static int keep_announcements = 1; /* Thread safe: no aging of state */ 209SYSCTL_INT(_net_link_ether_inet, OID_AUTO, keep_announcements, 210 CTLFLAG_RW | CTLFLAG_LOCKED, 211 &keep_announcements, 0, 212 "keep arp announcements"); 213 214static int send_conflicting_probes = 1; /* Thread safe: no accumulated state */ 215SYSCTL_INT(_net_link_ether_inet, OID_AUTO, send_conflicting_probes, 216 CTLFLAG_RW | CTLFLAG_LOCKED, 217 &send_conflicting_probes, 0, 218 "send conflicting link-local arp probes"); 219 220static int arp_verbose; 221SYSCTL_INT(_net_link_ether_inet, OID_AUTO, verbose, 222 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_verbose, 0, ""); 223 224struct arpstat arpstat; 225SYSCTL_PROC(_net_link_ether_inet, OID_AUTO, stats, 226 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED, 227 0, 0, arp_getstat, "S,arpstat", 228 "ARP statistics (struct arpstat, net/if_arp.h)"); 229 230/* these are deprecated (read-only); use net.link.generic.system node instead */ 231SYSCTL_INT(_net_link_ether_inet, OID_AUTO, apple_hwcksum_tx, 232 CTLFLAG_RD | CTLFLAG_LOCKED, &hwcksum_tx, 0, ""); 233 234SYSCTL_INT(_net_link_ether_inet, OID_AUTO, apple_hwcksum_rx, 235 CTLFLAG_RD | CTLFLAG_LOCKED, &hwcksum_rx, 0, ""); 236 237static struct zone *llinfo_arp_zone; 238#define LLINFO_ARP_ZONE_MAX 256 /* maximum elements in zone */ 239#define LLINFO_ARP_ZONE_NAME "llinfo_arp" /* name for zone */ 240 241void 242arp_init(void) 243{ 244 VERIFY(!arpinit_done); 245 246 LIST_INIT(&llinfo_arp); 247 248 llinfo_arp_zone = zinit(sizeof (struct llinfo_arp), 249 LLINFO_ARP_ZONE_MAX * sizeof (struct llinfo_arp), 0, 250 LLINFO_ARP_ZONE_NAME); 251 if (llinfo_arp_zone == NULL) 252 panic("%s: failed allocating llinfo_arp_zone", __func__); 253 254 zone_change(llinfo_arp_zone, Z_EXPAND, TRUE); 255 zone_change(llinfo_arp_zone, Z_CALLERACCT, FALSE); 256 257 arpinit_done = 1; 258} 259 260static struct llinfo_arp * 261arp_llinfo_alloc(int how) 262{ 263 struct llinfo_arp *la; 264 265 la = (how == M_WAITOK) ? zalloc(llinfo_arp_zone) : 266 zalloc_noblock(llinfo_arp_zone); 267 if (la != NULL) 268 bzero(la, sizeof (*la)); 269 270 return (la); 271} 272 273static void 274arp_llinfo_free(void *arg) 275{ 276 struct llinfo_arp *la = arg; 277 278 if (la->la_le.le_next != NULL || la->la_le.le_prev != NULL) { 279 panic("%s: trying to free %p when it is in use", __func__, la); 280 /* NOTREACHED */ 281 } 282 283 /* Just in case there's anything there, free it */ 284 if (la->la_hold != NULL) { 285 m_freem(la->la_hold); 286 la->la_hold = NULL; 287 arpstat.purged++; 288 } 289 290 /* Purge any link-layer info caching */ 291 VERIFY(la->la_rt->rt_llinfo == la); 292 if (la->la_rt->rt_llinfo_purge != NULL) 293 la->la_rt->rt_llinfo_purge(la->la_rt); 294 295 zfree(llinfo_arp_zone, la); 296} 297 298static void 299arp_llinfo_purge(struct rtentry *rt) 300{ 301 struct llinfo_arp *la = rt->rt_llinfo; 302 303 RT_LOCK_ASSERT_HELD(rt); 304 VERIFY(rt->rt_llinfo_purge == arp_llinfo_purge && la != NULL); 305 306 if (la->la_llreach != NULL) { 307 RT_CONVERT_LOCK(rt); 308 ifnet_llreach_free(la->la_llreach); 309 la->la_llreach = NULL; 310 } 311 la->la_lastused = 0; 312} 313 314static void 315arp_llinfo_get_ri(struct rtentry *rt, struct rt_reach_info *ri) 316{ 317 struct llinfo_arp *la = rt->rt_llinfo; 318 struct if_llreach *lr = la->la_llreach; 319 320 if (lr == NULL) { 321 bzero(ri, sizeof (*ri)); 322 ri->ri_rssi = IFNET_RSSI_UNKNOWN; 323 ri->ri_lqm = IFNET_LQM_THRESH_OFF; 324 ri->ri_npm = IFNET_NPM_THRESH_UNKNOWN; 325 } else { 326 IFLR_LOCK(lr); 327 /* Export to rt_reach_info structure */ 328 ifnet_lr2ri(lr, ri); 329 /* Export ARP send expiration (calendar) time */ 330 ri->ri_snd_expire = 331 ifnet_llreach_up2calexp(lr, la->la_lastused); 332 IFLR_UNLOCK(lr); 333 } 334} 335 336static void 337arp_llinfo_get_iflri(struct rtentry *rt, struct ifnet_llreach_info *iflri) 338{ 339 struct llinfo_arp *la = rt->rt_llinfo; 340 struct if_llreach *lr = la->la_llreach; 341 342 if (lr == NULL) { 343 bzero(iflri, sizeof (*iflri)); 344 iflri->iflri_rssi = IFNET_RSSI_UNKNOWN; 345 iflri->iflri_lqm = IFNET_LQM_THRESH_OFF; 346 iflri->iflri_npm = IFNET_NPM_THRESH_UNKNOWN; 347 } else { 348 IFLR_LOCK(lr); 349 /* Export to ifnet_llreach_info structure */ 350 ifnet_lr2iflri(lr, iflri); 351 /* Export ARP send expiration (uptime) time */ 352 iflri->iflri_snd_expire = 353 ifnet_llreach_up2upexp(lr, la->la_lastused); 354 IFLR_UNLOCK(lr); 355 } 356} 357 358void 359arp_llreach_set_reachable(struct ifnet *ifp, void *addr, unsigned int alen) 360{ 361 /* Nothing more to do if it's disabled */ 362 if (arp_llreach_base == 0) 363 return; 364 365 ifnet_llreach_set_reachable(ifp, ETHERTYPE_IP, addr, alen); 366} 367 368static __inline void 369arp_llreach_use(struct llinfo_arp *la) 370{ 371 if (la->la_llreach != NULL) 372 la->la_lastused = net_uptime(); 373} 374 375static __inline int 376arp_llreach_reachable(struct llinfo_arp *la) 377{ 378 struct if_llreach *lr; 379 const char *why = NULL; 380 381 /* Nothing more to do if it's disabled; pretend it's reachable */ 382 if (arp_llreach_base == 0) 383 return (1); 384 385 if ((lr = la->la_llreach) == NULL) { 386 /* 387 * Link-layer reachability record isn't present for this 388 * ARP entry; pretend it's reachable and use it as is. 389 */ 390 return (1); 391 } else if (ifnet_llreach_reachable(lr)) { 392 /* 393 * Record is present, it's not shared with other ARP 394 * entries and a packet has recently been received 395 * from the remote host; consider it reachable. 396 */ 397 if (lr->lr_reqcnt == 1) 398 return (1); 399 400 /* Prime it up, if this is the first time */ 401 if (la->la_lastused == 0) { 402 VERIFY(la->la_llreach != NULL); 403 arp_llreach_use(la); 404 } 405 406 /* 407 * Record is present and shared with one or more ARP 408 * entries, and a packet has recently been received 409 * from the remote host. Since it's shared by more 410 * than one IP addresses, we can't rely on the link- 411 * layer reachability alone; consider it reachable if 412 * this ARP entry has been used "recently." 413 */ 414 if (ifnet_llreach_reachable_delta(lr, la->la_lastused)) 415 return (1); 416 417 why = "has alias(es) and hasn't been used in a while"; 418 } else { 419 why = "haven't heard from it in a while"; 420 } 421 422 if (arp_verbose > 1) { 423 char tmp[MAX_IPv4_STR_LEN]; 424 u_int64_t now = net_uptime(); 425 426 log(LOG_DEBUG, "%s: ARP probe(s) needed for %s; " 427 "%s [lastused %lld, lastrcvd %lld] secs ago\n", 428 if_name(lr->lr_ifp), inet_ntop(AF_INET, 429 &SIN(rt_key(la->la_rt))->sin_addr, tmp, sizeof (tmp)), why, 430 (la->la_lastused ? (int64_t)(now - la->la_lastused) : -1), 431 (lr->lr_lastrcvd ? (int64_t)(now - lr->lr_lastrcvd) : -1)); 432 433 } 434 return (0); 435} 436 437/* 438 * Obtain a link-layer source cache entry for the sender. 439 * 440 * NOTE: This is currently only for ARP/Ethernet. 441 */ 442static void 443arp_llreach_alloc(struct rtentry *rt, struct ifnet *ifp, void *addr, 444 unsigned int alen, boolean_t solicited) 445{ 446 VERIFY(rt->rt_expire == 0 || rt->rt_rmx.rmx_expire != 0); 447 VERIFY(rt->rt_expire != 0 || rt->rt_rmx.rmx_expire == 0); 448 449 if (arp_llreach_base != 0 && rt->rt_expire != 0 && 450 !(rt->rt_ifp->if_flags & IFF_LOOPBACK) && 451 ifp->if_addrlen == IF_LLREACH_MAXLEN && /* Ethernet */ 452 alen == ifp->if_addrlen) { 453 struct llinfo_arp *la = rt->rt_llinfo; 454 struct if_llreach *lr; 455 const char *why = NULL, *type = ""; 456 457 /* Become a regular mutex, just in case */ 458 RT_CONVERT_LOCK(rt); 459 460 if ((lr = la->la_llreach) != NULL) { 461 type = (solicited ? "ARP reply" : "ARP announcement"); 462 /* 463 * If target has changed, create a new record; 464 * otherwise keep existing record. 465 */ 466 IFLR_LOCK(lr); 467 if (bcmp(addr, lr->lr_key.addr, alen) != 0) { 468 IFLR_UNLOCK(lr); 469 /* Purge any link-layer info caching */ 470 VERIFY(rt->rt_llinfo_purge != NULL); 471 rt->rt_llinfo_purge(rt); 472 lr = NULL; 473 why = " for different target HW address; " 474 "using new llreach record"; 475 } else { 476 lr->lr_probes = 0; /* reset probe count */ 477 IFLR_UNLOCK(lr); 478 if (solicited) { 479 why = " for same target HW address; " 480 "keeping existing llreach record"; 481 } 482 } 483 } 484 485 if (lr == NULL) { 486 lr = la->la_llreach = ifnet_llreach_alloc(ifp, 487 ETHERTYPE_IP, addr, alen, arp_llreach_base); 488 if (lr != NULL) { 489 lr->lr_probes = 0; /* reset probe count */ 490 if (why == NULL) 491 why = "creating new llreach record"; 492 } 493 } 494 495 /* Bump up retry ceiling to accomodate unicast retries */ 496 if (lr != NULL) 497 la->la_maxtries = arp_maxtries + arp_unicast_lim; 498 499 if (arp_verbose > 1 && lr != NULL && why != NULL) { 500 char tmp[MAX_IPv4_STR_LEN]; 501 502 log(LOG_DEBUG, "%s: %s%s for %s\n", if_name(ifp), 503 type, why, inet_ntop(AF_INET, 504 &SIN(rt_key(rt))->sin_addr, tmp, sizeof (tmp))); 505 } 506 } 507} 508 509struct arptf_arg { 510 int draining; 511 uint32_t killed; 512 uint32_t aging; 513 uint32_t sticky; 514 uint32_t found; 515}; 516 517/* 518 * Free an arp entry. 519 */ 520static void 521arptfree(struct llinfo_arp *la, void *arg) 522{ 523 struct arptf_arg *ap = arg; 524 struct rtentry *rt = la->la_rt; 525 526 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); 527 528 /* rnh_lock acquired by caller protects rt from going away */ 529 RT_LOCK(rt); 530 531 VERIFY(rt->rt_expire == 0 || rt->rt_rmx.rmx_expire != 0); 532 VERIFY(rt->rt_expire != 0 || rt->rt_rmx.rmx_expire == 0); 533 534 ap->found++; 535 if (rt->rt_expire == 0 || (rt->rt_flags & RTF_STATIC)) { 536 ap->sticky++; 537 /* ARP entry is permanent? */ 538 if (rt->rt_expire == 0) { 539 RT_UNLOCK(rt); 540 return; 541 } 542 } 543 544 /* ARP entry hasn't expired and we're not draining? */ 545 if (!ap->draining && rt->rt_expire > net_uptime()) { 546 RT_UNLOCK(rt); 547 ap->aging++; 548 return; 549 } 550 551 if (rt->rt_refcnt > 0) { 552 /* 553 * ARP entry has expired, with outstanding refcnt. 554 * If we're not draining, force ARP query to be 555 * generated next time this entry is used. 556 */ 557 if (!ap->draining) { 558 struct sockaddr_dl *sdl = SDL(rt->rt_gateway); 559 if (sdl != NULL) 560 sdl->sdl_alen = 0; 561 la->la_asked = 0; 562 rt->rt_flags &= ~RTF_REJECT; 563 } 564 RT_UNLOCK(rt); 565 } else if (!(rt->rt_flags & RTF_STATIC)) { 566 /* 567 * ARP entry has no outstanding refcnt, and we're either 568 * draining or it has expired; delete it from the routing 569 * table. Safe to drop rt_lock and use rt_key, since holding 570 * rnh_lock here prevents another thread from calling 571 * rt_setgate() on this route. 572 */ 573 RT_UNLOCK(rt); 574 rtrequest_locked(RTM_DELETE, rt_key(rt), NULL, 575 rt_mask(rt), 0, NULL); 576 arpstat.timeouts++; 577 ap->killed++; 578 } else { 579 /* ARP entry is static; let it linger */ 580 RT_UNLOCK(rt); 581 } 582} 583 584void 585in_arpdrain(void *arg) 586{ 587#pragma unused(arg) 588 struct llinfo_arp *la, *ola; 589 struct arptf_arg farg; 590 591 if (arp_verbose) 592 log(LOG_DEBUG, "%s: draining ARP entries\n", __func__); 593 594 lck_mtx_lock(rnh_lock); 595 la = llinfo_arp.lh_first; 596 bzero(&farg, sizeof (farg)); 597 farg.draining = 1; 598 while ((ola = la) != NULL) { 599 la = la->la_le.le_next; 600 arptfree(ola, &farg); 601 } 602 if (arp_verbose) { 603 log(LOG_DEBUG, "%s: found %u, aging %u, sticky %u, killed %u\n", 604 __func__, farg.found, farg.aging, farg.sticky, farg.killed); 605 } 606 lck_mtx_unlock(rnh_lock); 607} 608 609/* 610 * Timeout routine. Age arp_tab entries periodically. 611 */ 612static void 613arp_timeout(void *arg) 614{ 615#pragma unused(arg) 616 struct llinfo_arp *la, *ola; 617 struct timeval atv; 618 struct arptf_arg farg; 619 620 lck_mtx_lock(rnh_lock); 621 la = llinfo_arp.lh_first; 622 bzero(&farg, sizeof (farg)); 623 while ((ola = la) != NULL) { 624 la = la->la_le.le_next; 625 arptfree(ola, &farg); 626 } 627 if (arp_verbose) { 628 log(LOG_DEBUG, "%s: found %u, aging %u, sticky %u, killed %u\n", 629 __func__, farg.found, farg.aging, farg.sticky, farg.killed); 630 } 631 atv.tv_usec = 0; 632 atv.tv_sec = arpt_prune; 633 /* re-arm the timer if there's work to do */ 634 arp_timeout_run = 0; 635 if (farg.aging > 0) 636 arp_sched_timeout(&atv); 637 else if (arp_verbose) 638 log(LOG_DEBUG, "%s: not rescheduling timer\n", __func__); 639 lck_mtx_unlock(rnh_lock); 640} 641 642static void 643arp_sched_timeout(struct timeval *atv) 644{ 645 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); 646 647 if (!arp_timeout_run) { 648 struct timeval tv; 649 650 if (atv == NULL) { 651 tv.tv_usec = 0; 652 tv.tv_sec = MAX(arpt_prune / 5, 1); 653 atv = &tv; 654 } 655 if (arp_verbose) { 656 log(LOG_DEBUG, "%s: timer scheduled in " 657 "T+%llus.%lluu\n", __func__, 658 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec); 659 } 660 arp_timeout_run = 1; 661 timeout(arp_timeout, NULL, tvtohz(atv)); 662 } 663} 664 665/* 666 * ifa_rtrequest() callback 667 */ 668static void 669arp_rtrequest(int req, struct rtentry *rt, struct sockaddr *sa) 670{ 671#pragma unused(sa) 672 struct sockaddr *gate = rt->rt_gateway; 673 struct llinfo_arp *la = rt->rt_llinfo; 674 static struct sockaddr_dl null_sdl = 675 { .sdl_len = sizeof (null_sdl), .sdl_family = AF_LINK }; 676 uint64_t timenow; 677 char buf[MAX_IPv4_STR_LEN]; 678 679 VERIFY(arpinit_done); 680 lck_mtx_assert(rnh_lock, LCK_MTX_ASSERT_OWNED); 681 RT_LOCK_ASSERT_HELD(rt); 682 683 if (rt->rt_flags & RTF_GATEWAY) 684 return; 685 686 timenow = net_uptime(); 687 switch (req) { 688 case RTM_ADD: 689 /* 690 * XXX: If this is a manually added route to interface 691 * such as older version of routed or gated might provide, 692 * restore cloning bit. 693 */ 694 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != NULL && 695 SIN(rt_mask(rt))->sin_addr.s_addr != INADDR_BROADCAST) 696 rt->rt_flags |= RTF_CLONING; 697 698 if (rt->rt_flags & RTF_CLONING) { 699 /* 700 * Case 1: This route should come from a route to iface. 701 */ 702 if (rt_setgate(rt, rt_key(rt), SA(&null_sdl)) == 0) { 703 gate = rt->rt_gateway; 704 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 705 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 706 /* 707 * In case we're called before 1.0 sec. 708 * has elapsed. 709 */ 710 rt_setexpire(rt, MAX(timenow, 1)); 711 } 712 break; 713 } 714 /* Announce a new entry if requested. */ 715 if (rt->rt_flags & RTF_ANNOUNCE) { 716 if (la != NULL) 717 arp_llreach_use(la); /* Mark use timestamp */ 718 RT_UNLOCK(rt); 719 dlil_send_arp(rt->rt_ifp, ARPOP_REQUEST, 720 SDL(gate), rt_key(rt), NULL, rt_key(rt), 0); 721 RT_LOCK(rt); 722 arpstat.txannounces++; 723 } 724 /* FALLTHRU */ 725 case RTM_RESOLVE: 726 if (gate->sa_family != AF_LINK || 727 gate->sa_len < sizeof (null_sdl)) { 728 arpstat.invalidreqs++; 729 log(LOG_ERR, "%s: route to %s has bad gateway address " 730 "(sa_family %u sa_len %u) on %s\n", 731 __func__, inet_ntop(AF_INET, 732 &SIN(rt_key(rt))->sin_addr.s_addr, buf, 733 sizeof (buf)), gate->sa_family, gate->sa_len, 734 if_name(rt->rt_ifp)); 735 break; 736 } 737 SDL(gate)->sdl_type = rt->rt_ifp->if_type; 738 SDL(gate)->sdl_index = rt->rt_ifp->if_index; 739 740 if (la != NULL) 741 break; /* This happens on a route change */ 742 743 /* 744 * Case 2: This route may come from cloning, or a manual route 745 * add with a LL address. 746 */ 747 rt->rt_llinfo = la = arp_llinfo_alloc(M_WAITOK); 748 if (la == NULL) { 749 arpstat.reqnobufs++; 750 break; 751 } 752 rt->rt_llinfo_get_ri = arp_llinfo_get_ri; 753 rt->rt_llinfo_get_iflri = arp_llinfo_get_iflri; 754 rt->rt_llinfo_purge = arp_llinfo_purge; 755 rt->rt_llinfo_free = arp_llinfo_free; 756 rt->rt_flags |= RTF_LLINFO; 757 la->la_rt = rt; 758 LIST_INSERT_HEAD(&llinfo_arp, la, la_le); 759 arpstat.inuse++; 760 761 /* We have at least one entry; arm the timer if not already */ 762 arp_sched_timeout(NULL); 763 764 /* 765 * This keeps the multicast addresses from showing up 766 * in `arp -a' listings as unresolved. It's not actually 767 * functional. Then the same for broadcast. For IPv4 768 * link-local address, keep the entry around even after 769 * it has expired. 770 */ 771 if (IN_MULTICAST(ntohl(SIN(rt_key(rt))->sin_addr.s_addr))) { 772 RT_UNLOCK(rt); 773 dlil_resolve_multi(rt->rt_ifp, rt_key(rt), gate, 774 sizeof (struct sockaddr_dl)); 775 RT_LOCK(rt); 776 rt_setexpire(rt, 0); 777 } else if (in_broadcast(SIN(rt_key(rt))->sin_addr, 778 rt->rt_ifp)) { 779 struct sockaddr_dl *gate_ll = SDL(gate); 780 size_t broadcast_len; 781 ifnet_llbroadcast_copy_bytes(rt->rt_ifp, 782 LLADDR(gate_ll), sizeof (gate_ll->sdl_data), 783 &broadcast_len); 784 gate_ll->sdl_alen = broadcast_len; 785 gate_ll->sdl_family = AF_LINK; 786 gate_ll->sdl_len = sizeof (struct sockaddr_dl); 787 /* In case we're called before 1.0 sec. has elapsed */ 788 rt_setexpire(rt, MAX(timenow, 1)); 789 } else if (IN_LINKLOCAL(ntohl(SIN(rt_key(rt))-> 790 sin_addr.s_addr))) { 791 rt->rt_flags |= RTF_STATIC; 792 } 793 794 /* Set default maximum number of retries */ 795 la->la_maxtries = arp_maxtries; 796 797 /* Become a regular mutex, just in case */ 798 RT_CONVERT_LOCK(rt); 799 IFA_LOCK_SPIN(rt->rt_ifa); 800 if (SIN(rt_key(rt))->sin_addr.s_addr == 801 (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) { 802 IFA_UNLOCK(rt->rt_ifa); 803 /* 804 * This test used to be 805 * if (loif.if_flags & IFF_UP) 806 * It allowed local traffic to be forced through the 807 * hardware by configuring the loopback down. However, 808 * it causes problems during network configuration 809 * for boards that can't receive packets they send. 810 * It is now necessary to clear "useloopback" and 811 * remove the route to force traffic out to the 812 * hardware. 813 */ 814 rt_setexpire(rt, 0); 815 ifnet_lladdr_copy_bytes(rt->rt_ifp, LLADDR(SDL(gate)), 816 SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen); 817 if (useloopback) { 818 if (rt->rt_ifp != lo_ifp) { 819 /* 820 * Purge any link-layer info caching. 821 */ 822 if (rt->rt_llinfo_purge != NULL) 823 rt->rt_llinfo_purge(rt); 824 825 /* 826 * Adjust route ref count for the 827 * interfaces. 828 */ 829 if (rt->rt_if_ref_fn != NULL) { 830 rt->rt_if_ref_fn(lo_ifp, 1); 831 rt->rt_if_ref_fn(rt->rt_ifp, -1); 832 } 833 } 834 rt->rt_ifp = lo_ifp; 835 /* 836 * If rmx_mtu is not locked, update it 837 * to the MTU used by the new interface. 838 */ 839 if (!(rt->rt_rmx.rmx_locks & RTV_MTU)) 840 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; 841 } 842 } else { 843 IFA_UNLOCK(rt->rt_ifa); 844 } 845 break; 846 847 case RTM_DELETE: 848 if (la == NULL) 849 break; 850 /* 851 * Unchain it but defer the actual freeing until the route 852 * itself is to be freed. rt->rt_llinfo still points to 853 * llinfo_arp, and likewise, la->la_rt still points to this 854 * route entry, except that RTF_LLINFO is now cleared. 855 */ 856 LIST_REMOVE(la, la_le); 857 la->la_le.le_next = NULL; 858 la->la_le.le_prev = NULL; 859 arpstat.inuse--; 860 861 /* 862 * Purge any link-layer info caching. 863 */ 864 if (rt->rt_llinfo_purge != NULL) 865 rt->rt_llinfo_purge(rt); 866 867 rt->rt_flags &= ~RTF_LLINFO; 868 if (la->la_hold != NULL) { 869 m_freem(la->la_hold); 870 la->la_hold = NULL; 871 arpstat.purged++; 872 } 873 } 874} 875 876/* 877 * convert hardware address to hex string for logging errors. 878 */ 879static const char * 880sdl_addr_to_hex(const struct sockaddr_dl *sdl, char *orig_buf, int buflen) 881{ 882 char *buf = orig_buf; 883 int i; 884 const u_char *lladdr = (u_char *)(size_t)sdl->sdl_data; 885 int maxbytes = buflen / 3; 886 887 if (maxbytes > sdl->sdl_alen) { 888 maxbytes = sdl->sdl_alen; 889 } 890 *buf = '\0'; 891 for (i = 0; i < maxbytes; i++) { 892 snprintf(buf, 3, "%02x", lladdr[i]); 893 buf += 2; 894 *buf = (i == maxbytes - 1) ? '\0' : ':'; 895 buf++; 896 } 897 return (orig_buf); 898} 899 900/* 901 * arp_lookup_route will lookup the route for a given address. 902 * 903 * The address must be for a host on a local network on this interface. 904 * If the returned route is non-NULL, the route is locked and the caller 905 * is responsible for unlocking it and releasing its reference. 906 */ 907static errno_t 908arp_lookup_route(const struct in_addr *addr, int create, int proxy, 909 route_t *route, unsigned int ifscope) 910{ 911 struct sockaddr_inarp sin = 912 { sizeof (sin), AF_INET, 0, { 0 }, { 0 }, 0, 0 }; 913 const char *why = NULL; 914 errno_t error = 0; 915 route_t rt; 916 917 *route = NULL; 918 919 sin.sin_addr.s_addr = addr->s_addr; 920 sin.sin_other = proxy ? SIN_PROXY : 0; 921 922 /* 923 * If the destination is a link-local address, don't 924 * constrain the lookup (don't scope it). 925 */ 926 if (IN_LINKLOCAL(ntohl(addr->s_addr))) 927 ifscope = IFSCOPE_NONE; 928 929 rt = rtalloc1_scoped((struct sockaddr *)&sin, create, 0, ifscope); 930 if (rt == NULL) 931 return (ENETUNREACH); 932 933 RT_LOCK(rt); 934 935 if (rt->rt_flags & RTF_GATEWAY) { 936 why = "host is not on local network"; 937 error = ENETUNREACH; 938 } else if (!(rt->rt_flags & RTF_LLINFO)) { 939 why = "could not allocate llinfo"; 940 error = ENOMEM; 941 } else if (rt->rt_gateway->sa_family != AF_LINK) { 942 why = "gateway route is not ours"; 943 error = EPROTONOSUPPORT; 944 } 945 946 if (error != 0) { 947 if (create && (arp_verbose || log_arp_warnings)) { 948 char tmp[MAX_IPv4_STR_LEN]; 949 log(LOG_DEBUG, "%s: link#%d %s failed: %s\n", 950 __func__, ifscope, inet_ntop(AF_INET, addr, tmp, 951 sizeof (tmp)), why); 952 } 953 954 /* 955 * If there are no references to this route, and it is 956 * a cloned route, and not static, and ARP had created 957 * the route, then purge it from the routing table as 958 * it is probably bogus. 959 */ 960 if (rt->rt_refcnt == 1 && 961 (rt->rt_flags & (RTF_WASCLONED | RTF_STATIC)) == 962 RTF_WASCLONED) { 963 /* 964 * Prevent another thread from modiying rt_key, 965 * rt_gateway via rt_setgate() after rt_lock is 966 * dropped by marking the route as defunct. 967 */ 968 rt->rt_flags |= RTF_CONDEMNED; 969 RT_UNLOCK(rt); 970 rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, 971 rt_mask(rt), rt->rt_flags, NULL); 972 rtfree(rt); 973 } else { 974 RT_REMREF_LOCKED(rt); 975 RT_UNLOCK(rt); 976 } 977 return (error); 978 } 979 980 /* 981 * Caller releases reference and does RT_UNLOCK(rt). 982 */ 983 *route = rt; 984 return (0); 985} 986 987/* 988 * This is the ARP pre-output routine; care must be taken to ensure that 989 * the "hint" route never gets freed via rtfree(), since the caller may 990 * have stored it inside a struct route with a reference held for that 991 * placeholder. 992 */ 993errno_t 994arp_lookup_ip(ifnet_t ifp, const struct sockaddr_in *net_dest, 995 struct sockaddr_dl *ll_dest, size_t ll_dest_len, route_t hint, 996 mbuf_t packet) 997{ 998 route_t route = NULL; /* output route */ 999 errno_t result = 0; 1000 struct sockaddr_dl *gateway; 1001 struct llinfo_arp *llinfo = NULL; 1002 uint64_t timenow; 1003 int unreachable = 0; 1004 struct if_llreach *lr; 1005 struct ifaddr *rt_ifa; 1006 struct sockaddr *sa; 1007 uint32_t rtflags; 1008 struct sockaddr_dl sdl; 1009 1010 if (net_dest->sin_family != AF_INET) 1011 return (EAFNOSUPPORT); 1012 1013 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) 1014 return (ENETDOWN); 1015 1016 /* 1017 * If we were given a route, verify the route and grab the gateway 1018 */ 1019 if (hint != NULL) { 1020 /* 1021 * Callee holds a reference on the route and returns 1022 * with the route entry locked, upon success. 1023 */ 1024 result = route_to_gwroute((const struct sockaddr *) 1025 net_dest, hint, &route); 1026 if (result != 0) 1027 return (result); 1028 if (route != NULL) 1029 RT_LOCK_ASSERT_HELD(route); 1030 } 1031 1032 if (packet->m_flags & M_BCAST) { 1033 size_t broadcast_len; 1034 bzero(ll_dest, ll_dest_len); 1035 result = ifnet_llbroadcast_copy_bytes(ifp, LLADDR(ll_dest), 1036 ll_dest_len - offsetof(struct sockaddr_dl, sdl_data), 1037 &broadcast_len); 1038 if (result == 0) { 1039 ll_dest->sdl_alen = broadcast_len; 1040 ll_dest->sdl_family = AF_LINK; 1041 ll_dest->sdl_len = sizeof (struct sockaddr_dl); 1042 } 1043 goto release; 1044 } 1045 if (packet->m_flags & M_MCAST) { 1046 if (route != NULL) 1047 RT_UNLOCK(route); 1048 result = dlil_resolve_multi(ifp, 1049 (const struct sockaddr *)net_dest, 1050 (struct sockaddr *)ll_dest, ll_dest_len); 1051 if (route != NULL) 1052 RT_LOCK(route); 1053 goto release; 1054 } 1055 1056 /* 1057 * If we didn't find a route, or the route doesn't have 1058 * link layer information, trigger the creation of the 1059 * route and link layer information. 1060 */ 1061 if (route == NULL || route->rt_llinfo == NULL) { 1062 /* Clean up now while we can */ 1063 if (route != NULL) { 1064 if (route == hint) { 1065 RT_REMREF_LOCKED(route); 1066 RT_UNLOCK(route); 1067 } else { 1068 RT_UNLOCK(route); 1069 rtfree(route); 1070 } 1071 } 1072 /* 1073 * Callee holds a reference on the route and returns 1074 * with the route entry locked, upon success. 1075 */ 1076 result = arp_lookup_route(&net_dest->sin_addr, 1, 0, &route, 1077 ifp->if_index); 1078 if (result == 0) 1079 RT_LOCK_ASSERT_HELD(route); 1080 } 1081 1082 if (result || route == NULL || (llinfo = route->rt_llinfo) == NULL) { 1083 /* In case result is 0 but no route, return an error */ 1084 if (result == 0) 1085 result = EHOSTUNREACH; 1086 1087 if (route != NULL && route->rt_llinfo == NULL) { 1088 char tmp[MAX_IPv4_STR_LEN]; 1089 log(LOG_ERR, "%s: can't allocate llinfo for %s\n", 1090 __func__, inet_ntop(AF_INET, &net_dest->sin_addr, 1091 tmp, sizeof (tmp))); 1092 } 1093 goto release; 1094 } 1095 1096 /* 1097 * Now that we have the right route, is it filled in? 1098 */ 1099 gateway = SDL(route->rt_gateway); 1100 timenow = net_uptime(); 1101 VERIFY(route->rt_expire == 0 || route->rt_rmx.rmx_expire != 0); 1102 VERIFY(route->rt_expire != 0 || route->rt_rmx.rmx_expire == 0); 1103 if ((route->rt_expire == 0 || 1104 route->rt_expire > timenow) && gateway != NULL && 1105 gateway->sdl_family == AF_LINK && gateway->sdl_alen != 0 && 1106 !(unreachable = !arp_llreach_reachable(llinfo))) { 1107 bcopy(gateway, ll_dest, MIN(gateway->sdl_len, ll_dest_len)); 1108 result = 0; 1109 arp_llreach_use(llinfo); /* Mark use timestamp */ 1110 /* 1111 * Start the unicast probe right before the entry expires. 1112 */ 1113 lr = llinfo->la_llreach; 1114 if (lr == NULL) 1115 goto release; 1116 rt_ifa = route->rt_ifa; 1117 /* Become a regular mutex, just in case */ 1118 RT_CONVERT_LOCK(route); 1119 IFLR_LOCK_SPIN(lr); 1120 if (route->rt_expire <= timenow + arp_unicast_lim && 1121 ifp->if_addrlen == IF_LLREACH_MAXLEN && 1122 lr->lr_probes <= arp_unicast_lim) { 1123 lr->lr_probes++; 1124 bzero(&sdl, sizeof (sdl)); 1125 sdl.sdl_alen = ifp->if_addrlen; 1126 bcopy(&lr->lr_key.addr, LLADDR(&sdl), 1127 ifp->if_addrlen); 1128 IFLR_UNLOCK(lr); 1129 IFA_LOCK_SPIN(rt_ifa); 1130 IFA_ADDREF_LOCKED(rt_ifa); 1131 sa = rt_ifa->ifa_addr; 1132 IFA_UNLOCK(rt_ifa); 1133 rtflags = route->rt_flags; 1134 RT_UNLOCK(route); 1135 dlil_send_arp(ifp, ARPOP_REQUEST, NULL, sa, 1136 (const struct sockaddr_dl *)&sdl, 1137 (const struct sockaddr *)net_dest, rtflags); 1138 IFA_REMREF(rt_ifa); 1139 RT_LOCK(route); 1140 } else 1141 IFLR_UNLOCK(lr); 1142 goto release; 1143 } else if (unreachable) { 1144 /* 1145 * Discard existing answer in case we need to probe. 1146 */ 1147 gateway->sdl_alen = 0; 1148 } 1149 1150 if (ifp->if_flags & IFF_NOARP) { 1151 result = ENOTSUP; 1152 goto release; 1153 } 1154 1155 /* 1156 * Route wasn't complete/valid. We need to arp. 1157 */ 1158 if (packet != NULL) { 1159 if (llinfo->la_hold != NULL) { 1160 m_freem(llinfo->la_hold); 1161 arpstat.dropped++; 1162 } 1163 llinfo->la_hold = packet; 1164 } 1165 1166 if (route->rt_expire) { 1167 route->rt_flags &= ~RTF_REJECT; 1168 if (llinfo->la_asked == 0 || route->rt_expire != timenow) { 1169 rt_setexpire(route, timenow); 1170 if (llinfo->la_asked++ < llinfo->la_maxtries) { 1171 struct kev_msg ev_msg; 1172 struct kev_in_arpfailure in_arpfailure; 1173 boolean_t sendkev = FALSE; 1174 1175 rt_ifa = route->rt_ifa; 1176 lr = llinfo->la_llreach; 1177 /* Become a regular mutex, just in case */ 1178 RT_CONVERT_LOCK(route); 1179 /* Update probe count, if applicable */ 1180 if (lr != NULL) { 1181 IFLR_LOCK_SPIN(lr); 1182 lr->lr_probes++; 1183 IFLR_UNLOCK(lr); 1184 } 1185 if (ifp->if_addrlen == IF_LLREACH_MAXLEN && 1186 route->rt_flags & RTF_ROUTER && 1187 llinfo->la_asked > 1) { 1188 sendkev = TRUE; 1189 llinfo->la_flags |= LLINFO_RTRFAIL_EVTSENT; 1190 } 1191 IFA_LOCK_SPIN(rt_ifa); 1192 IFA_ADDREF_LOCKED(rt_ifa); 1193 sa = rt_ifa->ifa_addr; 1194 IFA_UNLOCK(rt_ifa); 1195 arp_llreach_use(llinfo); /* Mark use tstamp */ 1196 rtflags = route->rt_flags; 1197 RT_UNLOCK(route); 1198 dlil_send_arp(ifp, ARPOP_REQUEST, NULL, sa, 1199 NULL, (const struct sockaddr *)net_dest, 1200 rtflags); 1201 IFA_REMREF(rt_ifa); 1202 if (sendkev) { 1203 bzero(&ev_msg, sizeof(ev_msg)); 1204 bzero(&in_arpfailure, 1205 sizeof(in_arpfailure)); 1206 in_arpfailure.link_data.if_family = 1207 ifp->if_family; 1208 in_arpfailure.link_data.if_unit = 1209 ifp->if_unit; 1210 strlcpy(in_arpfailure.link_data.if_name, 1211 ifp->if_name, IFNAMSIZ); 1212 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1213 ev_msg.kev_class = KEV_NETWORK_CLASS; 1214 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 1215 ev_msg.event_code = 1216 KEV_INET_ARPRTRFAILURE; 1217 ev_msg.dv[0].data_ptr = &in_arpfailure; 1218 ev_msg.dv[0].data_length = 1219 sizeof(struct 1220 kev_in_arpfailure); 1221 kev_post_msg(&ev_msg); 1222 } 1223 result = EJUSTRETURN; 1224 RT_LOCK(route); 1225 goto release; 1226 } else { 1227 route->rt_flags |= RTF_REJECT; 1228 rt_setexpire(route, 1229 route->rt_expire + arpt_down); 1230 llinfo->la_asked = 0; 1231 /* 1232 * Clear la_hold; don't free the packet since 1233 * we're not returning EJUSTRETURN; the caller 1234 * will handle the freeing. 1235 */ 1236 llinfo->la_hold = NULL; 1237 result = EHOSTUNREACH; 1238 goto release; 1239 } 1240 } 1241 } 1242 1243 /* The packet is now held inside la_hold (can "packet" be NULL?) */ 1244 result = EJUSTRETURN; 1245 1246release: 1247 if (result == EHOSTUNREACH) 1248 arpstat.dropped++; 1249 1250 if (route != NULL) { 1251 if (route == hint) { 1252 RT_REMREF_LOCKED(route); 1253 RT_UNLOCK(route); 1254 } else { 1255 RT_UNLOCK(route); 1256 rtfree(route); 1257 } 1258 } 1259 return (result); 1260} 1261 1262errno_t 1263arp_ip_handle_input(ifnet_t ifp, u_short arpop, 1264 const struct sockaddr_dl *sender_hw, const struct sockaddr_in *sender_ip, 1265 const struct sockaddr_in *target_ip) 1266{ 1267 char ipv4str[MAX_IPv4_STR_LEN]; 1268 struct sockaddr_dl proxied; 1269 struct sockaddr_dl *gateway, *target_hw = NULL; 1270 struct ifaddr *ifa; 1271 struct in_ifaddr *ia; 1272 struct in_ifaddr *best_ia = NULL; 1273 struct sockaddr_in best_ia_sin; 1274 route_t route = NULL; 1275 char buf[3 * MAX_HW_LEN]; /* enough for MAX_HW_LEN byte hw address */ 1276 struct llinfo_arp *llinfo; 1277 errno_t error; 1278 int created_announcement = 0; 1279 int bridged = 0, is_bridge = 0; 1280 1281 arpstat.received++; 1282 1283 /* Do not respond to requests for 0.0.0.0 */ 1284 if (target_ip->sin_addr.s_addr == INADDR_ANY && arpop == ARPOP_REQUEST) 1285 goto done; 1286 1287 if (ifp->if_bridge) 1288 bridged = 1; 1289 if (ifp->if_type == IFT_BRIDGE) 1290 is_bridge = 1; 1291 1292 if (arpop == ARPOP_REPLY) 1293 arpstat.rxreplies++; 1294 1295 /* 1296 * Determine if this ARP is for us 1297 * For a bridge, we want to check the address irrespective 1298 * of the receive interface. 1299 */ 1300 lck_rw_lock_shared(in_ifaddr_rwlock); 1301 TAILQ_FOREACH(ia, INADDR_HASH(target_ip->sin_addr.s_addr), ia_hash) { 1302 IFA_LOCK_SPIN(&ia->ia_ifa); 1303 if (((bridged && ia->ia_ifp->if_bridge != NULL) || 1304 (ia->ia_ifp == ifp)) && 1305 ia->ia_addr.sin_addr.s_addr == target_ip->sin_addr.s_addr) { 1306 best_ia = ia; 1307 best_ia_sin = best_ia->ia_addr; 1308 IFA_ADDREF_LOCKED(&ia->ia_ifa); 1309 IFA_UNLOCK(&ia->ia_ifa); 1310 lck_rw_done(in_ifaddr_rwlock); 1311 goto match; 1312 } 1313 IFA_UNLOCK(&ia->ia_ifa); 1314 } 1315 1316 TAILQ_FOREACH(ia, INADDR_HASH(sender_ip->sin_addr.s_addr), ia_hash) { 1317 IFA_LOCK_SPIN(&ia->ia_ifa); 1318 if (((bridged && ia->ia_ifp->if_bridge != NULL) || 1319 (ia->ia_ifp == ifp)) && 1320 ia->ia_addr.sin_addr.s_addr == sender_ip->sin_addr.s_addr) { 1321 best_ia = ia; 1322 best_ia_sin = best_ia->ia_addr; 1323 IFA_ADDREF_LOCKED(&ia->ia_ifa); 1324 IFA_UNLOCK(&ia->ia_ifa); 1325 lck_rw_done(in_ifaddr_rwlock); 1326 goto match; 1327 } 1328 IFA_UNLOCK(&ia->ia_ifa); 1329 } 1330 1331#define BDG_MEMBER_MATCHES_ARP(addr, ifp, ia) \ 1332 (ia->ia_ifp->if_bridge == ifp->if_softc && \ 1333 bcmp(IF_LLADDR(ia->ia_ifp), IF_LLADDR(ifp), ifp->if_addrlen) == 0 && \ 1334 addr == ia->ia_addr.sin_addr.s_addr) 1335 /* 1336 * Check the case when bridge shares its MAC address with 1337 * some of its children, so packets are claimed by bridge 1338 * itself (bridge_input() does it first), but they are really 1339 * meant to be destined to the bridge member. 1340 */ 1341 if (is_bridge) { 1342 TAILQ_FOREACH(ia, INADDR_HASH(target_ip->sin_addr.s_addr), 1343 ia_hash) { 1344 IFA_LOCK_SPIN(&ia->ia_ifa); 1345 if (BDG_MEMBER_MATCHES_ARP(target_ip->sin_addr.s_addr, 1346 ifp, ia)) { 1347 ifp = ia->ia_ifp; 1348 best_ia = ia; 1349 best_ia_sin = best_ia->ia_addr; 1350 IFA_ADDREF_LOCKED(&ia->ia_ifa); 1351 IFA_UNLOCK(&ia->ia_ifa); 1352 lck_rw_done(in_ifaddr_rwlock); 1353 goto match; 1354 } 1355 IFA_UNLOCK(&ia->ia_ifa); 1356 } 1357 } 1358#undef BDG_MEMBER_MATCHES_ARP 1359 lck_rw_done(in_ifaddr_rwlock); 1360 1361 /* 1362 * No match, use the first inet address on the receive interface 1363 * as a dummy address for the rest of the function; we may be 1364 * proxying for another address. 1365 */ 1366 ifnet_lock_shared(ifp); 1367 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1368 IFA_LOCK_SPIN(ifa); 1369 if (ifa->ifa_addr->sa_family != AF_INET) { 1370 IFA_UNLOCK(ifa); 1371 continue; 1372 } 1373 best_ia = (struct in_ifaddr *)ifa; 1374 best_ia_sin = best_ia->ia_addr; 1375 IFA_ADDREF_LOCKED(ifa); 1376 IFA_UNLOCK(ifa); 1377 ifnet_lock_done(ifp); 1378 goto match; 1379 } 1380 ifnet_lock_done(ifp); 1381 1382 /* 1383 * If we're not a bridge member, or if we are but there's no 1384 * IPv4 address to use for the interface, drop the packet. 1385 */ 1386 if (!bridged || best_ia == NULL) 1387 goto done; 1388 1389match: 1390 /* If the packet is from this interface, ignore the packet */ 1391 if (bcmp(CONST_LLADDR(sender_hw), IF_LLADDR(ifp), 1392 sender_hw->sdl_alen) == 0) 1393 goto done; 1394 1395 /* Check for a conflict */ 1396 if (!bridged && 1397 sender_ip->sin_addr.s_addr == best_ia_sin.sin_addr.s_addr) { 1398 struct kev_msg ev_msg; 1399 struct kev_in_collision *in_collision; 1400 u_char storage[sizeof (struct kev_in_collision) + MAX_HW_LEN]; 1401 1402 bzero(&ev_msg, sizeof (struct kev_msg)); 1403 bzero(storage, (sizeof (struct kev_in_collision) + MAX_HW_LEN)); 1404 in_collision = (struct kev_in_collision *)(void *)storage; 1405 log(LOG_ERR, "%s duplicate IP address %s sent from " 1406 "address %s\n", if_name(ifp), 1407 inet_ntop(AF_INET, &sender_ip->sin_addr, ipv4str, 1408 sizeof (ipv4str)), sdl_addr_to_hex(sender_hw, buf, 1409 sizeof (buf))); 1410 1411 /* Send a kernel event so anyone can learn of the conflict */ 1412 in_collision->link_data.if_family = ifp->if_family; 1413 in_collision->link_data.if_unit = ifp->if_unit; 1414 strlcpy(&in_collision->link_data.if_name[0], 1415 ifp->if_name, IFNAMSIZ); 1416 in_collision->ia_ipaddr = sender_ip->sin_addr; 1417 in_collision->hw_len = (sender_hw->sdl_alen < MAX_HW_LEN) ? 1418 sender_hw->sdl_alen : MAX_HW_LEN; 1419 bcopy(CONST_LLADDR(sender_hw), (caddr_t)in_collision->hw_addr, 1420 in_collision->hw_len); 1421 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1422 ev_msg.kev_class = KEV_NETWORK_CLASS; 1423 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 1424 ev_msg.event_code = KEV_INET_ARPCOLLISION; 1425 ev_msg.dv[0].data_ptr = in_collision; 1426 ev_msg.dv[0].data_length = 1427 sizeof (struct kev_in_collision) + in_collision->hw_len; 1428 ev_msg.dv[1].data_length = 0; 1429 kev_post_msg(&ev_msg); 1430 arpstat.dupips++; 1431 goto respond; 1432 } 1433 1434 /* 1435 * Look up the routing entry. If it doesn't exist and we are the 1436 * target, and the sender isn't 0.0.0.0, go ahead and create one. 1437 * Callee holds a reference on the route and returns with the route 1438 * entry locked, upon success. 1439 */ 1440 error = arp_lookup_route(&sender_ip->sin_addr, 1441 (target_ip->sin_addr.s_addr == best_ia_sin.sin_addr.s_addr && 1442 sender_ip->sin_addr.s_addr != 0), 0, &route, ifp->if_index); 1443 1444 if (error == 0) 1445 RT_LOCK_ASSERT_HELD(route); 1446 1447 if (error || route == NULL || route->rt_gateway == NULL) { 1448 if (arpop != ARPOP_REQUEST) 1449 goto respond; 1450 1451 if (arp_sendllconflict && send_conflicting_probes != 0 && 1452 (ifp->if_eflags & IFEF_ARPLL) && 1453 IN_LINKLOCAL(ntohl(target_ip->sin_addr.s_addr)) && 1454 sender_ip->sin_addr.s_addr == INADDR_ANY) { 1455 /* 1456 * Verify this ARP probe doesn't conflict with 1457 * an IPv4LL we know of on another interface. 1458 */ 1459 if (route != NULL) { 1460 RT_REMREF_LOCKED(route); 1461 RT_UNLOCK(route); 1462 route = NULL; 1463 } 1464 /* 1465 * Callee holds a reference on the route and returns 1466 * with the route entry locked, upon success. 1467 */ 1468 error = arp_lookup_route(&target_ip->sin_addr, 0, 0, 1469 &route, ifp->if_index); 1470 1471 if (error != 0 || route == NULL || 1472 route->rt_gateway == NULL) 1473 goto respond; 1474 1475 RT_LOCK_ASSERT_HELD(route); 1476 1477 gateway = SDL(route->rt_gateway); 1478 if (route->rt_ifp != ifp && gateway->sdl_alen != 0 && 1479 (gateway->sdl_alen != sender_hw->sdl_alen || 1480 bcmp(CONST_LLADDR(gateway), CONST_LLADDR(sender_hw), 1481 gateway->sdl_alen) != 0)) { 1482 /* 1483 * A node is probing for an IPv4LL we know 1484 * exists on a different interface. We respond 1485 * with a conflicting probe to force the new 1486 * device to pick a different IPv4LL address. 1487 */ 1488 if (arp_verbose || log_arp_warnings) { 1489 log(LOG_INFO, "arp: %s on %s sent " 1490 "probe for %s, already on %s\n", 1491 sdl_addr_to_hex(sender_hw, buf, 1492 sizeof (buf)), if_name(ifp), 1493 inet_ntop(AF_INET, 1494 &target_ip->sin_addr, ipv4str, 1495 sizeof (ipv4str)), 1496 if_name(route->rt_ifp)); 1497 log(LOG_INFO, "arp: sending " 1498 "conflicting probe to %s on %s\n", 1499 sdl_addr_to_hex(sender_hw, buf, 1500 sizeof (buf)), if_name(ifp)); 1501 } 1502 /* Mark use timestamp */ 1503 if (route->rt_llinfo != NULL) 1504 arp_llreach_use(route->rt_llinfo); 1505 /* We're done with the route */ 1506 RT_REMREF_LOCKED(route); 1507 RT_UNLOCK(route); 1508 route = NULL; 1509 /* 1510 * Send a conservative unicast "ARP probe". 1511 * This should force the other device to pick 1512 * a new number. This will not force the 1513 * device to pick a new number if the device 1514 * has already assigned that number. This will 1515 * not imply to the device that we own that 1516 * address. The link address is always 1517 * present; it's never freed. 1518 */ 1519 ifnet_lock_shared(ifp); 1520 ifa = ifp->if_lladdr; 1521 IFA_ADDREF(ifa); 1522 ifnet_lock_done(ifp); 1523 dlil_send_arp_internal(ifp, ARPOP_REQUEST, 1524 SDL(ifa->ifa_addr), 1525 (const struct sockaddr *)sender_ip, 1526 sender_hw, 1527 (const struct sockaddr *)target_ip); 1528 IFA_REMREF(ifa); 1529 ifa = NULL; 1530 arpstat.txconflicts++; 1531 } 1532 goto respond; 1533 } else if (keep_announcements != 0 && 1534 target_ip->sin_addr.s_addr == sender_ip->sin_addr.s_addr) { 1535 /* 1536 * Don't create entry if link-local address and 1537 * link-local is disabled 1538 */ 1539 if (!IN_LINKLOCAL(ntohl(sender_ip->sin_addr.s_addr)) || 1540 (ifp->if_eflags & IFEF_ARPLL)) { 1541 if (route != NULL) { 1542 RT_REMREF_LOCKED(route); 1543 RT_UNLOCK(route); 1544 route = NULL; 1545 } 1546 /* 1547 * Callee holds a reference on the route and 1548 * returns with the route entry locked, upon 1549 * success. 1550 */ 1551 error = arp_lookup_route(&sender_ip->sin_addr, 1552 1, 0, &route, ifp->if_index); 1553 1554 if (error == 0) 1555 RT_LOCK_ASSERT_HELD(route); 1556 1557 if (error == 0 && route != NULL && 1558 route->rt_gateway != NULL) 1559 created_announcement = 1; 1560 } 1561 if (created_announcement == 0) 1562 goto respond; 1563 } else { 1564 goto respond; 1565 } 1566 } 1567 1568 RT_LOCK_ASSERT_HELD(route); 1569 VERIFY(route->rt_expire == 0 || route->rt_rmx.rmx_expire != 0); 1570 VERIFY(route->rt_expire != 0 || route->rt_rmx.rmx_expire == 0); 1571 1572 gateway = SDL(route->rt_gateway); 1573 if (!bridged && route->rt_ifp != ifp) { 1574 if (!IN_LINKLOCAL(ntohl(sender_ip->sin_addr.s_addr)) || 1575 !(ifp->if_eflags & IFEF_ARPLL)) { 1576 if (arp_verbose || log_arp_warnings) 1577 log(LOG_ERR, "arp: %s is on %s but got " 1578 "reply from %s on %s\n", 1579 inet_ntop(AF_INET, &sender_ip->sin_addr, 1580 ipv4str, sizeof (ipv4str)), 1581 if_name(route->rt_ifp), 1582 sdl_addr_to_hex(sender_hw, buf, 1583 sizeof (buf)), if_name(ifp)); 1584 goto respond; 1585 } else { 1586 /* Don't change a permanent address */ 1587 if (route->rt_expire == 0) 1588 goto respond; 1589 1590 /* 1591 * We're about to check and/or change the route's ifp 1592 * and ifa, so do the lock dance: drop rt_lock, hold 1593 * rnh_lock and re-hold rt_lock to avoid violating the 1594 * lock ordering. We have an extra reference on the 1595 * route, so it won't go away while we do this. 1596 */ 1597 RT_UNLOCK(route); 1598 lck_mtx_lock(rnh_lock); 1599 RT_LOCK(route); 1600 /* 1601 * Don't change the cloned route away from the 1602 * parent's interface if the address did resolve 1603 * or if the route is defunct. rt_ifp on both 1604 * the parent and the clone can now be freely 1605 * accessed now that we have acquired rnh_lock. 1606 */ 1607 gateway = SDL(route->rt_gateway); 1608 if ((gateway->sdl_alen != 0 && 1609 route->rt_parent != NULL && 1610 route->rt_parent->rt_ifp == route->rt_ifp) || 1611 (route->rt_flags & RTF_CONDEMNED)) { 1612 RT_REMREF_LOCKED(route); 1613 RT_UNLOCK(route); 1614 route = NULL; 1615 lck_mtx_unlock(rnh_lock); 1616 goto respond; 1617 } 1618 if (route->rt_ifp != ifp) { 1619 /* 1620 * Purge any link-layer info caching. 1621 */ 1622 if (route->rt_llinfo_purge != NULL) 1623 route->rt_llinfo_purge(route); 1624 1625 /* Adjust route ref count for the interfaces */ 1626 if (route->rt_if_ref_fn != NULL) { 1627 route->rt_if_ref_fn(ifp, 1); 1628 route->rt_if_ref_fn(route->rt_ifp, -1); 1629 } 1630 } 1631 /* Change the interface when the existing route is on */ 1632 route->rt_ifp = ifp; 1633 /* 1634 * If rmx_mtu is not locked, update it 1635 * to the MTU used by the new interface. 1636 */ 1637 if (!(route->rt_rmx.rmx_locks & RTV_MTU)) 1638 route->rt_rmx.rmx_mtu = route->rt_ifp->if_mtu; 1639 1640 rtsetifa(route, &best_ia->ia_ifa); 1641 gateway->sdl_index = ifp->if_index; 1642 RT_UNLOCK(route); 1643 lck_mtx_unlock(rnh_lock); 1644 RT_LOCK(route); 1645 /* Don't bother if the route is down */ 1646 if (!(route->rt_flags & RTF_UP)) 1647 goto respond; 1648 /* Refresh gateway pointer */ 1649 gateway = SDL(route->rt_gateway); 1650 } 1651 RT_LOCK_ASSERT_HELD(route); 1652 } 1653 1654 if (gateway->sdl_alen != 0 && bcmp(LLADDR(gateway), 1655 CONST_LLADDR(sender_hw), gateway->sdl_alen) != 0) { 1656 if (route->rt_expire != 0 && 1657 (arp_verbose || log_arp_warnings)) { 1658 char buf2[3 * MAX_HW_LEN]; 1659 log(LOG_INFO, "arp: %s moved from %s to %s on %s\n", 1660 inet_ntop(AF_INET, &sender_ip->sin_addr, ipv4str, 1661 sizeof (ipv4str)), 1662 sdl_addr_to_hex(gateway, buf, sizeof (buf)), 1663 sdl_addr_to_hex(sender_hw, buf2, sizeof (buf2)), 1664 if_name(ifp)); 1665 } else if (route->rt_expire == 0) { 1666 if (arp_verbose || log_arp_warnings) { 1667 log(LOG_ERR, "arp: %s attempts to modify " 1668 "permanent entry for %s on %s\n", 1669 sdl_addr_to_hex(sender_hw, buf, 1670 sizeof (buf)), 1671 inet_ntop(AF_INET, &sender_ip->sin_addr, 1672 ipv4str, sizeof (ipv4str)), 1673 if_name(ifp)); 1674 } 1675 goto respond; 1676 } 1677 } 1678 1679 /* Copy the sender hardware address in to the route's gateway address */ 1680 gateway->sdl_alen = sender_hw->sdl_alen; 1681 bcopy(CONST_LLADDR(sender_hw), LLADDR(gateway), gateway->sdl_alen); 1682 1683 /* Update the expire time for the route and clear the reject flag */ 1684 if (route->rt_expire != 0) 1685 rt_setexpire(route, net_uptime() + arpt_keep); 1686 route->rt_flags &= ~RTF_REJECT; 1687 1688 /* cache the gateway (sender HW) address */ 1689 arp_llreach_alloc(route, ifp, LLADDR(gateway), gateway->sdl_alen, 1690 (arpop == ARPOP_REPLY)); 1691 1692 llinfo = route->rt_llinfo; 1693 /* send a notification that the route is back up */ 1694 if (ifp->if_addrlen == IF_LLREACH_MAXLEN && 1695 route->rt_flags & RTF_ROUTER && 1696 llinfo->la_flags & LLINFO_RTRFAIL_EVTSENT) { 1697 struct kev_msg ev_msg; 1698 struct kev_in_arpfailure in_arpalive; 1699 1700 llinfo->la_flags &= ~LLINFO_RTRFAIL_EVTSENT; 1701 RT_UNLOCK(route); 1702 bzero(&ev_msg, sizeof(ev_msg)); 1703 bzero(&in_arpalive, sizeof(in_arpalive)); 1704 in_arpalive.link_data.if_family = ifp->if_family; 1705 in_arpalive.link_data.if_unit = ifp->if_unit; 1706 strlcpy(in_arpalive.link_data.if_name, ifp->if_name, IFNAMSIZ); 1707 ev_msg.vendor_code = KEV_VENDOR_APPLE; 1708 ev_msg.kev_class = KEV_NETWORK_CLASS; 1709 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 1710 ev_msg.event_code = KEV_INET_ARPRTRALIVE; 1711 ev_msg.dv[0].data_ptr = &in_arpalive; 1712 ev_msg.dv[0].data_length = sizeof(struct kev_in_arpalive); 1713 kev_post_msg(&ev_msg); 1714 RT_LOCK(route); 1715 } 1716 /* update the llinfo, send a queued packet if there is one */ 1717 llinfo->la_asked = 0; 1718 if (llinfo->la_hold) { 1719 struct mbuf *m0 = llinfo->la_hold; 1720 llinfo->la_hold = NULL; 1721 RT_UNLOCK(route); 1722 dlil_output(ifp, PF_INET, m0, (caddr_t)route, 1723 rt_key(route), 0, NULL); 1724 RT_REMREF(route); 1725 route = NULL; 1726 } 1727 1728 1729respond: 1730 if (route != NULL) { 1731 /* Mark use timestamp if we're going to send a reply */ 1732 if (arpop == ARPOP_REQUEST && route->rt_llinfo != NULL) 1733 arp_llreach_use(route->rt_llinfo); 1734 RT_REMREF_LOCKED(route); 1735 RT_UNLOCK(route); 1736 route = NULL; 1737 } 1738 1739 if (arpop != ARPOP_REQUEST) 1740 goto done; 1741 1742 arpstat.rxrequests++; 1743 1744 /* If we are not the target, check if we should proxy */ 1745 if (target_ip->sin_addr.s_addr != best_ia_sin.sin_addr.s_addr) { 1746 /* 1747 * Find a proxy route; callee holds a reference on the 1748 * route and returns with the route entry locked, upon 1749 * success. 1750 */ 1751 error = arp_lookup_route(&target_ip->sin_addr, 0, SIN_PROXY, 1752 &route, ifp->if_index); 1753 1754 if (error == 0) { 1755 RT_LOCK_ASSERT_HELD(route); 1756 /* 1757 * Return proxied ARP replies only on the interface 1758 * or bridge cluster where this network resides. 1759 * Otherwise we may conflict with the host we are 1760 * proxying for. 1761 */ 1762 if (route->rt_ifp != ifp && 1763 (route->rt_ifp->if_bridge != ifp->if_bridge || 1764 ifp->if_bridge == NULL)) { 1765 RT_REMREF_LOCKED(route); 1766 RT_UNLOCK(route); 1767 goto done; 1768 } 1769 proxied = *SDL(route->rt_gateway); 1770 target_hw = &proxied; 1771 } else { 1772 /* 1773 * We don't have a route entry indicating we should 1774 * use proxy. If we aren't supposed to proxy all, 1775 * we are done. 1776 */ 1777 if (!arp_proxyall) 1778 goto done; 1779 1780 /* 1781 * See if we have a route to the target ip before 1782 * we proxy it. 1783 */ 1784 route = rtalloc1_scoped((struct sockaddr *) 1785 (size_t)target_ip, 0, 0, ifp->if_index); 1786 if (!route) 1787 goto done; 1788 1789 /* 1790 * Don't proxy for hosts already on the same interface. 1791 */ 1792 RT_LOCK(route); 1793 if (route->rt_ifp == ifp) { 1794 RT_UNLOCK(route); 1795 rtfree(route); 1796 goto done; 1797 } 1798 } 1799 /* Mark use timestamp */ 1800 if (route->rt_llinfo != NULL) 1801 arp_llreach_use(route->rt_llinfo); 1802 RT_REMREF_LOCKED(route); 1803 RT_UNLOCK(route); 1804 } 1805 1806 dlil_send_arp(ifp, ARPOP_REPLY, 1807 target_hw, (const struct sockaddr *)target_ip, 1808 sender_hw, (const struct sockaddr *)sender_ip, 0); 1809 1810done: 1811 if (best_ia != NULL) 1812 IFA_REMREF(&best_ia->ia_ifa); 1813 return (0); 1814} 1815 1816void 1817arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa) 1818{ 1819 struct sockaddr *sa; 1820 1821 IFA_LOCK(ifa); 1822 ifa->ifa_rtrequest = arp_rtrequest; 1823 ifa->ifa_flags |= RTF_CLONING; 1824 sa = ifa->ifa_addr; 1825 IFA_UNLOCK(ifa); 1826 dlil_send_arp(ifp, ARPOP_REQUEST, NULL, sa, NULL, sa, 0); 1827} 1828 1829static int 1830arp_getstat SYSCTL_HANDLER_ARGS 1831{ 1832#pragma unused(oidp, arg1, arg2) 1833 if (req->oldptr == USER_ADDR_NULL) 1834 req->oldlen = (size_t)sizeof (struct arpstat); 1835 1836 return (SYSCTL_OUT(req, &arpstat, MIN(sizeof (arpstat), req->oldlen))); 1837} 1838