xref: /netbsd-src/sys/net/if_llatbl.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /*	$NetBSD: if_llatbl.c,v 1.22 2017/11/10 07:24:28 ozaki-r Exp $	*/
2 /*
3  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
4  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
5  * Copyright (c) 2008 Kip Macy. All rights reserved.
6  * Copyright (c) 2015 The NetBSD Foundation, Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 #include <sys/cdefs.h>
31 
32 #ifdef _KERNEL_OPT
33 #include "opt_ddb.h"
34 #include "opt_inet.h"
35 #include "opt_inet6.h"
36 #include "opt_net_mpsafe.h"
37 #endif
38 
39 #include "arp.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/syslog.h>
46 #include <sys/sysctl.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/kernel.h>
50 #include <sys/lock.h>
51 #include <sys/mutex.h>
52 #include <sys/rwlock.h>
53 
54 #ifdef DDB
55 #include <ddb/ddb.h>
56 #endif
57 
58 #include <netinet/in.h>
59 #include <net/if_llatbl.h>
60 #include <net/if.h>
61 #include <net/if_dl.h>
62 #include <net/route.h>
63 #include <netinet/if_inarp.h>
64 #include <netinet/in_var.h>
65 #include <netinet6/in6_var.h>
66 #include <netinet6/nd6.h>
67 
68 static SLIST_HEAD(, lltable) lltables;
69 krwlock_t lltable_rwlock;
70 
71 static void lltable_unlink(struct lltable *llt);
72 static void llentries_unlink(struct lltable *llt, struct llentries *head);
73 
74 static void htable_unlink_entry(struct llentry *lle);
75 static void htable_link_entry(struct lltable *llt, struct llentry *lle);
76 static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
77     void *farg);
78 
79 int
80 lltable_dump_entry(struct lltable *llt, struct llentry *lle,
81     struct rt_walkarg *w, struct sockaddr *sa)
82 {
83 #define RTF_LLINFO	0x400
84 #define RTF_CLONED	0x2000
85 	struct ifnet *ifp = llt->llt_ifp;
86 	int error;
87 	void *a;
88 	struct sockaddr_dl sdl;
89 	int size;
90 	struct rt_addrinfo info;
91 
92 	memset(&info, 0, sizeof(info));
93 	info.rti_info[RTAX_DST] = sa;
94 
95 	a = (lle->la_flags & LLE_VALID) == LLE_VALID ? &lle->ll_addr : NULL;
96 	if (sockaddr_dl_init(&sdl, sizeof(sdl), ifp->if_index, ifp->if_type,
97 	    NULL, 0, a, ifp->if_addrlen) == NULL)
98 		return EINVAL;
99 
100 	info.rti_info[RTAX_GATEWAY] = sstocsa(&sdl);
101 	if (sa->sa_family == AF_INET && lle->la_flags & LLE_PUB) {
102 		struct sockaddr_inarp *sin;
103 		sin = (struct sockaddr_inarp *)sa;
104 		sin->sin_other = SIN_PROXY;
105 	}
106 	if ((error = rt_msg3(RTM_GET, &info, 0, w, &size)))
107 		return error;
108 	if (w->w_where && w->w_tmem && w->w_needed <= 0) {
109 		struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
110 
111 		/* Need to copy by myself */
112 		rtm->rtm_index = ifp->if_index;
113 		rtm->rtm_rmx.rmx_mtu = 0;
114 		rtm->rtm_rmx.rmx_expire =
115 		    (lle->la_flags & LLE_STATIC) ? 0 : lle->la_expire;
116 		rtm->rtm_flags = RTF_UP;
117 		rtm->rtm_flags |= RTF_HOST; /* For ndp */
118 		/* For backward compatibility */
119 		rtm->rtm_flags |= RTF_LLINFO | RTF_CLONED;
120 		rtm->rtm_flags |= (lle->la_flags & LLE_STATIC) ? RTF_STATIC : 0;
121 		if (lle->la_flags & LLE_PUB)
122 			rtm->rtm_flags |= RTF_ANNOUNCE;
123 		rtm->rtm_addrs = info.rti_addrs;
124 		if ((error = copyout(rtm, w->w_where, size)) != 0)
125 			w->w_where = NULL;
126 		else
127 			w->w_where = (char *)w->w_where + size;
128 	}
129 
130 	return error;
131 #undef RTF_LLINFO
132 #undef RTF_CLONED
133 }
134 
135 /*
136  * Dump lle state for a specific address family.
137  */
138 static int
139 lltable_dump_af(struct lltable *llt, struct rt_walkarg *w)
140 {
141 	int error;
142 
143 	LLTABLE_LOCK_ASSERT();
144 
145 	if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
146 		return (0);
147 	error = 0;
148 
149 	IF_AFDATA_RLOCK(llt->llt_ifp);
150 	error = lltable_foreach_lle(llt,
151 	    (llt_foreach_cb_t *)llt->llt_dump_entry, w);
152 	IF_AFDATA_RUNLOCK(llt->llt_ifp);
153 
154 	return (error);
155 }
156 
157 /*
158  * Dump arp state for a specific address family.
159  */
160 int
161 lltable_sysctl_dump(int af, struct rt_walkarg *w)
162 {
163 	struct lltable *llt;
164 	int error = 0;
165 
166 	LLTABLE_RLOCK();
167 	SLIST_FOREACH(llt, &lltables, llt_link) {
168 		if (llt->llt_af == af) {
169 			error = lltable_dump_af(llt, w);
170 			if (error != 0)
171 				goto done;
172 		}
173 	}
174 done:
175 	LLTABLE_RUNLOCK();
176 	return (error);
177 }
178 
179 /*
180  * Common function helpers for chained hash table.
181  */
182 
183 /*
184  * Runs specified callback for each entry in @llt.
185  * Caller does the locking.
186  *
187  */
188 static int
189 htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
190 {
191 	struct llentry *lle, *next;
192 	int i, error;
193 
194 	error = 0;
195 
196 	for (i = 0; i < llt->llt_hsize; i++) {
197 		LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
198 			error = f(llt, lle, farg);
199 			if (error != 0)
200 				break;
201 		}
202 	}
203 
204 	return (error);
205 }
206 
207 static void
208 htable_link_entry(struct lltable *llt, struct llentry *lle)
209 {
210 	struct llentries *lleh;
211 	uint32_t hashidx;
212 
213 	if ((lle->la_flags & LLE_LINKED) != 0)
214 		return;
215 
216 	IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
217 
218 	hashidx = llt->llt_hash(lle, llt->llt_hsize);
219 	lleh = &llt->lle_head[hashidx];
220 
221 	lle->lle_tbl  = llt;
222 	lle->lle_head = lleh;
223 	lle->la_flags |= LLE_LINKED;
224 	LIST_INSERT_HEAD(lleh, lle, lle_next);
225 
226 	llt->llt_lle_count++;
227 }
228 
229 static void
230 htable_unlink_entry(struct llentry *lle)
231 {
232 
233 	if ((lle->la_flags & LLE_LINKED) != 0) {
234 		IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
235 		LIST_REMOVE(lle, lle_next);
236 		lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
237 #if 0
238 		lle->lle_tbl = NULL;
239 		lle->lle_head = NULL;
240 #endif
241 		KASSERT(lle->lle_tbl->llt_lle_count != 0);
242 		lle->lle_tbl->llt_lle_count--;
243 	}
244 }
245 
246 struct prefix_match_data {
247 	const struct sockaddr *prefix;
248 	const struct sockaddr *mask;
249 	struct llentries dchain;
250 	u_int flags;
251 };
252 
253 static int
254 htable_prefix_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
255 {
256 	struct prefix_match_data *pmd;
257 
258 	pmd = (struct prefix_match_data *)farg;
259 
260 	if (llt->llt_match_prefix(pmd->prefix, pmd->mask, pmd->flags, lle)) {
261 		LLE_WLOCK(lle);
262 		LIST_INSERT_HEAD(&pmd->dchain, lle, lle_chain);
263 	}
264 
265 	return (0);
266 }
267 
268 static void
269 htable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
270     const struct sockaddr *mask, u_int flags)
271 {
272 	struct llentry *lle, *next;
273 	struct prefix_match_data pmd;
274 
275 	memset(&pmd, 0, sizeof(pmd));
276 	pmd.prefix = prefix;
277 	pmd.mask = mask;
278 	pmd.flags = flags;
279 	LIST_INIT(&pmd.dchain);
280 
281 	IF_AFDATA_WLOCK(llt->llt_ifp);
282 	/* Push matching lles to chain */
283 	lltable_foreach_lle(llt, htable_prefix_free_cb, &pmd);
284 
285 	llentries_unlink(llt, &pmd.dchain);
286 	IF_AFDATA_WUNLOCK(llt->llt_ifp);
287 
288 	LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next)
289 		llt->llt_free_entry(llt, lle);
290 }
291 
292 static void
293 htable_free_tbl(struct lltable *llt)
294 {
295 
296 	free(llt->lle_head, M_LLTABLE);
297 	free(llt, M_LLTABLE);
298 }
299 
300 static void
301 llentries_unlink(struct lltable *llt, struct llentries *head)
302 {
303 	struct llentry *lle, *next;
304 
305 	LIST_FOREACH_SAFE(lle, head, lle_chain, next)
306 		llt->llt_unlink_entry(lle);
307 }
308 
309 /*
310  * Helper function used to drop all mbufs in hold queue.
311  *
312  * Returns the number of held packets, if any, that were dropped.
313  */
314 size_t
315 lltable_drop_entry_queue(struct llentry *lle)
316 {
317 	size_t pkts_dropped;
318 	struct mbuf *next;
319 
320 	LLE_WLOCK_ASSERT(lle);
321 
322 	pkts_dropped = 0;
323 	while ((lle->la_numheld > 0) && (lle->la_hold != NULL)) {
324 		next = lle->la_hold->m_nextpkt;
325 		m_freem(lle->la_hold);
326 		lle->la_hold = next;
327 		lle->la_numheld--;
328 		pkts_dropped++;
329 	}
330 
331 	KASSERTMSG(lle->la_numheld == 0,
332 		"la_numheld %d > 0, pkts_droped %zd",
333 		 lle->la_numheld, pkts_dropped);
334 
335 	return (pkts_dropped);
336 }
337 
338 /*
339  * Deletes an address from the address table.
340  * This function is called by the timer functions
341  * such as arptimer() and nd6_llinfo_timer(), and
342  * the caller does the locking.
343  *
344  * Returns the number of held packets, if any, that were dropped.
345  */
346 size_t
347 llentry_free(struct llentry *lle)
348 {
349 	struct lltable *llt;
350 	size_t pkts_dropped;
351 
352 	LLE_WLOCK_ASSERT(lle);
353 
354 	if ((lle->la_flags & LLE_LINKED) != 0) {
355 		llt = lle->lle_tbl;
356 
357 		IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
358 		llt->llt_unlink_entry(lle);
359 	}
360 
361 	pkts_dropped = lltable_drop_entry_queue(lle);
362 
363 	LLE_FREE_LOCKED(lle);
364 
365 	return (pkts_dropped);
366 }
367 
368 /*
369  * (al)locate an llentry for address dst (equivalent to rtalloc for new-arp).
370  *
371  * If found the llentry * is returned referenced and unlocked.
372  */
373 struct llentry *
374 llentry_alloc(struct ifnet *ifp, struct lltable *lt,
375     struct sockaddr_storage *dst)
376 {
377 	struct llentry *la;
378 
379 	IF_AFDATA_RLOCK(ifp);
380 	la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
381 	IF_AFDATA_RUNLOCK(ifp);
382 	if ((la == NULL) &&
383 #ifdef __FreeBSD__
384 	    (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
385 #else /* XXX */
386 	    (ifp->if_flags & IFF_NOARP) == 0) {
387 #endif
388 		IF_AFDATA_WLOCK(ifp);
389 		la = lla_create(lt, 0, (struct sockaddr *)dst, NULL /* XXX */);
390 		IF_AFDATA_WUNLOCK(ifp);
391 	}
392 
393 	if (la != NULL) {
394 		LLE_ADDREF(la);
395 		LLE_WUNLOCK(la);
396 	}
397 
398 	return (la);
399 }
400 
401 /*
402  * Free all entries from given table and free itself.
403  */
404 
405 static int
406 lltable_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
407 {
408 	struct llentries *dchain;
409 
410 	dchain = (struct llentries *)farg;
411 
412 	LLE_WLOCK(lle);
413 	LIST_INSERT_HEAD(dchain, lle, lle_chain);
414 
415 	return (0);
416 }
417 
418 /*
419  * Free all entries from given table.
420  */
421 void
422 lltable_purge_entries(struct lltable *llt)
423 {
424 	struct llentry *lle, *next;
425 	struct llentries dchain;
426 
427 	KASSERTMSG(llt != NULL, "llt is NULL");
428 
429 	LIST_INIT(&dchain);
430 	IF_AFDATA_WLOCK(llt->llt_ifp);
431 	/* Push all lles to @dchain */
432 	lltable_foreach_lle(llt, lltable_free_cb, &dchain);
433 	llentries_unlink(llt, &dchain);
434 	IF_AFDATA_WUNLOCK(llt->llt_ifp);
435 
436 	LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
437 		/*
438 		 * We need to release the lock here to lle_timer proceeds;
439 		 * lle_timer should stop immediately if LLE_LINKED isn't set.
440 		 * Note that we cannot pass lle->lle_lock to callout_halt
441 		 * because it's a rwlock.
442 		 */
443 		LLE_ADDREF(lle);
444 		LLE_WUNLOCK(lle);
445 #ifdef NET_MPSAFE
446 		callout_halt(&lle->la_timer, NULL);
447 #else
448 		if (mutex_owned(softnet_lock))
449 			callout_halt(&lle->la_timer, softnet_lock);
450 		else
451 			callout_halt(&lle->la_timer, NULL);
452 #endif
453 		LLE_WLOCK(lle);
454 		LLE_REMREF(lle);
455 		llentry_free(lle);
456 	}
457 
458 }
459 
460 /*
461  * Free all entries from given table and free itself.
462  */
463 void
464 lltable_free(struct lltable *llt)
465 {
466 
467 	KASSERTMSG(llt != NULL, "llt is NULL");
468 
469 	lltable_unlink(llt);
470 	lltable_purge_entries(llt);
471 	llt->llt_free_tbl(llt);
472 }
473 
474 void
475 lltable_drain(int af)
476 {
477 	struct lltable	*llt;
478 	struct llentry	*lle;
479 	register int i;
480 
481 	LLTABLE_RLOCK();
482 	SLIST_FOREACH(llt, &lltables, llt_link) {
483 		if (llt->llt_af != af)
484 			continue;
485 
486 		for (i=0; i < llt->llt_hsize; i++) {
487 			LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
488 				LLE_WLOCK(lle);
489 				lltable_drop_entry_queue(lle);
490 				LLE_WUNLOCK(lle);
491 			}
492 		}
493 	}
494 	LLTABLE_RUNLOCK();
495 }
496 
497 void
498 lltable_prefix_free(const int af, const struct sockaddr *prefix,
499     const struct sockaddr *mask, const u_int flags)
500 {
501 	struct lltable *llt;
502 
503 	LLTABLE_RLOCK();
504 	SLIST_FOREACH(llt, &lltables, llt_link) {
505 		if (llt->llt_af != af)
506 			continue;
507 
508 		llt->llt_prefix_free(llt, prefix, mask, flags);
509 	}
510 	LLTABLE_RUNLOCK();
511 }
512 
513 struct lltable *
514 lltable_allocate_htbl(uint32_t hsize)
515 {
516 	struct lltable *llt;
517 	int i;
518 
519 	llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
520 	llt->llt_hsize = hsize;
521 	llt->lle_head = malloc(sizeof(struct llentries) * hsize,
522 	    M_LLTABLE, M_WAITOK | M_ZERO);
523 
524 	for (i = 0; i < llt->llt_hsize; i++)
525 		LIST_INIT(&llt->lle_head[i]);
526 
527 	/* Set some default callbacks */
528 	llt->llt_link_entry = htable_link_entry;
529 	llt->llt_unlink_entry = htable_unlink_entry;
530 	llt->llt_prefix_free = htable_prefix_free;
531 	llt->llt_foreach_entry = htable_foreach_lle;
532 
533 	llt->llt_free_tbl = htable_free_tbl;
534 
535 	return (llt);
536 }
537 
538 /*
539  * Links lltable to global llt list.
540  */
541 void
542 lltable_link(struct lltable *llt)
543 {
544 
545 	LLTABLE_WLOCK();
546 	SLIST_INSERT_HEAD(&lltables, llt, llt_link);
547 	LLTABLE_WUNLOCK();
548 }
549 
550 static void
551 lltable_unlink(struct lltable *llt)
552 {
553 
554 	LLTABLE_WLOCK();
555 	SLIST_REMOVE(&lltables, llt, lltable, llt_link);
556 	LLTABLE_WUNLOCK();
557 
558 }
559 
560 /*
561  * External methods used by lltable consumers
562  */
563 
564 int
565 lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
566 {
567 
568 	return (llt->llt_foreach_entry(llt, f, farg));
569 }
570 
571 void
572 lltable_link_entry(struct lltable *llt, struct llentry *lle)
573 {
574 
575 	llt->llt_link_entry(llt, lle);
576 }
577 
578 void
579 lltable_unlink_entry(struct lltable *llt, struct llentry *lle)
580 {
581 
582 	llt->llt_unlink_entry(lle);
583 }
584 
585 void
586 lltable_free_entry(struct lltable *llt, struct llentry *lle)
587 {
588 
589 	llt->llt_free_entry(llt, lle);
590 }
591 
592 void
593 lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
594 {
595 	struct lltable *llt;
596 
597 	llt = lle->lle_tbl;
598 	llt->llt_fill_sa_entry(lle, sa);
599 }
600 
601 struct ifnet *
602 lltable_get_ifp(const struct lltable *llt)
603 {
604 
605 	return (llt->llt_ifp);
606 }
607 
608 int
609 lltable_get_af(const struct lltable *llt)
610 {
611 
612 	return (llt->llt_af);
613 }
614 
615 /*
616  * Called in route_output when rtm_flags contains RTF_LLDATA.
617  */
618 int
619 lla_rt_output(const u_char rtm_type, const int rtm_flags, const time_t rtm_expire,
620     struct rt_addrinfo *info, int sdl_index)
621 {
622 	const struct sockaddr_dl *dl = satocsdl(info->rti_info[RTAX_GATEWAY]);
623 	const struct sockaddr *dst = info->rti_info[RTAX_DST];
624 	struct ifnet *ifp;
625 	struct lltable *llt;
626 	struct llentry *lle;
627 	u_int laflags;
628 	int error;
629 	struct psref psref;
630 	int bound;
631 
632 	KASSERTMSG(dl != NULL && dl->sdl_family == AF_LINK, "invalid dl");
633 
634 	bound = curlwp_bind();
635 	if (sdl_index != 0)
636 		ifp = if_get_byindex(sdl_index, &psref);
637 	else
638 		ifp = if_get_byindex(dl->sdl_index, &psref);
639 	if (ifp == NULL) {
640 		curlwp_bindx(bound);
641 		log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n",
642 		    __func__, sdl_index != 0 ? sdl_index : dl->sdl_index);
643 		return EINVAL;
644 	}
645 
646 	/* XXX linked list may be too expensive */
647 	LLTABLE_RLOCK();
648 	SLIST_FOREACH(llt, &lltables, llt_link) {
649 		if (llt->llt_af == dst->sa_family &&
650 		    llt->llt_ifp == ifp)
651 			break;
652 	}
653 	LLTABLE_RUNLOCK();
654 	KASSERTMSG(llt != NULL, "Yep, ugly hacks are bad");
655 
656 	error = 0;
657 
658 	switch (rtm_type) {
659 	case RTM_ADD: {
660 		struct rtentry *rt;
661 
662 		/* Never call rtalloc1 with IF_AFDATA_WLOCK */
663 		rt = rtalloc1(dst, 0);
664 
665 		/* Add static LLE */
666 		IF_AFDATA_WLOCK(ifp);
667 		lle = lla_lookup(llt, 0, dst);
668 
669 		/* Cannot overwrite an existing static entry */
670 		if (lle != NULL &&
671 		    (lle->la_flags & LLE_STATIC || lle->la_expire == 0)) {
672 			LLE_RUNLOCK(lle);
673 			IF_AFDATA_WUNLOCK(ifp);
674 			if (rt != NULL)
675 				rt_unref(rt);
676 			error = EEXIST;
677 			goto out;
678 		}
679 		if (lle != NULL)
680 			LLE_RUNLOCK(lle);
681 
682 		lle = lla_create(llt, 0, dst, rt);
683 		if (lle == NULL) {
684 			IF_AFDATA_WUNLOCK(ifp);
685 			if (rt != NULL)
686 				rt_unref(rt);
687 			error = ENOMEM;
688 			goto out;
689 		}
690 
691 		KASSERT(ifp->if_addrlen <= sizeof(lle->ll_addr));
692 		memcpy(&lle->ll_addr, CLLADDR(dl), ifp->if_addrlen);
693 		if ((rtm_flags & RTF_ANNOUNCE))
694 			lle->la_flags |= LLE_PUB;
695 		lle->la_flags |= LLE_VALID;
696 #ifdef INET6
697 		/*
698 		 * ND6
699 		 */
700 		if (dst->sa_family == AF_INET6)
701 			lle->ln_state = ND6_LLINFO_REACHABLE;
702 #endif
703 		/*
704 		 * NB: arp and ndp always set (RTF_STATIC | RTF_HOST)
705 		 */
706 
707 		if (rtm_expire == 0) {
708 			lle->la_flags |= LLE_STATIC;
709 			lle->la_expire = 0;
710 		} else
711 			lle->la_expire = rtm_expire;
712 		laflags = lle->la_flags;
713 		LLE_WUNLOCK(lle);
714 		IF_AFDATA_WUNLOCK(ifp);
715 		if (rt != NULL)
716 			rt_unref(rt);
717 #if defined(INET) && NARP > 0
718 		/* gratuitous ARP */
719 		if ((laflags & LLE_PUB) && dst->sa_family == AF_INET) {
720 			const struct sockaddr_in *sin;
721 			struct in_ifaddr *ia;
722 			struct psref _psref;
723 
724 			sin = satocsin(dst);
725 			ia = in_get_ia_on_iface_psref(sin->sin_addr,
726 			    ifp, &_psref);
727 			if (ia != NULL) {
728 				arpannounce(ifp, &ia->ia_ifa, CLLADDR(dl));
729 				ia4_release(ia, &_psref);
730 			}
731 		}
732 #else
733 		(void)laflags;
734 #endif
735 		break;
736 	    }
737 
738 	case RTM_DELETE:
739 		IF_AFDATA_WLOCK(ifp);
740 		error = lla_delete(llt, 0, dst);
741 		IF_AFDATA_WUNLOCK(ifp);
742 		error = (error == 0 ? 0 : ENOENT);
743 		break;
744 
745 	default:
746 		error = EINVAL;
747 	}
748 
749 out:
750 	if_put(ifp, &psref);
751 	curlwp_bindx(bound);
752 	return (error);
753 }
754 
755 void
756 lltableinit(void)
757 {
758 
759 	SLIST_INIT(&lltables);
760 	rw_init(&lltable_rwlock);
761 }
762 
763 #ifdef __FreeBSD__
764 #ifdef DDB
765 struct llentry_sa {
766 	struct llentry		base;
767 	struct sockaddr		l3_addr;
768 };
769 
770 static void
771 llatbl_lle_show(struct llentry_sa *la)
772 {
773 	struct llentry *lle;
774 	uint8_t octet[6];
775 
776 	lle = &la->base;
777 	db_printf("lle=%p\n", lle);
778 	db_printf(" lle_next=%p\n", lle->lle_next.le_next);
779 	db_printf(" lle_lock=%p\n", &lle->lle_lock);
780 	db_printf(" lle_tbl=%p\n", lle->lle_tbl);
781 	db_printf(" lle_head=%p\n", lle->lle_head);
782 	db_printf(" la_hold=%p\n", lle->la_hold);
783 	db_printf(" la_numheld=%d\n", lle->la_numheld);
784 	db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire);
785 	db_printf(" la_flags=0x%04x\n", lle->la_flags);
786 	db_printf(" la_asked=%u\n", lle->la_asked);
787 	db_printf(" la_preempt=%u\n", lle->la_preempt);
788 	db_printf(" ln_byhint=%u\n", lle->ln_byhint);
789 	db_printf(" ln_state=%d\n", lle->ln_state);
790 	db_printf(" ln_router=%u\n", lle->ln_router);
791 	db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
792 	db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
793 	memcopy(octet, &lle->ll_addr.mac16, sizeof(octet));
794 	db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
795 	    octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
796 	db_printf(" lle_timer=%p\n", &lle->lle_timer);
797 
798 	switch (la->l3_addr.sa_family) {
799 #ifdef INET
800 	case AF_INET:
801 	{
802 		struct sockaddr_in *sin;
803 		char l3s[INET_ADDRSTRLEN];
804 
805 		sin = (struct sockaddr_in *)&la->l3_addr;
806 		inet_ntoa_r(sin->sin_addr, l3s);
807 		db_printf(" l3_addr=%s\n", l3s);
808 		break;
809 	}
810 #endif
811 #ifdef INET6
812 	case AF_INET6:
813 	{
814 		struct sockaddr_in6 *sin6;
815 		char l3s[INET6_ADDRSTRLEN];
816 
817 		sin6 = (struct sockaddr_in6 *)&la->l3_addr;
818 		IN6_PRINT(l3s, &sin6->sin6_addr);
819 		db_printf(" l3_addr=%s\n", l3s);
820 		break;
821 	}
822 #endif
823 	default:
824 		db_printf(" l3_addr=N/A (af=%d)\n", la->l3_addr.sa_family);
825 		break;
826 	}
827 }
828 
829 DB_SHOW_COMMAND(llentry, db_show_llentry)
830 {
831 
832 	if (!have_addr) {
833 		db_printf("usage: show llentry <struct llentry *>\n");
834 		return;
835 	}
836 
837 	llatbl_lle_show((struct llentry_sa *)addr);
838 }
839 
840 static void
841 llatbl_llt_show(struct lltable *llt)
842 {
843 	int i;
844 	struct llentry *lle;
845 
846 	db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
847 	    llt, llt->llt_af, llt->llt_ifp);
848 
849 	for (i = 0; i < llt->llt_hsize; i++) {
850 		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
851 
852 			llatbl_lle_show((struct llentry_sa *)lle);
853 			if (db_pager_quit)
854 				return;
855 		}
856 	}
857 }
858 
859 DB_SHOW_COMMAND(lltable, db_show_lltable)
860 {
861 
862 	if (!have_addr) {
863 		db_printf("usage: show lltable <struct lltable *>\n");
864 		return;
865 	}
866 
867 	llatbl_llt_show((struct lltable *)addr);
868 }
869 
870 DB_SHOW_ALL_COMMAND(lltables, db_show_all_lltables)
871 {
872 	VNET_ITERATOR_DECL(vnet_iter);
873 	struct lltable *llt;
874 
875 	VNET_FOREACH(vnet_iter) {
876 		CURVNET_SET_QUIET(vnet_iter);
877 #ifdef VIMAGE
878 		db_printf("vnet=%p\n", curvnet);
879 #endif
880 		SLIST_FOREACH(llt, &lltables, llt_link) {
881 			db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n",
882 			    llt, llt->llt_af, llt->llt_ifp,
883 			    (llt->llt_ifp != NULL) ?
884 				llt->llt_ifp->if_xname : "?");
885 			if (have_addr && addr != 0) /* verbose */
886 				llatbl_llt_show(llt);
887 			if (db_pager_quit) {
888 				CURVNET_RESTORE();
889 				return;
890 			}
891 		}
892 		CURVNET_RESTORE();
893 	}
894 }
895 #endif /* DDB */
896 #endif /* __FreeBSD__ */
897