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