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