Home | History | Annotate | Line # | Download | only in net
if_llatbl.c revision 1.23
      1 /*	$NetBSD: if_llatbl.c,v 1.23 2018/02/14 14:15:53 maxv 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) && (ifp->if_flags & IFF_NOARP) == 0) {
    383 		IF_AFDATA_WLOCK(ifp);
    384 		la = lla_create(lt, 0, (struct sockaddr *)dst, NULL /* XXX */);
    385 		IF_AFDATA_WUNLOCK(ifp);
    386 	}
    387 
    388 	if (la != NULL) {
    389 		LLE_ADDREF(la);
    390 		LLE_WUNLOCK(la);
    391 	}
    392 
    393 	return (la);
    394 }
    395 
    396 /*
    397  * Free all entries from given table and free itself.
    398  */
    399 
    400 static int
    401 lltable_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
    402 {
    403 	struct llentries *dchain;
    404 
    405 	dchain = (struct llentries *)farg;
    406 
    407 	LLE_WLOCK(lle);
    408 	LIST_INSERT_HEAD(dchain, lle, lle_chain);
    409 
    410 	return (0);
    411 }
    412 
    413 /*
    414  * Free all entries from given table.
    415  */
    416 void
    417 lltable_purge_entries(struct lltable *llt)
    418 {
    419 	struct llentry *lle, *next;
    420 	struct llentries dchain;
    421 
    422 	KASSERTMSG(llt != NULL, "llt is NULL");
    423 
    424 	LIST_INIT(&dchain);
    425 	IF_AFDATA_WLOCK(llt->llt_ifp);
    426 	/* Push all lles to @dchain */
    427 	lltable_foreach_lle(llt, lltable_free_cb, &dchain);
    428 	llentries_unlink(llt, &dchain);
    429 	IF_AFDATA_WUNLOCK(llt->llt_ifp);
    430 
    431 	LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
    432 		/*
    433 		 * We need to release the lock here to lle_timer proceeds;
    434 		 * lle_timer should stop immediately if LLE_LINKED isn't set.
    435 		 * Note that we cannot pass lle->lle_lock to callout_halt
    436 		 * because it's a rwlock.
    437 		 */
    438 		LLE_ADDREF(lle);
    439 		LLE_WUNLOCK(lle);
    440 #ifdef NET_MPSAFE
    441 		callout_halt(&lle->la_timer, NULL);
    442 #else
    443 		if (mutex_owned(softnet_lock))
    444 			callout_halt(&lle->la_timer, softnet_lock);
    445 		else
    446 			callout_halt(&lle->la_timer, NULL);
    447 #endif
    448 		LLE_WLOCK(lle);
    449 		LLE_REMREF(lle);
    450 		llentry_free(lle);
    451 	}
    452 
    453 }
    454 
    455 /*
    456  * Free all entries from given table and free itself.
    457  */
    458 void
    459 lltable_free(struct lltable *llt)
    460 {
    461 
    462 	KASSERTMSG(llt != NULL, "llt is NULL");
    463 
    464 	lltable_unlink(llt);
    465 	lltable_purge_entries(llt);
    466 	llt->llt_free_tbl(llt);
    467 }
    468 
    469 void
    470 lltable_drain(int af)
    471 {
    472 	struct lltable	*llt;
    473 	struct llentry	*lle;
    474 	register int i;
    475 
    476 	LLTABLE_RLOCK();
    477 	SLIST_FOREACH(llt, &lltables, llt_link) {
    478 		if (llt->llt_af != af)
    479 			continue;
    480 
    481 		for (i=0; i < llt->llt_hsize; i++) {
    482 			LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
    483 				LLE_WLOCK(lle);
    484 				lltable_drop_entry_queue(lle);
    485 				LLE_WUNLOCK(lle);
    486 			}
    487 		}
    488 	}
    489 	LLTABLE_RUNLOCK();
    490 }
    491 
    492 void
    493 lltable_prefix_free(const int af, const struct sockaddr *prefix,
    494     const struct sockaddr *mask, const u_int flags)
    495 {
    496 	struct lltable *llt;
    497 
    498 	LLTABLE_RLOCK();
    499 	SLIST_FOREACH(llt, &lltables, llt_link) {
    500 		if (llt->llt_af != af)
    501 			continue;
    502 
    503 		llt->llt_prefix_free(llt, prefix, mask, flags);
    504 	}
    505 	LLTABLE_RUNLOCK();
    506 }
    507 
    508 struct lltable *
    509 lltable_allocate_htbl(uint32_t hsize)
    510 {
    511 	struct lltable *llt;
    512 	int i;
    513 
    514 	llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
    515 	llt->llt_hsize = hsize;
    516 	llt->lle_head = malloc(sizeof(struct llentries) * hsize,
    517 	    M_LLTABLE, M_WAITOK | M_ZERO);
    518 
    519 	for (i = 0; i < llt->llt_hsize; i++)
    520 		LIST_INIT(&llt->lle_head[i]);
    521 
    522 	/* Set some default callbacks */
    523 	llt->llt_link_entry = htable_link_entry;
    524 	llt->llt_unlink_entry = htable_unlink_entry;
    525 	llt->llt_prefix_free = htable_prefix_free;
    526 	llt->llt_foreach_entry = htable_foreach_lle;
    527 
    528 	llt->llt_free_tbl = htable_free_tbl;
    529 
    530 	return (llt);
    531 }
    532 
    533 /*
    534  * Links lltable to global llt list.
    535  */
    536 void
    537 lltable_link(struct lltable *llt)
    538 {
    539 
    540 	LLTABLE_WLOCK();
    541 	SLIST_INSERT_HEAD(&lltables, llt, llt_link);
    542 	LLTABLE_WUNLOCK();
    543 }
    544 
    545 static void
    546 lltable_unlink(struct lltable *llt)
    547 {
    548 
    549 	LLTABLE_WLOCK();
    550 	SLIST_REMOVE(&lltables, llt, lltable, llt_link);
    551 	LLTABLE_WUNLOCK();
    552 
    553 }
    554 
    555 /*
    556  * External methods used by lltable consumers
    557  */
    558 
    559 int
    560 lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
    561 {
    562 
    563 	return (llt->llt_foreach_entry(llt, f, farg));
    564 }
    565 
    566 void
    567 lltable_link_entry(struct lltable *llt, struct llentry *lle)
    568 {
    569 
    570 	llt->llt_link_entry(llt, lle);
    571 }
    572 
    573 void
    574 lltable_unlink_entry(struct lltable *llt, struct llentry *lle)
    575 {
    576 
    577 	llt->llt_unlink_entry(lle);
    578 }
    579 
    580 void
    581 lltable_free_entry(struct lltable *llt, struct llentry *lle)
    582 {
    583 
    584 	llt->llt_free_entry(llt, lle);
    585 }
    586 
    587 void
    588 lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
    589 {
    590 	struct lltable *llt;
    591 
    592 	llt = lle->lle_tbl;
    593 	llt->llt_fill_sa_entry(lle, sa);
    594 }
    595 
    596 struct ifnet *
    597 lltable_get_ifp(const struct lltable *llt)
    598 {
    599 
    600 	return (llt->llt_ifp);
    601 }
    602 
    603 int
    604 lltable_get_af(const struct lltable *llt)
    605 {
    606 
    607 	return (llt->llt_af);
    608 }
    609 
    610 /*
    611  * Called in route_output when rtm_flags contains RTF_LLDATA.
    612  */
    613 int
    614 lla_rt_output(const u_char rtm_type, const int rtm_flags, const time_t rtm_expire,
    615     struct rt_addrinfo *info, int sdl_index)
    616 {
    617 	const struct sockaddr_dl *dl = satocsdl(info->rti_info[RTAX_GATEWAY]);
    618 	const struct sockaddr *dst = info->rti_info[RTAX_DST];
    619 	struct ifnet *ifp;
    620 	struct lltable *llt;
    621 	struct llentry *lle;
    622 	u_int laflags;
    623 	int error;
    624 	struct psref psref;
    625 	int bound;
    626 
    627 	KASSERTMSG(dl != NULL && dl->sdl_family == AF_LINK, "invalid dl");
    628 
    629 	bound = curlwp_bind();
    630 	if (sdl_index != 0)
    631 		ifp = if_get_byindex(sdl_index, &psref);
    632 	else
    633 		ifp = if_get_byindex(dl->sdl_index, &psref);
    634 	if (ifp == NULL) {
    635 		curlwp_bindx(bound);
    636 		log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n",
    637 		    __func__, sdl_index != 0 ? sdl_index : dl->sdl_index);
    638 		return EINVAL;
    639 	}
    640 
    641 	/* XXX linked list may be too expensive */
    642 	LLTABLE_RLOCK();
    643 	SLIST_FOREACH(llt, &lltables, llt_link) {
    644 		if (llt->llt_af == dst->sa_family &&
    645 		    llt->llt_ifp == ifp)
    646 			break;
    647 	}
    648 	LLTABLE_RUNLOCK();
    649 	KASSERTMSG(llt != NULL, "Yep, ugly hacks are bad");
    650 
    651 	error = 0;
    652 
    653 	switch (rtm_type) {
    654 	case RTM_ADD: {
    655 		struct rtentry *rt;
    656 
    657 		/* Never call rtalloc1 with IF_AFDATA_WLOCK */
    658 		rt = rtalloc1(dst, 0);
    659 
    660 		/* Add static LLE */
    661 		IF_AFDATA_WLOCK(ifp);
    662 		lle = lla_lookup(llt, 0, dst);
    663 
    664 		/* Cannot overwrite an existing static entry */
    665 		if (lle != NULL &&
    666 		    (lle->la_flags & LLE_STATIC || lle->la_expire == 0)) {
    667 			LLE_RUNLOCK(lle);
    668 			IF_AFDATA_WUNLOCK(ifp);
    669 			if (rt != NULL)
    670 				rt_unref(rt);
    671 			error = EEXIST;
    672 			goto out;
    673 		}
    674 		if (lle != NULL)
    675 			LLE_RUNLOCK(lle);
    676 
    677 		lle = lla_create(llt, 0, dst, rt);
    678 		if (lle == NULL) {
    679 			IF_AFDATA_WUNLOCK(ifp);
    680 			if (rt != NULL)
    681 				rt_unref(rt);
    682 			error = ENOMEM;
    683 			goto out;
    684 		}
    685 
    686 		KASSERT(ifp->if_addrlen <= sizeof(lle->ll_addr));
    687 		memcpy(&lle->ll_addr, CLLADDR(dl), ifp->if_addrlen);
    688 		if ((rtm_flags & RTF_ANNOUNCE))
    689 			lle->la_flags |= LLE_PUB;
    690 		lle->la_flags |= LLE_VALID;
    691 #ifdef INET6
    692 		/*
    693 		 * ND6
    694 		 */
    695 		if (dst->sa_family == AF_INET6)
    696 			lle->ln_state = ND6_LLINFO_REACHABLE;
    697 #endif
    698 		/*
    699 		 * NB: arp and ndp always set (RTF_STATIC | RTF_HOST)
    700 		 */
    701 
    702 		if (rtm_expire == 0) {
    703 			lle->la_flags |= LLE_STATIC;
    704 			lle->la_expire = 0;
    705 		} else
    706 			lle->la_expire = rtm_expire;
    707 		laflags = lle->la_flags;
    708 		LLE_WUNLOCK(lle);
    709 		IF_AFDATA_WUNLOCK(ifp);
    710 		if (rt != NULL)
    711 			rt_unref(rt);
    712 #if defined(INET) && NARP > 0
    713 		/* gratuitous ARP */
    714 		if ((laflags & LLE_PUB) && dst->sa_family == AF_INET) {
    715 			const struct sockaddr_in *sin;
    716 			struct in_ifaddr *ia;
    717 			struct psref _psref;
    718 
    719 			sin = satocsin(dst);
    720 			ia = in_get_ia_on_iface_psref(sin->sin_addr,
    721 			    ifp, &_psref);
    722 			if (ia != NULL) {
    723 				arpannounce(ifp, &ia->ia_ifa, CLLADDR(dl));
    724 				ia4_release(ia, &_psref);
    725 			}
    726 		}
    727 #else
    728 		(void)laflags;
    729 #endif
    730 		break;
    731 	    }
    732 
    733 	case RTM_DELETE:
    734 		IF_AFDATA_WLOCK(ifp);
    735 		error = lla_delete(llt, 0, dst);
    736 		IF_AFDATA_WUNLOCK(ifp);
    737 		error = (error == 0 ? 0 : ENOENT);
    738 		break;
    739 
    740 	default:
    741 		error = EINVAL;
    742 	}
    743 
    744 out:
    745 	if_put(ifp, &psref);
    746 	curlwp_bindx(bound);
    747 	return (error);
    748 }
    749 
    750 void
    751 lltableinit(void)
    752 {
    753 
    754 	SLIST_INIT(&lltables);
    755 	rw_init(&lltable_rwlock);
    756 }
    757 
    758 #ifdef __FreeBSD__
    759 #ifdef DDB
    760 struct llentry_sa {
    761 	struct llentry		base;
    762 	struct sockaddr		l3_addr;
    763 };
    764 
    765 static void
    766 llatbl_lle_show(struct llentry_sa *la)
    767 {
    768 	struct llentry *lle;
    769 	uint8_t octet[6];
    770 
    771 	lle = &la->base;
    772 	db_printf("lle=%p\n", lle);
    773 	db_printf(" lle_next=%p\n", lle->lle_next.le_next);
    774 	db_printf(" lle_lock=%p\n", &lle->lle_lock);
    775 	db_printf(" lle_tbl=%p\n", lle->lle_tbl);
    776 	db_printf(" lle_head=%p\n", lle->lle_head);
    777 	db_printf(" la_hold=%p\n", lle->la_hold);
    778 	db_printf(" la_numheld=%d\n", lle->la_numheld);
    779 	db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire);
    780 	db_printf(" la_flags=0x%04x\n", lle->la_flags);
    781 	db_printf(" la_asked=%u\n", lle->la_asked);
    782 	db_printf(" la_preempt=%u\n", lle->la_preempt);
    783 	db_printf(" ln_byhint=%u\n", lle->ln_byhint);
    784 	db_printf(" ln_state=%d\n", lle->ln_state);
    785 	db_printf(" ln_router=%u\n", lle->ln_router);
    786 	db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
    787 	db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
    788 	memcopy(octet, &lle->ll_addr.mac16, sizeof(octet));
    789 	db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
    790 	    octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
    791 	db_printf(" lle_timer=%p\n", &lle->lle_timer);
    792 
    793 	switch (la->l3_addr.sa_family) {
    794 #ifdef INET
    795 	case AF_INET:
    796 	{
    797 		struct sockaddr_in *sin;
    798 		char l3s[INET_ADDRSTRLEN];
    799 
    800 		sin = (struct sockaddr_in *)&la->l3_addr;
    801 		inet_ntoa_r(sin->sin_addr, l3s);
    802 		db_printf(" l3_addr=%s\n", l3s);
    803 		break;
    804 	}
    805 #endif
    806 #ifdef INET6
    807 	case AF_INET6:
    808 	{
    809 		struct sockaddr_in6 *sin6;
    810 		char l3s[INET6_ADDRSTRLEN];
    811 
    812 		sin6 = (struct sockaddr_in6 *)&la->l3_addr;
    813 		IN6_PRINT(l3s, &sin6->sin6_addr);
    814 		db_printf(" l3_addr=%s\n", l3s);
    815 		break;
    816 	}
    817 #endif
    818 	default:
    819 		db_printf(" l3_addr=N/A (af=%d)\n", la->l3_addr.sa_family);
    820 		break;
    821 	}
    822 }
    823 
    824 DB_SHOW_COMMAND(llentry, db_show_llentry)
    825 {
    826 
    827 	if (!have_addr) {
    828 		db_printf("usage: show llentry <struct llentry *>\n");
    829 		return;
    830 	}
    831 
    832 	llatbl_lle_show((struct llentry_sa *)addr);
    833 }
    834 
    835 static void
    836 llatbl_llt_show(struct lltable *llt)
    837 {
    838 	int i;
    839 	struct llentry *lle;
    840 
    841 	db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
    842 	    llt, llt->llt_af, llt->llt_ifp);
    843 
    844 	for (i = 0; i < llt->llt_hsize; i++) {
    845 		LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
    846 
    847 			llatbl_lle_show((struct llentry_sa *)lle);
    848 			if (db_pager_quit)
    849 				return;
    850 		}
    851 	}
    852 }
    853 
    854 DB_SHOW_COMMAND(lltable, db_show_lltable)
    855 {
    856 
    857 	if (!have_addr) {
    858 		db_printf("usage: show lltable <struct lltable *>\n");
    859 		return;
    860 	}
    861 
    862 	llatbl_llt_show((struct lltable *)addr);
    863 }
    864 
    865 DB_SHOW_ALL_COMMAND(lltables, db_show_all_lltables)
    866 {
    867 	VNET_ITERATOR_DECL(vnet_iter);
    868 	struct lltable *llt;
    869 
    870 	VNET_FOREACH(vnet_iter) {
    871 		CURVNET_SET_QUIET(vnet_iter);
    872 #ifdef VIMAGE
    873 		db_printf("vnet=%p\n", curvnet);
    874 #endif
    875 		SLIST_FOREACH(llt, &lltables, llt_link) {
    876 			db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n",
    877 			    llt, llt->llt_af, llt->llt_ifp,
    878 			    (llt->llt_ifp != NULL) ?
    879 				llt->llt_ifp->if_xname : "?");
    880 			if (have_addr && addr != 0) /* verbose */
    881 				llatbl_llt_show(llt);
    882 			if (db_pager_quit) {
    883 				CURVNET_RESTORE();
    884 				return;
    885 			}
    886 		}
    887 		CURVNET_RESTORE();
    888 	}
    889 }
    890 #endif /* DDB */
    891 #endif /* __FreeBSD__ */
    892