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