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