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