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