]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet/in_arp.c
xnu-4570.20.62.tar.gz
[apple/xnu.git] / bsd / netinet / in_arp.c
CommitLineData
91447636 1/*
5ba3f43e 2 * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
5d5c5d0d 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
39236c6e 5 *
2d21ac55
A
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.
39236c6e 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
39236c6e 17 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
39236c6e 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
91447636
A
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>
6d2010ae
A
73#include <sys/mcache.h>
74#include <sys/protosw.h>
91447636
A
75#include <string.h>
76#include <net/if_arp.h>
77#include <net/if_dl.h>
78#include <net/dlil.h>
b7266188 79#include <net/if_types.h>
6d2010ae 80#include <net/if_llreach.h>
91447636 81#include <net/route.h>
5ba3f43e 82#include <net/nwk_wq.h>
39236c6e 83
91447636
A
84#include <netinet/if_ether.h>
85#include <netinet/in_var.h>
b0d623f7 86#include <kern/zalloc.h>
91447636 87
39037602
A
88#include <kern/thread.h>
89#include <kern/sched_prim.h>
90
39236c6e 91#define CONST_LLADDR(s) ((const u_char*)((s)->sdl_data + (s)->sdl_nlen))
91447636
A
92
93static const size_t MAX_HW_LEN = 10;
94
b0d623f7
A
95/*
96 * Synchronization notes:
97 *
98 * The global list of ARP entries are stored in llinfo_arp; an entry
99 * gets inserted into the list when the route is created and gets
100 * removed from the list when it is deleted; this is done as part
101 * of RTM_ADD/RTM_RESOLVE/RTM_DELETE in arp_rtrequest().
102 *
103 * Because rnh_lock and rt_lock for the entry are held during those
104 * operations, the same locks (and thus lock ordering) must be used
105 * elsewhere to access the relevant data structure fields:
106 *
107 * la_le.{le_next,le_prev}, la_rt
108 *
109 * - Routing lock (rnh_lock)
110 *
39037602 111 * la_holdq, la_asked, la_llreach, la_lastused, la_flags
b0d623f7
A
112 *
113 * - Routing entry lock (rt_lock)
114 *
115 * Due to the dependency on rt_lock, llinfo_arp has the same lifetime
116 * as the route entry itself. When a route is deleted (RTM_DELETE),
117 * it is simply removed from the global list but the memory is not
118 * freed until the route itself is freed.
119 */
39236c6e
A
120struct llinfo_arp {
121 /*
122 * The following are protected by rnh_lock
123 */
124 LIST_ENTRY(llinfo_arp) la_le;
5ba3f43e 125 struct rtentry *la_rt;
39236c6e
A
126 /*
127 * The following are protected by rt_lock
128 */
5ba3f43e
A
129 class_queue_t la_holdq; /* packets awaiting resolution */
130 struct if_llreach *la_llreach; /* link-layer reachability record */
131 u_int64_t la_lastused; /* last used timestamp */
132 u_int32_t la_asked; /* # of requests sent */
133 u_int32_t la_maxtries; /* retry limit */
134 u_int64_t la_probeexp; /* probe deadline timestamp */
135 u_int32_t la_prbreq_cnt; /* probe request count */
39037602 136 u_int32_t la_flags;
5ba3f43e
A
137#define LLINFO_RTRFAIL_EVTSENT 0x1 /* sent an ARP event */
138#define LLINFO_PROBING 0x2 /* waiting for an ARP reply */
39236c6e 139};
5ba3f43e 140
91447636
A
141static LIST_HEAD(, llinfo_arp) llinfo_arp;
142
39037602 143static thread_call_t arp_timeout_tcall;
39236c6e 144static int arp_timeout_run; /* arp_timeout is scheduled to run */
39037602 145static void arp_timeout(thread_call_param_t arg0, thread_call_param_t arg1);
39236c6e
A
146static void arp_sched_timeout(struct timeval *);
147
39037602
A
148static thread_call_t arp_probe_tcall;
149static int arp_probe_run; /* arp_probe is scheduled to run */
150static void arp_probe(thread_call_param_t arg0, thread_call_param_t arg1);
151static void arp_sched_probe(struct timeval *);
152
39236c6e
A
153static void arptfree(struct llinfo_arp *, void *);
154static errno_t arp_lookup_route(const struct in_addr *, int,
155 int, route_t *, unsigned int);
156static int arp_getstat SYSCTL_HANDLER_ARGS;
157
158static struct llinfo_arp *arp_llinfo_alloc(int);
159static void arp_llinfo_free(void *);
39037602 160static uint32_t arp_llinfo_flushq(struct llinfo_arp *);
39236c6e
A
161static void arp_llinfo_purge(struct rtentry *);
162static void arp_llinfo_get_ri(struct rtentry *, struct rt_reach_info *);
163static void arp_llinfo_get_iflri(struct rtentry *, struct ifnet_llreach_info *);
3e170ce0 164static void arp_llinfo_refresh(struct rtentry *);
39236c6e
A
165
166static __inline void arp_llreach_use(struct llinfo_arp *);
167static __inline int arp_llreach_reachable(struct llinfo_arp *);
168static void arp_llreach_alloc(struct rtentry *, struct ifnet *, void *,
5ba3f43e 169 unsigned int, boolean_t, uint32_t *);
39236c6e
A
170
171extern int tvtohz(struct timeval *);
172
173static int arpinit_done;
174
175SYSCTL_DECL(_net_link_ether);
176SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW|CTLFLAG_LOCKED, 0, "");
177
39236c6e
A
178static int arpt_prune = (5*60*1); /* walk list every 5 minutes */
179SYSCTL_INT(_net_link_ether_inet, OID_AUTO, prune_intvl,
180 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_prune, 0, "");
181
39037602
A
182#define ARP_PROBE_TIME 7 /* seconds */
183static u_int32_t arpt_probe = ARP_PROBE_TIME;
184SYSCTL_UINT(_net_link_ether_inet, OID_AUTO, probe_intvl,
185 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_probe, 0, "");
186
39236c6e
A
187static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
188SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_age,
189 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_keep, 0, "");
190
191static int arpt_down = 20; /* once declared down, don't send for 20 sec */
192SYSCTL_INT(_net_link_ether_inet, OID_AUTO, host_down_time,
193 CTLFLAG_RW | CTLFLAG_LOCKED, &arpt_down, 0, "");
194
39037602 195static int arp_llreach_base = 120; /* seconds */
39236c6e 196SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_llreach_base,
39037602 197 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_llreach_base, 0,
39236c6e
A
198 "default ARP link-layer reachability max lifetime (in seconds)");
199
39037602 200#define ARP_UNICAST_LIMIT 3 /* # of probes until ARP refresh broadcast */
39236c6e
A
201static u_int32_t arp_unicast_lim = ARP_UNICAST_LIMIT;
202SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_unicast_lim,
203 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_unicast_lim, ARP_UNICAST_LIMIT,
204 "number of unicast ARP refresh probes before using broadcast");
91447636 205
6d2010ae 206static u_int32_t arp_maxtries = 5;
39236c6e
A
207SYSCTL_INT(_net_link_ether_inet, OID_AUTO, maxtries,
208 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_maxtries, 0, "");
91447636 209
39037602
A
210static u_int32_t arp_maxhold = 16;
211SYSCTL_UINT(_net_link_ether_inet, OID_AUTO, maxhold,
212 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_maxhold, 0, "");
213
39236c6e
A
214static int useloopback = 1; /* use loopback interface for local traffic */
215SYSCTL_INT(_net_link_ether_inet, OID_AUTO, useloopback,
216 CTLFLAG_RW | CTLFLAG_LOCKED, &useloopback, 0, "");
217
218static int arp_proxyall = 0;
219SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall,
220 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_proxyall, 0, "");
221
222static int arp_sendllconflict = 0;
223SYSCTL_INT(_net_link_ether_inet, OID_AUTO, sendllconflict,
224 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_sendllconflict, 0, "");
91447636 225
39236c6e 226static int log_arp_warnings = 0; /* Thread safe: no accumulated state */
6d2010ae
A
227SYSCTL_INT(_net_link_ether_inet, OID_AUTO, log_arp_warnings,
228 CTLFLAG_RW | CTLFLAG_LOCKED,
91447636
A
229 &log_arp_warnings, 0,
230 "log arp warning messages");
231
6d2010ae
A
232static int keep_announcements = 1; /* Thread safe: no aging of state */
233SYSCTL_INT(_net_link_ether_inet, OID_AUTO, keep_announcements,
234 CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
235 &keep_announcements, 0,
236 "keep arp announcements");
237
6d2010ae
A
238static int send_conflicting_probes = 1; /* Thread safe: no accumulated state */
239SYSCTL_INT(_net_link_ether_inet, OID_AUTO, send_conflicting_probes,
240 CTLFLAG_RW | CTLFLAG_LOCKED,
2d21ac55
A
241 &send_conflicting_probes, 0,
242 "send conflicting link-local arp probes");
243
39236c6e
A
244static int arp_verbose;
245SYSCTL_INT(_net_link_ether_inet, OID_AUTO, verbose,
246 CTLFLAG_RW | CTLFLAG_LOCKED, &arp_verbose, 0, "");
6d2010ae 247
39037602
A
248/*
249 * Generally protected by rnh_lock; use atomic operations on fields
250 * that are also modified outside of that lock (if needed).
251 */
252struct arpstat arpstat __attribute__((aligned(sizeof (uint64_t))));
fe8ab488
A
253SYSCTL_PROC(_net_link_ether_inet, OID_AUTO, stats,
254 CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
39236c6e
A
255 0, 0, arp_getstat, "S,arpstat",
256 "ARP statistics (struct arpstat, net/if_arp.h)");
b0d623f7 257
b0d623f7
A
258static struct zone *llinfo_arp_zone;
259#define LLINFO_ARP_ZONE_MAX 256 /* maximum elements in zone */
260#define LLINFO_ARP_ZONE_NAME "llinfo_arp" /* name for zone */
261
262void
263arp_init(void)
264{
39236c6e 265 VERIFY(!arpinit_done);
b0d623f7
A
266
267 LIST_INIT(&llinfo_arp);
268
269 llinfo_arp_zone = zinit(sizeof (struct llinfo_arp),
270 LLINFO_ARP_ZONE_MAX * sizeof (struct llinfo_arp), 0,
271 LLINFO_ARP_ZONE_NAME);
272 if (llinfo_arp_zone == NULL)
273 panic("%s: failed allocating llinfo_arp_zone", __func__);
274
275 zone_change(llinfo_arp_zone, Z_EXPAND, TRUE);
6d2010ae 276 zone_change(llinfo_arp_zone, Z_CALLERACCT, FALSE);
b0d623f7
A
277
278 arpinit_done = 1;
b0d623f7
A
279}
280
281static struct llinfo_arp *
39236c6e 282arp_llinfo_alloc(int how)
b0d623f7 283{
39236c6e
A
284 struct llinfo_arp *la;
285
286 la = (how == M_WAITOK) ? zalloc(llinfo_arp_zone) :
287 zalloc_noblock(llinfo_arp_zone);
39037602 288 if (la != NULL) {
39236c6e 289 bzero(la, sizeof (*la));
39037602
A
290 /*
291 * The type of queue (Q_DROPHEAD) here is just a hint;
292 * the actual logic that works on this queue performs
293 * a head drop, details in arp_llinfo_addq().
294 */
295 _qinit(&la->la_holdq, Q_DROPHEAD, (arp_maxhold == 0) ?
5ba3f43e 296 (uint32_t)-1 : arp_maxhold, QP_MBUF);
39037602 297 }
39236c6e
A
298
299 return (la);
b0d623f7
A
300}
301
302static void
303arp_llinfo_free(void *arg)
304{
305 struct llinfo_arp *la = arg;
306
307 if (la->la_le.le_next != NULL || la->la_le.le_prev != NULL) {
308 panic("%s: trying to free %p when it is in use", __func__, la);
309 /* NOTREACHED */
310 }
311
39037602
A
312 /* Free any held packets */
313 (void) arp_llinfo_flushq(la);
b0d623f7 314
6d2010ae
A
315 /* Purge any link-layer info caching */
316 VERIFY(la->la_rt->rt_llinfo == la);
317 if (la->la_rt->rt_llinfo_purge != NULL)
318 la->la_rt->rt_llinfo_purge(la->la_rt);
319
b0d623f7
A
320 zfree(llinfo_arp_zone, la);
321}
322
39037602
A
323static void
324arp_llinfo_addq(struct llinfo_arp *la, struct mbuf *m)
325{
326 if (qlen(&la->la_holdq) >= qlimit(&la->la_holdq)) {
327 struct mbuf *_m;
328 /* prune less than CTL, else take what's at the head */
329 _m = _getq_scidx_lt(&la->la_holdq, SCIDX_CTL);
330 if (_m == NULL)
331 _m = _getq(&la->la_holdq);
332 VERIFY(_m != NULL);
333 if (arp_verbose) {
334 log(LOG_DEBUG, "%s: dropping packet (scidx %u)\n",
335 __func__, MBUF_SCIDX(mbuf_get_service_class(_m)));
336 }
337 m_freem(_m);
338 atomic_add_32(&arpstat.dropped, 1);
339 atomic_add_32(&arpstat.held, -1);
340 }
341 _addq(&la->la_holdq, m);
342 atomic_add_32(&arpstat.held, 1);
343 if (arp_verbose) {
344 log(LOG_DEBUG, "%s: enqueued packet (scidx %u), qlen now %u\n",
345 __func__, MBUF_SCIDX(mbuf_get_service_class(m)),
346 qlen(&la->la_holdq));
347 }
348}
349
350static uint32_t
351arp_llinfo_flushq(struct llinfo_arp *la)
352{
353 uint32_t held = qlen(&la->la_holdq);
354
5ba3f43e
A
355 if (held != 0) {
356 atomic_add_32(&arpstat.purged, held);
357 atomic_add_32(&arpstat.held, -held);
358 _flushq(&la->la_holdq);
359 }
360 la->la_prbreq_cnt = 0;
39037602 361 VERIFY(qempty(&la->la_holdq));
39037602
A
362 return (held);
363}
364
6d2010ae
A
365static void
366arp_llinfo_purge(struct rtentry *rt)
367{
368 struct llinfo_arp *la = rt->rt_llinfo;
369
370 RT_LOCK_ASSERT_HELD(rt);
371 VERIFY(rt->rt_llinfo_purge == arp_llinfo_purge && la != NULL);
372
373 if (la->la_llreach != NULL) {
374 RT_CONVERT_LOCK(rt);
375 ifnet_llreach_free(la->la_llreach);
376 la->la_llreach = NULL;
377 }
378 la->la_lastused = 0;
379}
380
381static void
382arp_llinfo_get_ri(struct rtentry *rt, struct rt_reach_info *ri)
383{
384 struct llinfo_arp *la = rt->rt_llinfo;
385 struct if_llreach *lr = la->la_llreach;
386
387 if (lr == NULL) {
388 bzero(ri, sizeof (*ri));
316670eb
A
389 ri->ri_rssi = IFNET_RSSI_UNKNOWN;
390 ri->ri_lqm = IFNET_LQM_THRESH_OFF;
391 ri->ri_npm = IFNET_NPM_THRESH_UNKNOWN;
6d2010ae
A
392 } else {
393 IFLR_LOCK(lr);
394 /* Export to rt_reach_info structure */
395 ifnet_lr2ri(lr, ri);
316670eb
A
396 /* Export ARP send expiration (calendar) time */
397 ri->ri_snd_expire =
398 ifnet_llreach_up2calexp(lr, la->la_lastused);
399 IFLR_UNLOCK(lr);
400 }
401}
402
403static void
404arp_llinfo_get_iflri(struct rtentry *rt, struct ifnet_llreach_info *iflri)
405{
406 struct llinfo_arp *la = rt->rt_llinfo;
407 struct if_llreach *lr = la->la_llreach;
408
409 if (lr == NULL) {
410 bzero(iflri, sizeof (*iflri));
411 iflri->iflri_rssi = IFNET_RSSI_UNKNOWN;
412 iflri->iflri_lqm = IFNET_LQM_THRESH_OFF;
413 iflri->iflri_npm = IFNET_NPM_THRESH_UNKNOWN;
414 } else {
415 IFLR_LOCK(lr);
416 /* Export to ifnet_llreach_info structure */
417 ifnet_lr2iflri(lr, iflri);
418 /* Export ARP send expiration (uptime) time */
419 iflri->iflri_snd_expire =
420 ifnet_llreach_up2upexp(lr, la->la_lastused);
6d2010ae
A
421 IFLR_UNLOCK(lr);
422 }
423}
424
3e170ce0
A
425static void
426arp_llinfo_refresh(struct rtentry *rt)
427{
428 uint64_t timenow = net_uptime();
429 /*
430 * If route entry is permanent or if expiry is less
431 * than timenow and extra time taken for unicast probe
432 * we can't expedite the refresh
433 */
434 if ((rt->rt_expire == 0) ||
435 (rt->rt_flags & RTF_STATIC) ||
436 !(rt->rt_flags & RTF_LLINFO)) {
437 return;
438 }
439
39037602
A
440 if (rt->rt_expire > timenow)
441 rt->rt_expire = timenow;
3e170ce0
A
442 return;
443}
444
6d2010ae
A
445void
446arp_llreach_set_reachable(struct ifnet *ifp, void *addr, unsigned int alen)
447{
448 /* Nothing more to do if it's disabled */
449 if (arp_llreach_base == 0)
450 return;
451
452 ifnet_llreach_set_reachable(ifp, ETHERTYPE_IP, addr, alen);
453}
454
455static __inline void
456arp_llreach_use(struct llinfo_arp *la)
457{
458 if (la->la_llreach != NULL)
459 la->la_lastused = net_uptime();
460}
461
462static __inline int
463arp_llreach_reachable(struct llinfo_arp *la)
464{
465 struct if_llreach *lr;
466 const char *why = NULL;
467
468 /* Nothing more to do if it's disabled; pretend it's reachable */
469 if (arp_llreach_base == 0)
470 return (1);
471
472 if ((lr = la->la_llreach) == NULL) {
473 /*
474 * Link-layer reachability record isn't present for this
475 * ARP entry; pretend it's reachable and use it as is.
476 */
477 return (1);
478 } else if (ifnet_llreach_reachable(lr)) {
479 /*
480 * Record is present, it's not shared with other ARP
481 * entries and a packet has recently been received
482 * from the remote host; consider it reachable.
483 */
484 if (lr->lr_reqcnt == 1)
485 return (1);
486
487 /* Prime it up, if this is the first time */
488 if (la->la_lastused == 0) {
489 VERIFY(la->la_llreach != NULL);
490 arp_llreach_use(la);
491 }
492
493 /*
494 * Record is present and shared with one or more ARP
495 * entries, and a packet has recently been received
496 * from the remote host. Since it's shared by more
497 * than one IP addresses, we can't rely on the link-
498 * layer reachability alone; consider it reachable if
499 * this ARP entry has been used "recently."
500 */
501 if (ifnet_llreach_reachable_delta(lr, la->la_lastused))
502 return (1);
503
504 why = "has alias(es) and hasn't been used in a while";
505 } else {
506 why = "haven't heard from it in a while";
507 }
508
39236c6e 509 if (arp_verbose > 1) {
6d2010ae
A
510 char tmp[MAX_IPv4_STR_LEN];
511 u_int64_t now = net_uptime();
512
39236c6e 513 log(LOG_DEBUG, "%s: ARP probe(s) needed for %s; "
6d2010ae 514 "%s [lastused %lld, lastrcvd %lld] secs ago\n",
39236c6e 515 if_name(lr->lr_ifp), inet_ntop(AF_INET,
6d2010ae 516 &SIN(rt_key(la->la_rt))->sin_addr, tmp, sizeof (tmp)), why,
39236c6e
A
517 (la->la_lastused ? (int64_t)(now - la->la_lastused) : -1),
518 (lr->lr_lastrcvd ? (int64_t)(now - lr->lr_lastrcvd) : -1));
6d2010ae
A
519
520 }
521 return (0);
522}
523
524/*
525 * Obtain a link-layer source cache entry for the sender.
526 *
527 * NOTE: This is currently only for ARP/Ethernet.
528 */
529static void
530arp_llreach_alloc(struct rtentry *rt, struct ifnet *ifp, void *addr,
5ba3f43e 531 unsigned int alen, boolean_t solicited, uint32_t *p_rt_event_code)
6d2010ae
A
532{
533 VERIFY(rt->rt_expire == 0 || rt->rt_rmx.rmx_expire != 0);
534 VERIFY(rt->rt_expire != 0 || rt->rt_rmx.rmx_expire == 0);
39236c6e
A
535
536 if (arp_llreach_base != 0 && rt->rt_expire != 0 &&
537 !(rt->rt_ifp->if_flags & IFF_LOOPBACK) &&
6d2010ae
A
538 ifp->if_addrlen == IF_LLREACH_MAXLEN && /* Ethernet */
539 alen == ifp->if_addrlen) {
540 struct llinfo_arp *la = rt->rt_llinfo;
541 struct if_llreach *lr;
542 const char *why = NULL, *type = "";
543
544 /* Become a regular mutex, just in case */
545 RT_CONVERT_LOCK(rt);
546
547 if ((lr = la->la_llreach) != NULL) {
548 type = (solicited ? "ARP reply" : "ARP announcement");
549 /*
550 * If target has changed, create a new record;
551 * otherwise keep existing record.
552 */
553 IFLR_LOCK(lr);
554 if (bcmp(addr, lr->lr_key.addr, alen) != 0) {
555 IFLR_UNLOCK(lr);
556 /* Purge any link-layer info caching */
557 VERIFY(rt->rt_llinfo_purge != NULL);
558 rt->rt_llinfo_purge(rt);
559 lr = NULL;
560 why = " for different target HW address; "
561 "using new llreach record";
5ba3f43e 562 *p_rt_event_code = ROUTE_LLENTRY_CHANGED;
6d2010ae 563 } else {
5ba3f43e
A
564 /*
565 * If we were doing unicast probing, we need to
566 * deliver an event for neighbor cache resolution
567 */
568 if (lr->lr_probes != 0)
569 *p_rt_event_code = ROUTE_LLENTRY_RESOLVED;
570
6d2010ae
A
571 lr->lr_probes = 0; /* reset probe count */
572 IFLR_UNLOCK(lr);
573 if (solicited) {
574 why = " for same target HW address; "
575 "keeping existing llreach record";
576 }
577 }
578 }
579
580 if (lr == NULL) {
581 lr = la->la_llreach = ifnet_llreach_alloc(ifp,
582 ETHERTYPE_IP, addr, alen, arp_llreach_base);
583 if (lr != NULL) {
584 lr->lr_probes = 0; /* reset probe count */
585 if (why == NULL)
586 why = "creating new llreach record";
587 }
5ba3f43e 588 *p_rt_event_code = ROUTE_LLENTRY_RESOLVED;
6d2010ae
A
589 }
590
39236c6e 591 if (arp_verbose > 1 && lr != NULL && why != NULL) {
6d2010ae
A
592 char tmp[MAX_IPv4_STR_LEN];
593
39236c6e
A
594 log(LOG_DEBUG, "%s: %s%s for %s\n", if_name(ifp),
595 type, why, inet_ntop(AF_INET,
6d2010ae
A
596 &SIN(rt_key(rt))->sin_addr, tmp, sizeof (tmp)));
597 }
598 }
599}
600
39236c6e 601struct arptf_arg {
39037602
A
602 boolean_t draining;
603 boolean_t probing;
39236c6e
A
604 uint32_t killed;
605 uint32_t aging;
606 uint32_t sticky;
607 uint32_t found;
39037602
A
608 uint32_t qlen;
609 uint32_t qsize;
39236c6e
A
610};
611
91447636
A
612/*
613 * Free an arp entry.
614 */
615static void
39236c6e 616arptfree(struct llinfo_arp *la, void *arg)
91447636 617{
39236c6e 618 struct arptf_arg *ap = arg;
91447636 619 struct rtentry *rt = la->la_rt;
39037602 620 uint64_t timenow;
b0d623f7 621
5ba3f43e 622 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
b0d623f7 623
39236c6e
A
624 /* rnh_lock acquired by caller protects rt from going away */
625 RT_LOCK(rt);
626
627 VERIFY(rt->rt_expire == 0 || rt->rt_rmx.rmx_expire != 0);
628 VERIFY(rt->rt_expire != 0 || rt->rt_rmx.rmx_expire == 0);
629
630 ap->found++;
39037602
A
631 timenow = net_uptime();
632
633 /* If we're probing, flush out held packets upon probe expiration */
634 if (ap->probing && (la->la_flags & LLINFO_PROBING) &&
635 la->la_probeexp <= timenow) {
636 struct sockaddr_dl *sdl = SDL(rt->rt_gateway);
637 if (sdl != NULL)
638 sdl->sdl_alen = 0;
639 (void) arp_llinfo_flushq(la);
5ba3f43e
A
640 /*
641 * Enqueue work item to invoke callback for this route entry
642 */
643 route_event_enqueue_nwk_wq_entry(rt, NULL,
644 ROUTE_LLENTRY_UNREACH, NULL, TRUE);
39037602
A
645 }
646
5ba3f43e
A
647 /*
648 * The following is mostly being used to arm the timer
649 * again and for logging.
650 * qlen is used to re-arm the timer. Therefore, pure probe
651 * requests can be considered as 0 length packets
652 * contributing only to length but not to the size.
653 */
39037602 654 ap->qlen += qlen(&la->la_holdq);
5ba3f43e 655 ap->qlen += la->la_prbreq_cnt;
39037602
A
656 ap->qsize += qsize(&la->la_holdq);
657
39236c6e
A
658 if (rt->rt_expire == 0 || (rt->rt_flags & RTF_STATIC)) {
659 ap->sticky++;
660 /* ARP entry is permanent? */
15129b1c 661 if (rt->rt_expire == 0) {
39236c6e
A
662 RT_UNLOCK(rt);
663 return;
664 }
665 }
666
667 /* ARP entry hasn't expired and we're not draining? */
39037602 668 if (!ap->draining && rt->rt_expire > timenow) {
b0d623f7 669 RT_UNLOCK(rt);
39236c6e
A
670 ap->aging++;
671 return;
672 }
673
674 if (rt->rt_refcnt > 0) {
6d2010ae 675 /*
39236c6e
A
676 * ARP entry has expired, with outstanding refcnt.
677 * If we're not draining, force ARP query to be
678 * generated next time this entry is used.
6d2010ae 679 */
39037602 680 if (!ap->draining && !ap->probing) {
39236c6e
A
681 struct sockaddr_dl *sdl = SDL(rt->rt_gateway);
682 if (sdl != NULL)
683 sdl->sdl_alen = 0;
684 la->la_asked = 0;
685 rt->rt_flags &= ~RTF_REJECT;
686 }
6d2010ae 687 RT_UNLOCK(rt);
39037602 688 } else if (!(rt->rt_flags & RTF_STATIC) && !ap->probing) {
b0d623f7 689 /*
39236c6e
A
690 * ARP entry has no outstanding refcnt, and we're either
691 * draining or it has expired; delete it from the routing
692 * table. Safe to drop rt_lock and use rt_key, since holding
b0d623f7
A
693 * rnh_lock here prevents another thread from calling
694 * rt_setgate() on this route.
695 */
696 RT_UNLOCK(rt);
39236c6e
A
697 rtrequest_locked(RTM_DELETE, rt_key(rt), NULL,
698 rt_mask(rt), 0, NULL);
699 arpstat.timeouts++;
700 ap->killed++;
701 } else {
702 /* ARP entry is static; let it linger */
703 RT_UNLOCK(rt);
91447636 704 }
91447636
A
705}
706
d1ecb069 707void
39236c6e 708in_arpdrain(void *arg)
91447636 709{
39236c6e 710#pragma unused(arg)
0c530ab8 711 struct llinfo_arp *la, *ola;
39236c6e
A
712 struct arptf_arg farg;
713
714 if (arp_verbose)
715 log(LOG_DEBUG, "%s: draining ARP entries\n", __func__);
91447636 716
b0d623f7 717 lck_mtx_lock(rnh_lock);
0c530ab8 718 la = llinfo_arp.lh_first;
39236c6e 719 bzero(&farg, sizeof (farg));
39037602 720 farg.draining = TRUE;
39236c6e 721 while ((ola = la) != NULL) {
91447636 722 la = la->la_le.le_next;
39236c6e
A
723 arptfree(ola, &farg);
724 }
725 if (arp_verbose) {
39037602
A
726 log(LOG_DEBUG, "%s: found %u, aging %u, sticky %u, killed %u; "
727 "%u pkts held (%u bytes)\n", __func__, farg.found,
728 farg.aging, farg.sticky, farg.killed, farg.qlen,
729 farg.qsize);
91447636 730 }
b0d623f7 731 lck_mtx_unlock(rnh_lock);
d1ecb069
A
732}
733
39236c6e
A
734/*
735 * Timeout routine. Age arp_tab entries periodically.
736 */
737static void
39037602 738arp_timeout(thread_call_param_t arg0, thread_call_param_t arg1)
6d2010ae 739{
39037602 740#pragma unused(arg0, arg1)
39236c6e
A
741 struct llinfo_arp *la, *ola;
742 struct timeval atv;
743 struct arptf_arg farg;
6d2010ae 744
39236c6e
A
745 lck_mtx_lock(rnh_lock);
746 la = llinfo_arp.lh_first;
747 bzero(&farg, sizeof (farg));
748 while ((ola = la) != NULL) {
749 la = la->la_le.le_next;
750 arptfree(ola, &farg);
751 }
752 if (arp_verbose) {
39037602
A
753 log(LOG_DEBUG, "%s: found %u, aging %u, sticky %u, killed %u; "
754 "%u pkts held (%u bytes)\n", __func__, farg.found,
755 farg.aging, farg.sticky, farg.killed, farg.qlen,
756 farg.qsize);
39236c6e
A
757 }
758 atv.tv_usec = 0;
39037602 759 atv.tv_sec = MAX(arpt_prune, 5);
39236c6e
A
760 /* re-arm the timer if there's work to do */
761 arp_timeout_run = 0;
762 if (farg.aging > 0)
763 arp_sched_timeout(&atv);
764 else if (arp_verbose)
765 log(LOG_DEBUG, "%s: not rescheduling timer\n", __func__);
766 lck_mtx_unlock(rnh_lock);
6d2010ae
A
767}
768
d1ecb069 769static void
39236c6e 770arp_sched_timeout(struct timeval *atv)
d1ecb069 771{
5ba3f43e 772 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
39236c6e
A
773
774 if (!arp_timeout_run) {
775 struct timeval tv;
39037602
A
776 uint64_t deadline = 0;
777
778 if (arp_timeout_tcall == NULL) {
779 arp_timeout_tcall =
780 thread_call_allocate(arp_timeout, NULL);
781 VERIFY(arp_timeout_tcall != NULL);
782 }
39236c6e
A
783
784 if (atv == NULL) {
785 tv.tv_usec = 0;
786 tv.tv_sec = MAX(arpt_prune / 5, 1);
787 atv = &tv;
788 }
789 if (arp_verbose) {
790 log(LOG_DEBUG, "%s: timer scheduled in "
791 "T+%llus.%lluu\n", __func__,
792 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec);
793 }
794 arp_timeout_run = 1;
39037602
A
795
796 clock_deadline_for_periodic_event(atv->tv_sec * NSEC_PER_SEC,
797 mach_absolute_time(), &deadline);
798 (void) thread_call_enter_delayed(arp_timeout_tcall, deadline);
799 }
800}
801
802/*
803 * Probe routine.
804 */
805static void
806arp_probe(thread_call_param_t arg0, thread_call_param_t arg1)
807{
808#pragma unused(arg0, arg1)
809 struct llinfo_arp *la, *ola;
810 struct timeval atv;
811 struct arptf_arg farg;
812
813 lck_mtx_lock(rnh_lock);
814 la = llinfo_arp.lh_first;
815 bzero(&farg, sizeof (farg));
816 farg.probing = TRUE;
817 while ((ola = la) != NULL) {
818 la = la->la_le.le_next;
819 arptfree(ola, &farg);
820 }
821 if (arp_verbose) {
822 log(LOG_DEBUG, "%s: found %u, aging %u, sticky %u, killed %u; "
823 "%u pkts held (%u bytes)\n", __func__, farg.found,
824 farg.aging, farg.sticky, farg.killed, farg.qlen,
825 farg.qsize);
826 }
827 atv.tv_usec = 0;
828 atv.tv_sec = MAX(arpt_probe, ARP_PROBE_TIME);
829 /* re-arm the probe if there's work to do */
830 arp_probe_run = 0;
831 if (farg.qlen > 0)
832 arp_sched_probe(&atv);
833 else if (arp_verbose)
834 log(LOG_DEBUG, "%s: not rescheduling probe\n", __func__);
835 lck_mtx_unlock(rnh_lock);
836}
837
838static void
839arp_sched_probe(struct timeval *atv)
840{
5ba3f43e 841 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
39037602
A
842
843 if (!arp_probe_run) {
844 struct timeval tv;
845 uint64_t deadline = 0;
846
847 if (arp_probe_tcall == NULL) {
848 arp_probe_tcall =
849 thread_call_allocate(arp_probe, NULL);
850 VERIFY(arp_probe_tcall != NULL);
851 }
852
853 if (atv == NULL) {
854 tv.tv_usec = 0;
855 tv.tv_sec = MAX(arpt_probe, ARP_PROBE_TIME);
856 atv = &tv;
857 }
858 if (arp_verbose) {
859 log(LOG_DEBUG, "%s: probe scheduled in "
860 "T+%llus.%lluu\n", __func__,
861 (uint64_t)atv->tv_sec, (uint64_t)atv->tv_usec);
862 }
863 arp_probe_run = 1;
864
865 clock_deadline_for_periodic_event(atv->tv_sec * NSEC_PER_SEC,
866 mach_absolute_time(), &deadline);
867 (void) thread_call_enter_delayed(arp_probe_tcall, deadline);
39236c6e 868 }
91447636
A
869}
870
871/*
39236c6e 872 * ifa_rtrequest() callback
91447636
A
873 */
874static void
39236c6e 875arp_rtrequest(int req, struct rtentry *rt, struct sockaddr *sa)
91447636 876{
39236c6e 877#pragma unused(sa)
91447636 878 struct sockaddr *gate = rt->rt_gateway;
b0d623f7 879 struct llinfo_arp *la = rt->rt_llinfo;
39236c6e
A
880 static struct sockaddr_dl null_sdl =
881 { .sdl_len = sizeof (null_sdl), .sdl_family = AF_LINK };
6d2010ae 882 uint64_t timenow;
39236c6e 883 char buf[MAX_IPv4_STR_LEN];
91447636 884
39236c6e 885 VERIFY(arpinit_done);
5ba3f43e 886 LCK_MTX_ASSERT(rnh_lock, LCK_MTX_ASSERT_OWNED);
b0d623f7 887 RT_LOCK_ASSERT_HELD(rt);
91447636
A
888
889 if (rt->rt_flags & RTF_GATEWAY)
890 return;
39236c6e 891
6d2010ae 892 timenow = net_uptime();
91447636 893 switch (req) {
91447636
A
894 case RTM_ADD:
895 /*
896 * XXX: If this is a manually added route to interface
897 * such as older version of routed or gated might provide,
898 * restore cloning bit.
899 */
39236c6e
A
900 if (!(rt->rt_flags & RTF_HOST) && rt_mask(rt) != NULL &&
901 SIN(rt_mask(rt))->sin_addr.s_addr != INADDR_BROADCAST)
91447636 902 rt->rt_flags |= RTF_CLONING;
39236c6e 903
91447636
A
904 if (rt->rt_flags & RTF_CLONING) {
905 /*
906 * Case 1: This route should come from a route to iface.
907 */
39236c6e 908 if (rt_setgate(rt, rt_key(rt), SA(&null_sdl)) == 0) {
b0d623f7
A
909 gate = rt->rt_gateway;
910 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
911 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
912 /*
913 * In case we're called before 1.0 sec.
914 * has elapsed.
915 */
6d2010ae 916 rt_setexpire(rt, MAX(timenow, 1));
b0d623f7 917 }
91447636
A
918 break;
919 }
920 /* Announce a new entry if requested. */
b0d623f7 921 if (rt->rt_flags & RTF_ANNOUNCE) {
6d2010ae
A
922 if (la != NULL)
923 arp_llreach_use(la); /* Mark use timestamp */
b0d623f7
A
924 RT_UNLOCK(rt);
925 dlil_send_arp(rt->rt_ifp, ARPOP_REQUEST,
316670eb 926 SDL(gate), rt_key(rt), NULL, rt_key(rt), 0);
b0d623f7 927 RT_LOCK(rt);
39236c6e 928 arpstat.txannounces++;
b0d623f7 929 }
39236c6e 930 /* FALLTHRU */
91447636
A
931 case RTM_RESOLVE:
932 if (gate->sa_family != AF_LINK ||
39236c6e
A
933 gate->sa_len < sizeof (null_sdl)) {
934 arpstat.invalidreqs++;
935 log(LOG_ERR, "%s: route to %s has bad gateway address "
936 "(sa_family %u sa_len %u) on %s\n",
937 __func__, inet_ntop(AF_INET,
938 &SIN(rt_key(rt))->sin_addr.s_addr, buf,
939 sizeof (buf)), gate->sa_family, gate->sa_len,
940 if_name(rt->rt_ifp));
91447636
A
941 break;
942 }
943 SDL(gate)->sdl_type = rt->rt_ifp->if_type;
944 SDL(gate)->sdl_index = rt->rt_ifp->if_index;
39236c6e
A
945
946 if (la != NULL)
91447636 947 break; /* This happens on a route change */
39236c6e 948
91447636
A
949 /*
950 * Case 2: This route may come from cloning, or a manual route
951 * add with a LL address.
952 */
39236c6e 953 rt->rt_llinfo = la = arp_llinfo_alloc(M_WAITOK);
b0d623f7 954 if (la == NULL) {
39236c6e 955 arpstat.reqnobufs++;
91447636
A
956 break;
957 }
39236c6e
A
958 rt->rt_llinfo_get_ri = arp_llinfo_get_ri;
959 rt->rt_llinfo_get_iflri = arp_llinfo_get_iflri;
960 rt->rt_llinfo_purge = arp_llinfo_purge;
961 rt->rt_llinfo_free = arp_llinfo_free;
3e170ce0 962 rt->rt_llinfo_refresh = arp_llinfo_refresh;
91447636 963 rt->rt_flags |= RTF_LLINFO;
39236c6e 964 la->la_rt = rt;
91447636 965 LIST_INSERT_HEAD(&llinfo_arp, la, la_le);
39236c6e
A
966 arpstat.inuse++;
967
968 /* We have at least one entry; arm the timer if not already */
969 arp_sched_timeout(NULL);
91447636 970
91447636
A
971 /*
972 * This keeps the multicast addresses from showing up
973 * in `arp -a' listings as unresolved. It's not actually
6d2010ae
A
974 * functional. Then the same for broadcast. For IPv4
975 * link-local address, keep the entry around even after
976 * it has expired.
91447636
A
977 */
978 if (IN_MULTICAST(ntohl(SIN(rt_key(rt))->sin_addr.s_addr))) {
b0d623f7
A
979 RT_UNLOCK(rt);
980 dlil_resolve_multi(rt->rt_ifp, rt_key(rt), gate,
39236c6e 981 sizeof (struct sockaddr_dl));
b0d623f7 982 RT_LOCK(rt);
6d2010ae 983 rt_setexpire(rt, 0);
39236c6e
A
984 } else if (in_broadcast(SIN(rt_key(rt))->sin_addr,
985 rt->rt_ifp)) {
986 struct sockaddr_dl *gate_ll = SDL(gate);
987 size_t broadcast_len;
b0d623f7 988 ifnet_llbroadcast_copy_bytes(rt->rt_ifp,
39236c6e 989 LLADDR(gate_ll), sizeof (gate_ll->sdl_data),
b0d623f7 990 &broadcast_len);
91447636
A
991 gate_ll->sdl_alen = broadcast_len;
992 gate_ll->sdl_family = AF_LINK;
39236c6e 993 gate_ll->sdl_len = sizeof (struct sockaddr_dl);
593a1d5f 994 /* In case we're called before 1.0 sec. has elapsed */
6d2010ae 995 rt_setexpire(rt, MAX(timenow, 1));
39236c6e
A
996 } else if (IN_LINKLOCAL(ntohl(SIN(rt_key(rt))->
997 sin_addr.s_addr))) {
6d2010ae 998 rt->rt_flags |= RTF_STATIC;
91447636 999 }
91447636 1000
39236c6e
A
1001 /* Set default maximum number of retries */
1002 la->la_maxtries = arp_maxtries;
1003
6d2010ae
A
1004 /* Become a regular mutex, just in case */
1005 RT_CONVERT_LOCK(rt);
1006 IFA_LOCK_SPIN(rt->rt_ifa);
91447636
A
1007 if (SIN(rt_key(rt))->sin_addr.s_addr ==
1008 (IA_SIN(rt->rt_ifa))->sin_addr.s_addr) {
6d2010ae
A
1009 IFA_UNLOCK(rt->rt_ifa);
1010 /*
1011 * This test used to be
1012 * if (loif.if_flags & IFF_UP)
1013 * It allowed local traffic to be forced through the
1014 * hardware by configuring the loopback down. However,
1015 * it causes problems during network configuration
1016 * for boards that can't receive packets they send.
1017 * It is now necessary to clear "useloopback" and
1018 * remove the route to force traffic out to the
1019 * hardware.
1020 */
1021 rt_setexpire(rt, 0);
1022 ifnet_lladdr_copy_bytes(rt->rt_ifp, LLADDR(SDL(gate)),
1023 SDL(gate)->sdl_alen = rt->rt_ifp->if_addrlen);
d1ecb069 1024 if (useloopback) {
6d2010ae
A
1025 if (rt->rt_ifp != lo_ifp) {
1026 /*
1027 * Purge any link-layer info caching.
1028 */
1029 if (rt->rt_llinfo_purge != NULL)
1030 rt->rt_llinfo_purge(rt);
1031
1032 /*
1033 * Adjust route ref count for the
1034 * interfaces.
1035 */
1036 if (rt->rt_if_ref_fn != NULL) {
1037 rt->rt_if_ref_fn(lo_ifp, 1);
1038 rt->rt_if_ref_fn(rt->rt_ifp, -1);
1039 }
d1ecb069 1040 }
2d21ac55 1041 rt->rt_ifp = lo_ifp;
39236c6e
A
1042 /*
1043 * If rmx_mtu is not locked, update it
1044 * to the MTU used by the new interface.
1045 */
1046 if (!(rt->rt_rmx.rmx_locks & RTV_MTU))
1047 rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;
d1ecb069 1048 }
6d2010ae
A
1049 } else {
1050 IFA_UNLOCK(rt->rt_ifa);
91447636
A
1051 }
1052 break;
1053
1054 case RTM_DELETE:
39236c6e 1055 if (la == NULL)
91447636 1056 break;
b0d623f7
A
1057 /*
1058 * Unchain it but defer the actual freeing until the route
1059 * itself is to be freed. rt->rt_llinfo still points to
1060 * llinfo_arp, and likewise, la->la_rt still points to this
1061 * route entry, except that RTF_LLINFO is now cleared.
1062 */
91447636 1063 LIST_REMOVE(la, la_le);
b0d623f7
A
1064 la->la_le.le_next = NULL;
1065 la->la_le.le_prev = NULL;
39236c6e 1066 arpstat.inuse--;
6d2010ae
A
1067
1068 /*
1069 * Purge any link-layer info caching.
1070 */
1071 if (rt->rt_llinfo_purge != NULL)
1072 rt->rt_llinfo_purge(rt);
1073
91447636 1074 rt->rt_flags &= ~RTF_LLINFO;
39037602 1075 (void) arp_llinfo_flushq(la);
91447636
A
1076 }
1077}
1078
1079/*
1080 * convert hardware address to hex string for logging errors.
1081 */
1082static const char *
39236c6e 1083sdl_addr_to_hex(const struct sockaddr_dl *sdl, char *orig_buf, int buflen)
91447636 1084{
39236c6e
A
1085 char *buf = orig_buf;
1086 int i;
1087 const u_char *lladdr = (u_char *)(size_t)sdl->sdl_data;
1088 int maxbytes = buflen / 3;
1089
91447636
A
1090 if (maxbytes > sdl->sdl_alen) {
1091 maxbytes = sdl->sdl_alen;
39236c6e 1092 }
91447636
A
1093 *buf = '\0';
1094 for (i = 0; i < maxbytes; i++) {
1095 snprintf(buf, 3, "%02x", lladdr[i]);
1096 buf += 2;
1097 *buf = (i == maxbytes - 1) ? '\0' : ':';
1098 buf++;
1099 }
1100 return (orig_buf);
1101}
1102
1103/*
1104 * arp_lookup_route will lookup the route for a given address.
1105 *
b0d623f7
A
1106 * The address must be for a host on a local network on this interface.
1107 * If the returned route is non-NULL, the route is locked and the caller
1108 * is responsible for unlocking it and releasing its reference.
91447636
A
1109 */
1110static errno_t
b0d623f7
A
1111arp_lookup_route(const struct in_addr *addr, int create, int proxy,
1112 route_t *route, unsigned int ifscope)
91447636 1113{
39236c6e
A
1114 struct sockaddr_inarp sin =
1115 { sizeof (sin), AF_INET, 0, { 0 }, { 0 }, 0, 0 };
2d21ac55 1116 const char *why = NULL;
91447636 1117 errno_t error = 0;
b0d623f7
A
1118 route_t rt;
1119
1120 *route = NULL;
91447636
A
1121
1122 sin.sin_addr.s_addr = addr->s_addr;
1123 sin.sin_other = proxy ? SIN_PROXY : 0;
c910b4d9 1124
6d2010ae
A
1125 /*
1126 * If the destination is a link-local address, don't
1127 * constrain the lookup (don't scope it).
1128 */
1129 if (IN_LINKLOCAL(ntohl(addr->s_addr)))
1130 ifscope = IFSCOPE_NONE;
1131
39236c6e 1132 rt = rtalloc1_scoped((struct sockaddr *)&sin, create, 0, ifscope);
b0d623f7
A
1133 if (rt == NULL)
1134 return (ENETUNREACH);
1135
1136 RT_LOCK(rt);
1137
1138 if (rt->rt_flags & RTF_GATEWAY) {
91447636 1139 why = "host is not on local network";
91447636 1140 error = ENETUNREACH;
b0d623f7 1141 } else if (!(rt->rt_flags & RTF_LLINFO)) {
91447636 1142 why = "could not allocate llinfo";
91447636 1143 error = ENOMEM;
b0d623f7 1144 } else if (rt->rt_gateway->sa_family != AF_LINK) {
91447636 1145 why = "gateway route is not ours";
91447636
A
1146 error = EPROTONOSUPPORT;
1147 }
b0d623f7
A
1148
1149 if (error != 0) {
39236c6e 1150 if (create && (arp_verbose || log_arp_warnings)) {
b0d623f7 1151 char tmp[MAX_IPv4_STR_LEN];
39236c6e
A
1152 log(LOG_DEBUG, "%s: link#%d %s failed: %s\n",
1153 __func__, ifscope, inet_ntop(AF_INET, addr, tmp,
b0d623f7
A
1154 sizeof (tmp)), why);
1155 }
1156
1157 /*
1158 * If there are no references to this route, and it is
1159 * a cloned route, and not static, and ARP had created
1160 * the route, then purge it from the routing table as
1161 * it is probably bogus.
1162 */
1163 if (rt->rt_refcnt == 1 &&
1164 (rt->rt_flags & (RTF_WASCLONED | RTF_STATIC)) ==
1165 RTF_WASCLONED) {
1166 /*
1167 * Prevent another thread from modiying rt_key,
1168 * rt_gateway via rt_setgate() after rt_lock is
1169 * dropped by marking the route as defunct.
1170 */
1171 rt->rt_flags |= RTF_CONDEMNED;
1172 RT_UNLOCK(rt);
1173 rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
39236c6e 1174 rt_mask(rt), rt->rt_flags, NULL);
b0d623f7
A
1175 rtfree(rt);
1176 } else {
1177 RT_REMREF_LOCKED(rt);
1178 RT_UNLOCK(rt);
1179 }
1180 return (error);
91447636 1181 }
91447636 1182
b0d623f7
A
1183 /*
1184 * Caller releases reference and does RT_UNLOCK(rt).
1185 */
1186 *route = rt;
1187 return (0);
1188}
91447636 1189
5ba3f43e
A
1190boolean_t
1191arp_is_entry_probing (route_t p_route)
1192{
1193 struct llinfo_arp *llinfo = p_route->rt_llinfo;
1194
1195 if (llinfo != NULL &&
1196 llinfo->la_llreach != NULL &&
1197 llinfo->la_llreach->lr_probes != 0)
1198 return (TRUE);
1199
1200 return (FALSE);
1201}
1202
b0d623f7
A
1203/*
1204 * This is the ARP pre-output routine; care must be taken to ensure that
1205 * the "hint" route never gets freed via rtfree(), since the caller may
1206 * have stored it inside a struct route with a reference held for that
1207 * placeholder.
1208 */
91447636 1209errno_t
b0d623f7
A
1210arp_lookup_ip(ifnet_t ifp, const struct sockaddr_in *net_dest,
1211 struct sockaddr_dl *ll_dest, size_t ll_dest_len, route_t hint,
1212 mbuf_t packet)
91447636 1213{
b0d623f7 1214 route_t route = NULL; /* output route */
91447636 1215 errno_t result = 0;
39236c6e
A
1216 struct sockaddr_dl *gateway;
1217 struct llinfo_arp *llinfo = NULL;
39037602 1218 boolean_t usable, probing = FALSE;
6d2010ae 1219 uint64_t timenow;
fe8ab488
A
1220 struct if_llreach *lr;
1221 struct ifaddr *rt_ifa;
1222 struct sockaddr *sa;
1223 uint32_t rtflags;
1224 struct sockaddr_dl sdl;
5ba3f43e 1225 boolean_t send_probe_notif = FALSE;
b0d623f7 1226
39037602
A
1227 if (ifp == NULL || net_dest == NULL)
1228 return (EINVAL);
1229
91447636 1230 if (net_dest->sin_family != AF_INET)
b0d623f7
A
1231 return (EAFNOSUPPORT);
1232
91447636 1233 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
b0d623f7
A
1234 return (ENETDOWN);
1235
91447636
A
1236 /*
1237 * If we were given a route, verify the route and grab the gateway
1238 */
b0d623f7
A
1239 if (hint != NULL) {
1240 /*
1241 * Callee holds a reference on the route and returns
1242 * with the route entry locked, upon success.
1243 */
316670eb 1244 result = route_to_gwroute((const struct sockaddr *)
b0d623f7 1245 net_dest, hint, &route);
91447636 1246 if (result != 0)
b0d623f7
A
1247 return (result);
1248 if (route != NULL)
1249 RT_LOCK_ASSERT_HELD(route);
91447636 1250 }
b0d623f7 1251
39037602
A
1252 if ((packet != NULL && (packet->m_flags & M_BCAST)) ||
1253 in_broadcast(net_dest->sin_addr, ifp)) {
39236c6e 1254 size_t broadcast_len;
91447636 1255 bzero(ll_dest, ll_dest_len);
b0d623f7
A
1256 result = ifnet_llbroadcast_copy_bytes(ifp, LLADDR(ll_dest),
1257 ll_dest_len - offsetof(struct sockaddr_dl, sdl_data),
1258 &broadcast_len);
1259 if (result == 0) {
1260 ll_dest->sdl_alen = broadcast_len;
1261 ll_dest->sdl_family = AF_LINK;
39236c6e 1262 ll_dest->sdl_len = sizeof (struct sockaddr_dl);
91447636 1263 }
b0d623f7 1264 goto release;
91447636 1265 }
39037602
A
1266 if ((packet != NULL && (packet->m_flags & M_MCAST)) ||
1267 ((ifp->if_flags & IFF_MULTICAST) &&
1268 IN_MULTICAST(ntohl(net_dest->sin_addr.s_addr)))) {
b0d623f7
A
1269 if (route != NULL)
1270 RT_UNLOCK(route);
1271 result = dlil_resolve_multi(ifp,
39236c6e
A
1272 (const struct sockaddr *)net_dest,
1273 (struct sockaddr *)ll_dest, ll_dest_len);
b0d623f7
A
1274 if (route != NULL)
1275 RT_LOCK(route);
1276 goto release;
91447636 1277 }
b0d623f7 1278
91447636
A
1279 /*
1280 * If we didn't find a route, or the route doesn't have
1281 * link layer information, trigger the creation of the
1282 * route and link layer information.
1283 */
b0d623f7
A
1284 if (route == NULL || route->rt_llinfo == NULL) {
1285 /* Clean up now while we can */
1286 if (route != NULL) {
1287 if (route == hint) {
1288 RT_REMREF_LOCKED(route);
1289 RT_UNLOCK(route);
1290 } else {
1291 RT_UNLOCK(route);
1292 rtfree(route);
1293 }
1294 }
1295 /*
1296 * Callee holds a reference on the route and returns
1297 * with the route entry locked, upon success.
1298 */
c910b4d9
A
1299 result = arp_lookup_route(&net_dest->sin_addr, 1, 0, &route,
1300 ifp->if_index);
b0d623f7
A
1301 if (result == 0)
1302 RT_LOCK_ASSERT_HELD(route);
1303 }
1304
6d2010ae 1305 if (result || route == NULL || (llinfo = route->rt_llinfo) == NULL) {
b0d623f7
A
1306 /* In case result is 0 but no route, return an error */
1307 if (result == 0)
1308 result = EHOSTUNREACH;
1309
39236c6e
A
1310 if (route != NULL && route->rt_llinfo == NULL) {
1311 char tmp[MAX_IPv4_STR_LEN];
1312 log(LOG_ERR, "%s: can't allocate llinfo for %s\n",
1313 __func__, inet_ntop(AF_INET, &net_dest->sin_addr,
1314 tmp, sizeof (tmp)));
1315 }
b0d623f7 1316 goto release;
91447636 1317 }
b0d623f7 1318
91447636
A
1319 /*
1320 * Now that we have the right route, is it filled in?
1321 */
1322 gateway = SDL(route->rt_gateway);
6d2010ae
A
1323 timenow = net_uptime();
1324 VERIFY(route->rt_expire == 0 || route->rt_rmx.rmx_expire != 0);
1325 VERIFY(route->rt_expire != 0 || route->rt_rmx.rmx_expire == 0);
39037602
A
1326
1327 usable = ((route->rt_expire == 0 || route->rt_expire > timenow) &&
1328 gateway != NULL && gateway->sdl_family == AF_LINK &&
1329 gateway->sdl_alen != 0);
1330
1331 if (usable) {
1332 boolean_t unreachable = !arp_llreach_reachable(llinfo);
1333
1334 /* Entry is usable, so fill in info for caller */
91447636 1335 bcopy(gateway, ll_dest, MIN(gateway->sdl_len, ll_dest_len));
b0d623f7 1336 result = 0;
6d2010ae 1337 arp_llreach_use(llinfo); /* Mark use timestamp */
39037602 1338
fe8ab488
A
1339 lr = llinfo->la_llreach;
1340 if (lr == NULL)
1341 goto release;
1342 rt_ifa = route->rt_ifa;
39037602 1343
fe8ab488
A
1344 /* Become a regular mutex, just in case */
1345 RT_CONVERT_LOCK(route);
1346 IFLR_LOCK_SPIN(lr);
39037602
A
1347
1348 if ((unreachable || (llinfo->la_flags & LLINFO_PROBING)) &&
1349 lr->lr_probes < arp_unicast_lim) {
1350 /*
1351 * Thus mark the entry with la_probeexp deadline to
1352 * trigger the probe timer to be scheduled (if not
1353 * already). This gets cleared the moment we get
1354 * an ARP reply.
1355 */
1356 probing = TRUE;
1357 if (lr->lr_probes == 0) {
1358 llinfo->la_probeexp = (timenow + arpt_probe);
1359 llinfo->la_flags |= LLINFO_PROBING;
5ba3f43e
A
1360 /*
1361 * Provide notification that ARP unicast
1362 * probing has started.
1363 * We only do it for the first unicast probe
1364 * attempt.
1365 */
1366 send_probe_notif = TRUE;
39037602
A
1367 }
1368
1369 /*
1370 * Start the unicast probe and anticipate a reply;
1371 * afterwards, return existing entry to caller and
1372 * let it be used anyway. If peer is non-existent
1373 * we'll broadcast ARP next time around.
1374 */
fe8ab488
A
1375 lr->lr_probes++;
1376 bzero(&sdl, sizeof (sdl));
1377 sdl.sdl_alen = ifp->if_addrlen;
1378 bcopy(&lr->lr_key.addr, LLADDR(&sdl),
1379 ifp->if_addrlen);
1380 IFLR_UNLOCK(lr);
1381 IFA_LOCK_SPIN(rt_ifa);
1382 IFA_ADDREF_LOCKED(rt_ifa);
1383 sa = rt_ifa->ifa_addr;
1384 IFA_UNLOCK(rt_ifa);
1385 rtflags = route->rt_flags;
1386 RT_UNLOCK(route);
1387 dlil_send_arp(ifp, ARPOP_REQUEST, NULL, sa,
1388 (const struct sockaddr_dl *)&sdl,
1389 (const struct sockaddr *)net_dest, rtflags);
1390 IFA_REMREF(rt_ifa);
1391 RT_LOCK(route);
39037602
A
1392 goto release;
1393 } else {
fe8ab488 1394 IFLR_UNLOCK(lr);
39037602
A
1395 if (!unreachable &&
1396 !(llinfo->la_flags & LLINFO_PROBING)) {
1397 /*
1398 * Normal case where peer is still reachable,
1399 * we're not probing and if_addrlen is anything
1400 * but IF_LLREACH_MAXLEN.
1401 */
1402 goto release;
1403 }
1404 }
91447636 1405 }
b0d623f7
A
1406
1407 if (ifp->if_flags & IFF_NOARP) {
1408 result = ENOTSUP;
1409 goto release;
1410 }
1411
91447636 1412 /*
39037602
A
1413 * Route wasn't complete/valid; we need to send out ARP request.
1414 * If we've exceeded the limit of la_holdq, drop from the head
1415 * of queue and add this packet to the tail. If we end up with
1416 * RTF_REJECT below, we'll dequeue this from tail and have the
1417 * caller free the packet instead. It's safe to do that since
1418 * we still hold the route's rt_lock.
91447636 1419 */
39037602
A
1420 if (packet != NULL)
1421 arp_llinfo_addq(llinfo, packet);
5ba3f43e
A
1422 else
1423 llinfo->la_prbreq_cnt++;
39037602
A
1424 /*
1425 * Regardless of permanent vs. expirable entry, we need to
1426 * avoid having packets sit in la_holdq forever; thus mark the
1427 * entry with la_probeexp deadline to trigger the probe timer
1428 * to be scheduled (if not already). This gets cleared the
1429 * moment we get an ARP reply.
1430 */
1431 probing = TRUE;
5ba3f43e 1432 if ((qlen(&llinfo->la_holdq) + llinfo->la_prbreq_cnt) == 1) {
39037602
A
1433 llinfo->la_probeexp = (timenow + arpt_probe);
1434 llinfo->la_flags |= LLINFO_PROBING;
1435 }
5ba3f43e 1436
6d2010ae 1437 if (route->rt_expire) {
91447636 1438 route->rt_flags &= ~RTF_REJECT;
39236c6e 1439 if (llinfo->la_asked == 0 || route->rt_expire != timenow) {
6d2010ae 1440 rt_setexpire(route, timenow);
39236c6e 1441 if (llinfo->la_asked++ < llinfo->la_maxtries) {
fe8ab488
A
1442 struct kev_msg ev_msg;
1443 struct kev_in_arpfailure in_arpfailure;
1444 boolean_t sendkev = FALSE;
6d2010ae 1445
fe8ab488
A
1446 rt_ifa = route->rt_ifa;
1447 lr = llinfo->la_llreach;
6d2010ae
A
1448 /* Become a regular mutex, just in case */
1449 RT_CONVERT_LOCK(route);
1450 /* Update probe count, if applicable */
39236c6e
A
1451 if (lr != NULL) {
1452 IFLR_LOCK_SPIN(lr);
1453 lr->lr_probes++;
39236c6e 1454 IFLR_UNLOCK(lr);
6d2010ae 1455 }
fe8ab488
A
1456 if (ifp->if_addrlen == IF_LLREACH_MAXLEN &&
1457 route->rt_flags & RTF_ROUTER &&
1458 llinfo->la_asked > 1) {
1459 sendkev = TRUE;
1460 llinfo->la_flags |= LLINFO_RTRFAIL_EVTSENT;
1461 }
6d2010ae
A
1462 IFA_LOCK_SPIN(rt_ifa);
1463 IFA_ADDREF_LOCKED(rt_ifa);
1464 sa = rt_ifa->ifa_addr;
1465 IFA_UNLOCK(rt_ifa);
39236c6e 1466 arp_llreach_use(llinfo); /* Mark use tstamp */
316670eb 1467 rtflags = route->rt_flags;
b0d623f7 1468 RT_UNLOCK(route);
39236c6e 1469 dlil_send_arp(ifp, ARPOP_REQUEST, NULL, sa,
fe8ab488
A
1470 NULL, (const struct sockaddr *)net_dest,
1471 rtflags);
6d2010ae 1472 IFA_REMREF(rt_ifa);
fe8ab488
A
1473 if (sendkev) {
1474 bzero(&ev_msg, sizeof(ev_msg));
39037602 1475 bzero(&in_arpfailure,
fe8ab488
A
1476 sizeof(in_arpfailure));
1477 in_arpfailure.link_data.if_family =
1478 ifp->if_family;
1479 in_arpfailure.link_data.if_unit =
1480 ifp->if_unit;
1481 strlcpy(in_arpfailure.link_data.if_name,
1482 ifp->if_name, IFNAMSIZ);
1483 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1484 ev_msg.kev_class = KEV_NETWORK_CLASS;
1485 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
1486 ev_msg.event_code =
1487 KEV_INET_ARPRTRFAILURE;
1488 ev_msg.dv[0].data_ptr = &in_arpfailure;
1489 ev_msg.dv[0].data_length =
1490 sizeof(struct
39037602
A
1491 kev_in_arpfailure);
1492 dlil_post_complete_msg(NULL, &ev_msg);
fe8ab488 1493 }
b0d623f7 1494 result = EJUSTRETURN;
fe8ab488 1495 RT_LOCK(route);
b0d623f7
A
1496 goto release;
1497 } else {
91447636 1498 route->rt_flags |= RTF_REJECT;
39236c6e
A
1499 rt_setexpire(route,
1500 route->rt_expire + arpt_down);
91447636 1501 llinfo->la_asked = 0;
6d2010ae 1502 /*
39037602
A
1503 * Remove the packet that was just added above;
1504 * don't free it since we're not returning
1505 * EJUSTRETURN. The caller will handle the
1506 * freeing. Since we haven't dropped rt_lock
1507 * from the time of _addq() above, this packet
1508 * must be at the tail.
6d2010ae 1509 */
39037602
A
1510 if (packet != NULL) {
1511 struct mbuf *_m =
1512 _getq_tail(&llinfo->la_holdq);
1513 atomic_add_32(&arpstat.held, -1);
1514 VERIFY(_m == packet);
1515 }
b0d623f7 1516 result = EHOSTUNREACH;
5ba3f43e
A
1517
1518 /*
1519 * Enqueue work item to invoke callback for this route entry
1520 */
1521 route_event_enqueue_nwk_wq_entry(route, NULL,
1522 ROUTE_LLENTRY_UNREACH, NULL, TRUE);
b0d623f7 1523 goto release;
91447636
A
1524 }
1525 }
1526 }
b0d623f7 1527
39037602 1528 /* The packet is now held inside la_holdq */
b0d623f7
A
1529 result = EJUSTRETURN;
1530
1531release:
39236c6e 1532 if (result == EHOSTUNREACH)
39037602 1533 atomic_add_32(&arpstat.dropped, 1);
39236c6e 1534
b0d623f7 1535 if (route != NULL) {
5ba3f43e
A
1536 if (send_probe_notif) {
1537 route_event_enqueue_nwk_wq_entry(route, NULL,
1538 ROUTE_LLENTRY_PROBED, NULL, TRUE);
1539
1540 if (route->rt_flags & RTF_ROUTER) {
1541 struct radix_node_head *rnh = NULL;
1542 struct route_event rt_ev;
1543 route_event_init(&rt_ev, route, NULL, ROUTE_LLENTRY_PROBED);
1544 /*
1545 * We already have a reference on rt. The function
1546 * frees it before returning.
1547 */
1548 RT_UNLOCK(route);
1549 lck_mtx_lock(rnh_lock);
1550 rnh = rt_tables[AF_INET];
1551
1552 if (rnh != NULL)
1553 (void) rnh->rnh_walktree(rnh,
1554 route_event_walktree, (void *)&rt_ev);
1555 lck_mtx_unlock(rnh_lock);
1556 RT_LOCK(route);
1557 }
1558 }
1559
b0d623f7
A
1560 if (route == hint) {
1561 RT_REMREF_LOCKED(route);
1562 RT_UNLOCK(route);
1563 } else {
1564 RT_UNLOCK(route);
1565 rtfree(route);
1566 }
1567 }
39037602
A
1568 if (probing) {
1569 /* Do this after we drop rt_lock to preserve ordering */
1570 lck_mtx_lock(rnh_lock);
1571 arp_sched_probe(NULL);
1572 lck_mtx_unlock(rnh_lock);
1573 }
b0d623f7 1574 return (result);
91447636
A
1575}
1576
1577errno_t
39236c6e
A
1578arp_ip_handle_input(ifnet_t ifp, u_short arpop,
1579 const struct sockaddr_dl *sender_hw, const struct sockaddr_in *sender_ip,
1580 const struct sockaddr_in *target_ip)
91447636 1581{
39236c6e 1582 char ipv4str[MAX_IPv4_STR_LEN];
b0d623f7
A
1583 struct sockaddr_dl proxied;
1584 struct sockaddr_dl *gateway, *target_hw = NULL;
1585 struct ifaddr *ifa;
91447636
A
1586 struct in_ifaddr *ia;
1587 struct in_ifaddr *best_ia = NULL;
6d2010ae 1588 struct sockaddr_in best_ia_sin;
91447636 1589 route_t route = NULL;
39236c6e 1590 char buf[3 * MAX_HW_LEN]; /* enough for MAX_HW_LEN byte hw address */
91447636 1591 struct llinfo_arp *llinfo;
91447636 1592 errno_t error;
2d21ac55 1593 int created_announcement = 0;
b7266188 1594 int bridged = 0, is_bridge = 0;
5ba3f43e 1595 uint32_t rt_evcode = 0;
6d2010ae 1596
39037602
A
1597 /*
1598 * Here and other places within this routine where we don't hold
1599 * rnh_lock, trade accuracy for speed for the common scenarios
1600 * and avoid the use of atomic updates.
1601 */
39236c6e
A
1602 arpstat.received++;
1603
91447636 1604 /* Do not respond to requests for 0.0.0.0 */
39236c6e 1605 if (target_ip->sin_addr.s_addr == INADDR_ANY && arpop == ARPOP_REQUEST)
b0d623f7 1606 goto done;
6d2010ae
A
1607
1608 if (ifp->if_bridge)
b7266188
A
1609 bridged = 1;
1610 if (ifp->if_type == IFT_BRIDGE)
1611 is_bridge = 1;
b0d623f7 1612
39236c6e
A
1613 if (arpop == ARPOP_REPLY)
1614 arpstat.rxreplies++;
1615
91447636
A
1616 /*
1617 * Determine if this ARP is for us
6d2010ae 1618 * For a bridge, we want to check the address irrespective
b7266188 1619 * of the receive interface.
91447636 1620 */
b0d623f7
A
1621 lck_rw_lock_shared(in_ifaddr_rwlock);
1622 TAILQ_FOREACH(ia, INADDR_HASH(target_ip->sin_addr.s_addr), ia_hash) {
6d2010ae 1623 IFA_LOCK_SPIN(&ia->ia_ifa);
b7266188 1624 if (((bridged && ia->ia_ifp->if_bridge != NULL) ||
6d2010ae 1625 (ia->ia_ifp == ifp)) &&
b0d623f7 1626 ia->ia_addr.sin_addr.s_addr == target_ip->sin_addr.s_addr) {
6d2010ae
A
1627 best_ia = ia;
1628 best_ia_sin = best_ia->ia_addr;
1629 IFA_ADDREF_LOCKED(&ia->ia_ifa);
1630 IFA_UNLOCK(&ia->ia_ifa);
1631 lck_rw_done(in_ifaddr_rwlock);
1632 goto match;
91447636 1633 }
6d2010ae 1634 IFA_UNLOCK(&ia->ia_ifa);
91447636 1635 }
b0d623f7
A
1636
1637 TAILQ_FOREACH(ia, INADDR_HASH(sender_ip->sin_addr.s_addr), ia_hash) {
6d2010ae 1638 IFA_LOCK_SPIN(&ia->ia_ifa);
b7266188 1639 if (((bridged && ia->ia_ifp->if_bridge != NULL) ||
6d2010ae 1640 (ia->ia_ifp == ifp)) &&
b0d623f7 1641 ia->ia_addr.sin_addr.s_addr == sender_ip->sin_addr.s_addr) {
6d2010ae
A
1642 best_ia = ia;
1643 best_ia_sin = best_ia->ia_addr;
1644 IFA_ADDREF_LOCKED(&ia->ia_ifa);
1645 IFA_UNLOCK(&ia->ia_ifa);
1646 lck_rw_done(in_ifaddr_rwlock);
1647 goto match;
b7266188 1648 }
6d2010ae 1649 IFA_UNLOCK(&ia->ia_ifa);
b7266188
A
1650 }
1651
39236c6e
A
1652#define BDG_MEMBER_MATCHES_ARP(addr, ifp, ia) \
1653 (ia->ia_ifp->if_bridge == ifp->if_softc && \
1654 bcmp(IF_LLADDR(ia->ia_ifp), IF_LLADDR(ifp), ifp->if_addrlen) == 0 && \
b7266188
A
1655 addr == ia->ia_addr.sin_addr.s_addr)
1656 /*
1657 * Check the case when bridge shares its MAC address with
1658 * some of its children, so packets are claimed by bridge
1659 * itself (bridge_input() does it first), but they are really
1660 * meant to be destined to the bridge member.
1661 */
1662 if (is_bridge) {
6d2010ae
A
1663 TAILQ_FOREACH(ia, INADDR_HASH(target_ip->sin_addr.s_addr),
1664 ia_hash) {
1665 IFA_LOCK_SPIN(&ia->ia_ifa);
1666 if (BDG_MEMBER_MATCHES_ARP(target_ip->sin_addr.s_addr,
1667 ifp, ia)) {
b7266188
A
1668 ifp = ia->ia_ifp;
1669 best_ia = ia;
6d2010ae
A
1670 best_ia_sin = best_ia->ia_addr;
1671 IFA_ADDREF_LOCKED(&ia->ia_ifa);
1672 IFA_UNLOCK(&ia->ia_ifa);
b7266188
A
1673 lck_rw_done(in_ifaddr_rwlock);
1674 goto match;
1675 }
6d2010ae 1676 IFA_UNLOCK(&ia->ia_ifa);
b0d623f7 1677 }
91447636 1678 }
39236c6e 1679#undef BDG_MEMBER_MATCHES_ARP
b0d623f7
A
1680 lck_rw_done(in_ifaddr_rwlock);
1681
1682 /*
1683 * No match, use the first inet address on the receive interface
1684 * as a dummy address for the rest of the function; we may be
1685 * proxying for another address.
1686 */
1687 ifnet_lock_shared(ifp);
1688 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
6d2010ae
A
1689 IFA_LOCK_SPIN(ifa);
1690 if (ifa->ifa_addr->sa_family != AF_INET) {
1691 IFA_UNLOCK(ifa);
b0d623f7 1692 continue;
6d2010ae 1693 }
b0d623f7 1694 best_ia = (struct in_ifaddr *)ifa;
6d2010ae
A
1695 best_ia_sin = best_ia->ia_addr;
1696 IFA_ADDREF_LOCKED(ifa);
1697 IFA_UNLOCK(ifa);
b7266188
A
1698 ifnet_lock_done(ifp);
1699 goto match;
b0d623f7
A
1700 }
1701 ifnet_lock_done(ifp);
1702
b7266188
A
1703 /*
1704 * If we're not a bridge member, or if we are but there's no
1705 * IPv4 address to use for the interface, drop the packet.
1706 */
1707 if (!bridged || best_ia == NULL)
b0d623f7
A
1708 goto done;
1709
1710match:
91447636 1711 /* If the packet is from this interface, ignore the packet */
39236c6e
A
1712 if (bcmp(CONST_LLADDR(sender_hw), IF_LLADDR(ifp),
1713 sender_hw->sdl_alen) == 0)
b0d623f7 1714 goto done;
b0d623f7 1715
91447636 1716 /* Check for a conflict */
39236c6e
A
1717 if (!bridged &&
1718 sender_ip->sin_addr.s_addr == best_ia_sin.sin_addr.s_addr) {
1719 struct kev_msg ev_msg;
91447636 1720 struct kev_in_collision *in_collision;
39236c6e
A
1721 u_char storage[sizeof (struct kev_in_collision) + MAX_HW_LEN];
1722
1723 bzero(&ev_msg, sizeof (struct kev_msg));
1724 bzero(storage, (sizeof (struct kev_in_collision) + MAX_HW_LEN));
1725 in_collision = (struct kev_in_collision *)(void *)storage;
1726 log(LOG_ERR, "%s duplicate IP address %s sent from "
1727 "address %s\n", if_name(ifp),
1728 inet_ntop(AF_INET, &sender_ip->sin_addr, ipv4str,
1729 sizeof (ipv4str)), sdl_addr_to_hex(sender_hw, buf,
1730 sizeof (buf)));
b0d623f7 1731
91447636
A
1732 /* Send a kernel event so anyone can learn of the conflict */
1733 in_collision->link_data.if_family = ifp->if_family;
1734 in_collision->link_data.if_unit = ifp->if_unit;
fe8ab488 1735 strlcpy(&in_collision->link_data.if_name[0],
39236c6e 1736 ifp->if_name, IFNAMSIZ);
91447636 1737 in_collision->ia_ipaddr = sender_ip->sin_addr;
39236c6e
A
1738 in_collision->hw_len = (sender_hw->sdl_alen < MAX_HW_LEN) ?
1739 sender_hw->sdl_alen : MAX_HW_LEN;
1740 bcopy(CONST_LLADDR(sender_hw), (caddr_t)in_collision->hw_addr,
1741 in_collision->hw_len);
91447636
A
1742 ev_msg.vendor_code = KEV_VENDOR_APPLE;
1743 ev_msg.kev_class = KEV_NETWORK_CLASS;
1744 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
1745 ev_msg.event_code = KEV_INET_ARPCOLLISION;
1746 ev_msg.dv[0].data_ptr = in_collision;
39236c6e
A
1747 ev_msg.dv[0].data_length =
1748 sizeof (struct kev_in_collision) + in_collision->hw_len;
91447636 1749 ev_msg.dv[1].data_length = 0;
39037602
A
1750 dlil_post_complete_msg(NULL, &ev_msg);
1751 atomic_add_32(&arpstat.dupips, 1);
91447636
A
1752 goto respond;
1753 }
b0d623f7 1754
91447636
A
1755 /*
1756 * Look up the routing entry. If it doesn't exist and we are the
c910b4d9 1757 * target, and the sender isn't 0.0.0.0, go ahead and create one.
b0d623f7
A
1758 * Callee holds a reference on the route and returns with the route
1759 * entry locked, upon success.
91447636 1760 */
c910b4d9 1761 error = arp_lookup_route(&sender_ip->sin_addr,
6d2010ae 1762 (target_ip->sin_addr.s_addr == best_ia_sin.sin_addr.s_addr &&
c910b4d9 1763 sender_ip->sin_addr.s_addr != 0), 0, &route, ifp->if_index);
b0d623f7
A
1764
1765 if (error == 0)
1766 RT_LOCK_ASSERT_HELD(route);
1767
39236c6e
A
1768 if (error || route == NULL || route->rt_gateway == NULL) {
1769 if (arpop != ARPOP_REQUEST)
2d21ac55 1770 goto respond;
39236c6e
A
1771
1772 if (arp_sendllconflict && send_conflicting_probes != 0 &&
1773 (ifp->if_eflags & IFEF_ARPLL) &&
1774 IN_LINKLOCAL(ntohl(target_ip->sin_addr.s_addr)) &&
1775 sender_ip->sin_addr.s_addr == INADDR_ANY) {
91447636 1776 /*
39236c6e
A
1777 * Verify this ARP probe doesn't conflict with
1778 * an IPv4LL we know of on another interface.
91447636 1779 */
b0d623f7
A
1780 if (route != NULL) {
1781 RT_REMREF_LOCKED(route);
1782 RT_UNLOCK(route);
1783 route = NULL;
1784 }
1785 /*
1786 * Callee holds a reference on the route and returns
1787 * with the route entry locked, upon success.
1788 */
c910b4d9
A
1789 error = arp_lookup_route(&target_ip->sin_addr, 0, 0,
1790 &route, ifp->if_index);
b0d623f7 1791
39236c6e
A
1792 if (error != 0 || route == NULL ||
1793 route->rt_gateway == NULL)
1794 goto respond;
b0d623f7 1795
39236c6e
A
1796 RT_LOCK_ASSERT_HELD(route);
1797
1798 gateway = SDL(route->rt_gateway);
1799 if (route->rt_ifp != ifp && gateway->sdl_alen != 0 &&
1800 (gateway->sdl_alen != sender_hw->sdl_alen ||
1801 bcmp(CONST_LLADDR(gateway), CONST_LLADDR(sender_hw),
1802 gateway->sdl_alen) != 0)) {
1803 /*
1804 * A node is probing for an IPv4LL we know
1805 * exists on a different interface. We respond
1806 * with a conflicting probe to force the new
1807 * device to pick a different IPv4LL address.
1808 */
1809 if (arp_verbose || log_arp_warnings) {
1810 log(LOG_INFO, "arp: %s on %s sent "
1811 "probe for %s, already on %s\n",
1812 sdl_addr_to_hex(sender_hw, buf,
1813 sizeof (buf)), if_name(ifp),
1814 inet_ntop(AF_INET,
1815 &target_ip->sin_addr, ipv4str,
1816 sizeof (ipv4str)),
1817 if_name(route->rt_ifp));
1818 log(LOG_INFO, "arp: sending "
1819 "conflicting probe to %s on %s\n",
1820 sdl_addr_to_hex(sender_hw, buf,
1821 sizeof (buf)), if_name(ifp));
6d2010ae 1822 }
39236c6e
A
1823 /* Mark use timestamp */
1824 if (route->rt_llinfo != NULL)
1825 arp_llreach_use(route->rt_llinfo);
1826 /* We're done with the route */
1827 RT_REMREF_LOCKED(route);
1828 RT_UNLOCK(route);
1829 route = NULL;
1830 /*
1831 * Send a conservative unicast "ARP probe".
1832 * This should force the other device to pick
1833 * a new number. This will not force the
1834 * device to pick a new number if the device
1835 * has already assigned that number. This will
1836 * not imply to the device that we own that
1837 * address. The link address is always
1838 * present; it's never freed.
1839 */
1840 ifnet_lock_shared(ifp);
1841 ifa = ifp->if_lladdr;
1842 IFA_ADDREF(ifa);
1843 ifnet_lock_done(ifp);
1844 dlil_send_arp_internal(ifp, ARPOP_REQUEST,
1845 SDL(ifa->ifa_addr),
1846 (const struct sockaddr *)sender_ip,
1847 sender_hw,
1848 (const struct sockaddr *)target_ip);
1849 IFA_REMREF(ifa);
1850 ifa = NULL;
39037602 1851 atomic_add_32(&arpstat.txconflicts, 1);
91447636 1852 }
2d21ac55 1853 goto respond;
39236c6e
A
1854 } else if (keep_announcements != 0 &&
1855 target_ip->sin_addr.s_addr == sender_ip->sin_addr.s_addr) {
1856 /*
1857 * Don't create entry if link-local address and
1858 * link-local is disabled
1859 */
1860 if (!IN_LINKLOCAL(ntohl(sender_ip->sin_addr.s_addr)) ||
1861 (ifp->if_eflags & IFEF_ARPLL)) {
b0d623f7
A
1862 if (route != NULL) {
1863 RT_REMREF_LOCKED(route);
1864 RT_UNLOCK(route);
1865 route = NULL;
1866 }
1867 /*
1868 * Callee holds a reference on the route and
1869 * returns with the route entry locked, upon
1870 * success.
1871 */
c910b4d9
A
1872 error = arp_lookup_route(&sender_ip->sin_addr,
1873 1, 0, &route, ifp->if_index);
b0d623f7
A
1874
1875 if (error == 0)
1876 RT_LOCK_ASSERT_HELD(route);
1877
39236c6e
A
1878 if (error == 0 && route != NULL &&
1879 route->rt_gateway != NULL)
2d21ac55 1880 created_announcement = 1;
2d21ac55 1881 }
39236c6e 1882 if (created_announcement == 0)
2d21ac55 1883 goto respond;
2d21ac55
A
1884 } else {
1885 goto respond;
91447636 1886 }
91447636 1887 }
b0d623f7
A
1888
1889 RT_LOCK_ASSERT_HELD(route);
6d2010ae
A
1890 VERIFY(route->rt_expire == 0 || route->rt_rmx.rmx_expire != 0);
1891 VERIFY(route->rt_expire != 0 || route->rt_rmx.rmx_expire == 0);
39236c6e 1892
91447636 1893 gateway = SDL(route->rt_gateway);
b7266188 1894 if (!bridged && route->rt_ifp != ifp) {
39236c6e
A
1895 if (!IN_LINKLOCAL(ntohl(sender_ip->sin_addr.s_addr)) ||
1896 !(ifp->if_eflags & IFEF_ARPLL)) {
1897 if (arp_verbose || log_arp_warnings)
1898 log(LOG_ERR, "arp: %s is on %s but got "
1899 "reply from %s on %s\n",
1900 inet_ntop(AF_INET, &sender_ip->sin_addr,
1901 ipv4str, sizeof (ipv4str)),
1902 if_name(route->rt_ifp),
1903 sdl_addr_to_hex(sender_hw, buf,
1904 sizeof (buf)), if_name(ifp));
91447636 1905 goto respond;
39236c6e 1906 } else {
91447636 1907 /* Don't change a permanent address */
39236c6e 1908 if (route->rt_expire == 0)
91447636 1909 goto respond;
b0d623f7
A
1910
1911 /*
1912 * We're about to check and/or change the route's ifp
1913 * and ifa, so do the lock dance: drop rt_lock, hold
1914 * rnh_lock and re-hold rt_lock to avoid violating the
1915 * lock ordering. We have an extra reference on the
1916 * route, so it won't go away while we do this.
1917 */
1918 RT_UNLOCK(route);
1919 lck_mtx_lock(rnh_lock);
1920 RT_LOCK(route);
91447636 1921 /*
b0d623f7
A
1922 * Don't change the cloned route away from the
1923 * parent's interface if the address did resolve
1924 * or if the route is defunct. rt_ifp on both
1925 * the parent and the clone can now be freely
1926 * accessed now that we have acquired rnh_lock.
91447636 1927 */
b0d623f7 1928 gateway = SDL(route->rt_gateway);
39236c6e
A
1929 if ((gateway->sdl_alen != 0 &&
1930 route->rt_parent != NULL &&
b0d623f7
A
1931 route->rt_parent->rt_ifp == route->rt_ifp) ||
1932 (route->rt_flags & RTF_CONDEMNED)) {
1933 RT_REMREF_LOCKED(route);
1934 RT_UNLOCK(route);
1935 route = NULL;
1936 lck_mtx_unlock(rnh_lock);
91447636
A
1937 goto respond;
1938 }
6d2010ae
A
1939 if (route->rt_ifp != ifp) {
1940 /*
1941 * Purge any link-layer info caching.
1942 */
1943 if (route->rt_llinfo_purge != NULL)
1944 route->rt_llinfo_purge(route);
1945
1946 /* Adjust route ref count for the interfaces */
1947 if (route->rt_if_ref_fn != NULL) {
1948 route->rt_if_ref_fn(ifp, 1);
1949 route->rt_if_ref_fn(route->rt_ifp, -1);
1950 }
d1ecb069 1951 }
91447636
A
1952 /* Change the interface when the existing route is on */
1953 route->rt_ifp = ifp;
39236c6e
A
1954 /*
1955 * If rmx_mtu is not locked, update it
1956 * to the MTU used by the new interface.
1957 */
1958 if (!(route->rt_rmx.rmx_locks & RTV_MTU))
1959 route->rt_rmx.rmx_mtu = route->rt_ifp->if_mtu;
1960
91447636
A
1961 rtsetifa(route, &best_ia->ia_ifa);
1962 gateway->sdl_index = ifp->if_index;
b0d623f7
A
1963 RT_UNLOCK(route);
1964 lck_mtx_unlock(rnh_lock);
1965 RT_LOCK(route);
1966 /* Don't bother if the route is down */
1967 if (!(route->rt_flags & RTF_UP))
1968 goto respond;
1969 /* Refresh gateway pointer */
1970 gateway = SDL(route->rt_gateway);
91447636 1971 }
b0d623f7 1972 RT_LOCK_ASSERT_HELD(route);
91447636 1973 }
b0d623f7 1974
39236c6e
A
1975 if (gateway->sdl_alen != 0 && bcmp(LLADDR(gateway),
1976 CONST_LLADDR(sender_hw), gateway->sdl_alen) != 0) {
1977 if (route->rt_expire != 0 &&
1978 (arp_verbose || log_arp_warnings)) {
91447636 1979 char buf2[3 * MAX_HW_LEN];
39236c6e 1980 log(LOG_INFO, "arp: %s moved from %s to %s on %s\n",
2d21ac55 1981 inet_ntop(AF_INET, &sender_ip->sin_addr, ipv4str,
39236c6e
A
1982 sizeof (ipv4str)),
1983 sdl_addr_to_hex(gateway, buf, sizeof (buf)),
1984 sdl_addr_to_hex(sender_hw, buf2, sizeof (buf2)),
1985 if_name(ifp));
1986 } else if (route->rt_expire == 0) {
1987 if (arp_verbose || log_arp_warnings) {
2d21ac55 1988 log(LOG_ERR, "arp: %s attempts to modify "
39236c6e 1989 "permanent entry for %s on %s\n",
2d21ac55 1990 sdl_addr_to_hex(sender_hw, buf,
39236c6e 1991 sizeof (buf)),
2d21ac55 1992 inet_ntop(AF_INET, &sender_ip->sin_addr,
39236c6e
A
1993 ipv4str, sizeof (ipv4str)),
1994 if_name(ifp));
2d21ac55 1995 }
91447636
A
1996 goto respond;
1997 }
1998 }
b0d623f7 1999
91447636
A
2000 /* Copy the sender hardware address in to the route's gateway address */
2001 gateway->sdl_alen = sender_hw->sdl_alen;
2002 bcopy(CONST_LLADDR(sender_hw), LLADDR(gateway), gateway->sdl_alen);
b0d623f7 2003
91447636 2004 /* Update the expire time for the route and clear the reject flag */
39236c6e
A
2005 if (route->rt_expire != 0)
2006 rt_setexpire(route, net_uptime() + arpt_keep);
91447636 2007 route->rt_flags &= ~RTF_REJECT;
b0d623f7 2008
6d2010ae
A
2009 /* cache the gateway (sender HW) address */
2010 arp_llreach_alloc(route, ifp, LLADDR(gateway), gateway->sdl_alen,
5ba3f43e 2011 (arpop == ARPOP_REPLY), &rt_evcode);
6d2010ae 2012
b0d623f7 2013 llinfo = route->rt_llinfo;
fe8ab488
A
2014 /* send a notification that the route is back up */
2015 if (ifp->if_addrlen == IF_LLREACH_MAXLEN &&
39037602 2016 route->rt_flags & RTF_ROUTER &&
fe8ab488
A
2017 llinfo->la_flags & LLINFO_RTRFAIL_EVTSENT) {
2018 struct kev_msg ev_msg;
3e170ce0 2019 struct kev_in_arpalive in_arpalive;
fe8ab488
A
2020
2021 llinfo->la_flags &= ~LLINFO_RTRFAIL_EVTSENT;
2022 RT_UNLOCK(route);
2023 bzero(&ev_msg, sizeof(ev_msg));
2024 bzero(&in_arpalive, sizeof(in_arpalive));
2025 in_arpalive.link_data.if_family = ifp->if_family;
2026 in_arpalive.link_data.if_unit = ifp->if_unit;
2027 strlcpy(in_arpalive.link_data.if_name, ifp->if_name, IFNAMSIZ);
2028 ev_msg.vendor_code = KEV_VENDOR_APPLE;
2029 ev_msg.kev_class = KEV_NETWORK_CLASS;
2030 ev_msg.kev_subclass = KEV_INET_SUBCLASS;
2031 ev_msg.event_code = KEV_INET_ARPRTRALIVE;
2032 ev_msg.dv[0].data_ptr = &in_arpalive;
39037602
A
2033 ev_msg.dv[0].data_length = sizeof(struct kev_in_arpalive);
2034 dlil_post_complete_msg(NULL, &ev_msg);
fe8ab488
A
2035 RT_LOCK(route);
2036 }
39037602 2037 /* Update the llinfo, send out all queued packets at once */
91447636 2038 llinfo->la_asked = 0;
39037602 2039 llinfo->la_flags &= ~LLINFO_PROBING;
5ba3f43e
A
2040 llinfo->la_prbreq_cnt = 0;
2041
2042 if (rt_evcode) {
2043 /*
2044 * Enqueue work item to invoke callback for this route entry
2045 */
2046 route_event_enqueue_nwk_wq_entry(route, NULL, rt_evcode, NULL, TRUE);
2047
2048 if (route->rt_flags & RTF_ROUTER) {
2049 struct radix_node_head *rnh = NULL;
2050 struct route_event rt_ev;
2051 route_event_init(&rt_ev, route, NULL, rt_evcode);
2052 /*
2053 * We already have a reference on rt. The function
2054 * frees it before returning.
2055 */
2056 RT_UNLOCK(route);
2057 lck_mtx_lock(rnh_lock);
2058 rnh = rt_tables[AF_INET];
2059
2060 if (rnh != NULL)
2061 (void) rnh->rnh_walktree(rnh, route_event_walktree,
2062 (void *)&rt_ev);
2063 lck_mtx_unlock(rnh_lock);
2064 RT_LOCK(route);
2065 }
2066 }
2067
39037602
A
2068 if (!qempty(&llinfo->la_holdq)) {
2069 uint32_t held;
2070 struct mbuf *m0 =
2071 _getq_all(&llinfo->la_holdq, NULL, &held, NULL);
2072 if (arp_verbose) {
2073 log(LOG_DEBUG, "%s: sending %u held packets\n",
2074 __func__, held);
2075 }
2076 atomic_add_32(&arpstat.held, -held);
2077 VERIFY(qempty(&llinfo->la_holdq));
b0d623f7 2078 RT_UNLOCK(route);
39236c6e
A
2079 dlil_output(ifp, PF_INET, m0, (caddr_t)route,
2080 rt_key(route), 0, NULL);
b0d623f7
A
2081 RT_REMREF(route);
2082 route = NULL;
91447636 2083 }
b0d623f7 2084
91447636 2085respond:
b0d623f7 2086 if (route != NULL) {
6d2010ae
A
2087 /* Mark use timestamp if we're going to send a reply */
2088 if (arpop == ARPOP_REQUEST && route->rt_llinfo != NULL)
2089 arp_llreach_use(route->rt_llinfo);
b0d623f7
A
2090 RT_REMREF_LOCKED(route);
2091 RT_UNLOCK(route);
2092 route = NULL;
91447636 2093 }
b0d623f7
A
2094
2095 if (arpop != ARPOP_REQUEST)
2096 goto done;
2097
39037602 2098 /* See comments at the beginning of this routine */
39236c6e
A
2099 arpstat.rxrequests++;
2100
91447636 2101 /* If we are not the target, check if we should proxy */
6d2010ae 2102 if (target_ip->sin_addr.s_addr != best_ia_sin.sin_addr.s_addr) {
b0d623f7
A
2103 /*
2104 * Find a proxy route; callee holds a reference on the
2105 * route and returns with the route entry locked, upon
2106 * success.
2107 */
c910b4d9
A
2108 error = arp_lookup_route(&target_ip->sin_addr, 0, SIN_PROXY,
2109 &route, ifp->if_index);
b0d623f7
A
2110
2111 if (error == 0) {
2112 RT_LOCK_ASSERT_HELD(route);
b7266188
A
2113 /*
2114 * Return proxied ARP replies only on the interface
2115 * or bridge cluster where this network resides.
2116 * Otherwise we may conflict with the host we are
2117 * proxying for.
2118 */
2119 if (route->rt_ifp != ifp &&
39236c6e
A
2120 (route->rt_ifp->if_bridge != ifp->if_bridge ||
2121 ifp->if_bridge == NULL)) {
2122 RT_REMREF_LOCKED(route);
2123 RT_UNLOCK(route);
2124 goto done;
2125 }
b0d623f7
A
2126 proxied = *SDL(route->rt_gateway);
2127 target_hw = &proxied;
2128 } else {
2129 /*
2130 * We don't have a route entry indicating we should
2131 * use proxy. If we aren't supposed to proxy all,
2132 * we are done.
2133 */
2134 if (!arp_proxyall)
2135 goto done;
2136
2137 /*
2138 * See if we have a route to the target ip before
2139 * we proxy it.
2140 */
2141 route = rtalloc1_scoped((struct sockaddr *)
2142 (size_t)target_ip, 0, 0, ifp->if_index);
2143 if (!route)
2144 goto done;
2145
91447636
A
2146 /*
2147 * Don't proxy for hosts already on the same interface.
2148 */
b0d623f7 2149 RT_LOCK(route);
91447636 2150 if (route->rt_ifp == ifp) {
b0d623f7
A
2151 RT_UNLOCK(route);
2152 rtfree(route);
2153 goto done;
91447636
A
2154 }
2155 }
6d2010ae
A
2156 /* Mark use timestamp */
2157 if (route->rt_llinfo != NULL)
2158 arp_llreach_use(route->rt_llinfo);
b0d623f7
A
2159 RT_REMREF_LOCKED(route);
2160 RT_UNLOCK(route);
91447636 2161 }
b0d623f7
A
2162
2163 dlil_send_arp(ifp, ARPOP_REPLY,
39236c6e
A
2164 target_hw, (const struct sockaddr *)target_ip,
2165 sender_hw, (const struct sockaddr *)sender_ip, 0);
b0d623f7
A
2166
2167done:
2168 if (best_ia != NULL)
6d2010ae 2169 IFA_REMREF(&best_ia->ia_ifa);
39236c6e 2170 return (0);
91447636
A
2171}
2172
2173void
6d2010ae 2174arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
91447636 2175{
6d2010ae
A
2176 struct sockaddr *sa;
2177
2178 IFA_LOCK(ifa);
91447636
A
2179 ifa->ifa_rtrequest = arp_rtrequest;
2180 ifa->ifa_flags |= RTF_CLONING;
6d2010ae
A
2181 sa = ifa->ifa_addr;
2182 IFA_UNLOCK(ifa);
316670eb 2183 dlil_send_arp(ifp, ARPOP_REQUEST, NULL, sa, NULL, sa, 0);
91447636 2184}
39236c6e
A
2185
2186static int
2187arp_getstat SYSCTL_HANDLER_ARGS
2188{
2189#pragma unused(oidp, arg1, arg2)
2190 if (req->oldptr == USER_ADDR_NULL)
2191 req->oldlen = (size_t)sizeof (struct arpstat);
2192
2193 return (SYSCTL_OUT(req, &arpstat, MIN(sizeof (arpstat), req->oldlen)));
2194}