2 * SPDX-License-Identifier: BSD-2-Clause
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.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/cdefs.h>
32 #include "opt_inet6.h"
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/eventhandler.h>
37 #include <sys/malloc.h>
39 #include <sys/syslog.h>
40 #include <sys/sysctl.h>
41 #include <sys/socket.h>
42 #include <sys/kernel.h>
44 #include <sys/mutex.h>
45 #include <sys/rwlock.h>
53 #include <netinet/in.h>
54 #include <net/if_llatbl.h>
56 #include <net/if_dl.h>
57 #include <net/if_var.h>
58 #include <net/if_private.h>
59 #include <net/route.h>
60 #include <net/route/route_ctl.h>
61 #include <net/route/route_debug.h>
63 #include <netinet/if_ether.h>
64 #include <netinet6/in6_var.h>
65 #include <netinet6/nd6.h>
67 MALLOC_DEFINE(M_LLTABLE
, "lltable", "link level address tables");
69 VNET_DEFINE_STATIC(SLIST_HEAD(, lltable
), lltables
) =
70 SLIST_HEAD_INITIALIZER(lltables
);
71 #define V_lltables VNET(lltables)
73 static struct rwlock lltable_list_lock
;
74 RW_SYSINIT(lltable_list_lock
, &lltable_list_lock
, "lltable_list_lock");
75 #define LLTABLE_LIST_RLOCK() rw_rlock(&lltable_list_lock)
76 #define LLTABLE_LIST_RUNLOCK() rw_runlock(&lltable_list_lock)
77 #define LLTABLE_LIST_WLOCK() rw_wlock(&lltable_list_lock)
78 #define LLTABLE_LIST_WUNLOCK() rw_wunlock(&lltable_list_lock)
79 #define LLTABLE_LIST_LOCK_ASSERT() rw_assert(&lltable_list_lock, RA_LOCKED)
81 static void lltable_unlink(struct lltable
*llt
);
82 static void llentries_unlink(struct lltable
*llt
, struct llentries
*head
);
85 * Dump lle state for a specific address family.
88 lltable_dump_af(struct lltable
*llt
, struct sysctl_req
*wr
)
90 struct epoch_tracker et
;
93 LLTABLE_LIST_LOCK_ASSERT();
95 if (llt
->llt_ifp
->if_flags
& IFF_LOOPBACK
)
100 error
= lltable_foreach_lle(llt
,
101 (llt_foreach_cb_t
*)llt
->llt_dump_entry
, wr
);
108 * Dump arp state for a specific address family.
111 lltable_sysctl_dumparp(int af
, struct sysctl_req
*wr
)
116 LLTABLE_LIST_RLOCK();
117 SLIST_FOREACH(llt
, &V_lltables
, llt_link
) {
118 if (llt
->llt_af
== af
) {
119 error
= lltable_dump_af(llt
, wr
);
125 LLTABLE_LIST_RUNLOCK();
130 * Adds a mbuf to hold queue. Drops old packets if the queue is full.
132 * Returns the number of held packets that were dropped.
135 lltable_append_entry_queue(struct llentry
*lle
, struct mbuf
*m
,
138 size_t pkts_dropped
= 0;
140 LLE_WLOCK_ASSERT(lle
);
142 while (lle
->la_numheld
>= maxheld
&& lle
->la_hold
!= NULL
) {
143 struct mbuf
*next
= lle
->la_hold
->m_nextpkt
;
144 m_freem(lle
->la_hold
);
150 if (lle
->la_hold
!= NULL
) {
151 struct mbuf
*curr
= lle
->la_hold
;
152 while (curr
->m_nextpkt
!= NULL
)
153 curr
= curr
->m_nextpkt
;
165 * Common function helpers for chained hash table.
169 * Runs specified callback for each entry in @llt.
170 * Caller does the locking.
174 htable_foreach_lle(struct lltable
*llt
, llt_foreach_cb_t
*f
, void *farg
)
176 struct llentry
*lle
, *next
;
181 for (i
= 0; i
< llt
->llt_hsize
; i
++) {
182 CK_LIST_FOREACH_SAFE(lle
, &llt
->lle_head
[i
], lle_next
, next
) {
183 error
= f(llt
, lle
, farg
);
193 * The htable_[un]link_entry() functions return:
194 * 0 if the entry was (un)linked already and nothing changed,
195 * 1 if the entry was added/removed to/from the table, and
196 * -1 on error (e.g., not being able to add the entry due to limits reached).
197 * While the "unlink" operation should never error, callers of
198 * lltable_link_entry() need to check for errors and handle them.
201 htable_link_entry(struct lltable
*llt
, struct llentry
*lle
)
203 struct llentries
*lleh
;
206 if ((lle
->la_flags
& LLE_LINKED
) != 0)
209 IF_AFDATA_WLOCK_ASSERT(llt
->llt_ifp
);
211 if (llt
->llt_maxentries
> 0 &&
212 llt
->llt_entries
>= llt
->llt_maxentries
)
215 hashidx
= llt
->llt_hash(lle
, llt
->llt_hsize
);
216 lleh
= &llt
->lle_head
[hashidx
];
219 lle
->lle_head
= lleh
;
220 lle
->la_flags
|= LLE_LINKED
;
221 CK_LIST_INSERT_HEAD(lleh
, lle
, lle_next
);
228 htable_unlink_entry(struct llentry
*lle
)
232 if ((lle
->la_flags
& LLE_LINKED
) == 0)
236 IF_AFDATA_WLOCK_ASSERT(llt
->llt_ifp
);
237 KASSERT(llt
->llt_entries
> 0, ("%s: lltable %p (%s) entries %d <= 0",
238 __func__
, llt
, if_name(llt
->llt_ifp
), llt
->llt_entries
));
240 CK_LIST_REMOVE(lle
, lle_next
);
241 lle
->la_flags
&= ~(LLE_VALID
| LLE_LINKED
);
244 lle
->lle_head
= NULL
;
251 struct prefix_match_data
{
252 const struct sockaddr
*addr
;
253 const struct sockaddr
*mask
;
254 struct llentries dchain
;
259 htable_prefix_free_cb(struct lltable
*llt
, struct llentry
*lle
, void *farg
)
261 struct prefix_match_data
*pmd
;
263 pmd
= (struct prefix_match_data
*)farg
;
265 if (llt
->llt_match_prefix(pmd
->addr
, pmd
->mask
, pmd
->flags
, lle
)) {
267 CK_LIST_INSERT_HEAD(&pmd
->dchain
, lle
, lle_chain
);
274 htable_prefix_free(struct lltable
*llt
, const struct sockaddr
*addr
,
275 const struct sockaddr
*mask
, u_int flags
)
277 struct llentry
*lle
, *next
;
278 struct prefix_match_data pmd
;
280 bzero(&pmd
, sizeof(pmd
));
284 CK_LIST_INIT(&pmd
.dchain
);
286 IF_AFDATA_WLOCK(llt
->llt_ifp
);
287 /* Push matching lles to chain */
288 lltable_foreach_lle(llt
, htable_prefix_free_cb
, &pmd
);
290 llentries_unlink(llt
, &pmd
.dchain
);
291 IF_AFDATA_WUNLOCK(llt
->llt_ifp
);
293 CK_LIST_FOREACH_SAFE(lle
, &pmd
.dchain
, lle_chain
, next
)
294 lltable_free_entry(llt
, lle
);
298 htable_free_tbl(struct lltable
*llt
)
301 free(llt
->lle_head
, M_LLTABLE
);
302 free(llt
, M_LLTABLE
);
306 llentries_unlink(struct lltable
*llt
, struct llentries
*head
)
308 struct llentry
*lle
, *next
;
310 CK_LIST_FOREACH_SAFE(lle
, head
, lle_chain
, next
)
311 llt
->llt_unlink_entry(lle
);
315 * Helper function used to drop all mbufs in hold queue.
317 * Returns the number of held packets, if any, that were dropped.
320 lltable_drop_entry_queue(struct llentry
*lle
)
322 size_t pkts_dropped
= 0;
324 LLE_WLOCK_ASSERT(lle
);
326 while (lle
->la_hold
!= NULL
) {
327 struct mbuf
*next
= lle
->la_hold
->m_nextpkt
;
328 m_freem(lle
->la_hold
);
334 KASSERT(lle
->la_numheld
== 0,
335 ("%s: la_numheld %d > 0, pkts_dropped %zd", __func__
,
336 lle
->la_numheld
, pkts_dropped
));
338 return (pkts_dropped
);
342 lltable_set_entry_addr(struct ifnet
*ifp
, struct llentry
*lle
,
343 const char *linkhdr
, size_t linkhdrsize
, int lladdr_off
)
346 memcpy(lle
->r_linkdata
, linkhdr
, linkhdrsize
);
347 lle
->r_hdrlen
= linkhdrsize
;
348 lle
->ll_addr
= &lle
->r_linkdata
[lladdr_off
];
349 lle
->la_flags
|= LLE_VALID
;
350 lle
->r_flags
|= RLLE_VALID
;
354 * Acquires lltable write lock.
356 * Returns true on success, with both lltable and lle lock held.
357 * On failure, false is returned and lle wlock is still held.
360 lltable_acquire_wlock(struct ifnet
*ifp
, struct llentry
*lle
)
364 /* Perform real LLE update */
365 /* use afdata WLOCK to update fields */
367 IF_AFDATA_WLOCK(ifp
);
371 * Since we droppped LLE lock, other thread might have deleted
372 * this lle. Check and return
374 if ((lle
->la_flags
& LLE_DELETED
) != 0) {
375 IF_AFDATA_WUNLOCK(ifp
);
383 * Tries to update @lle link-level address.
384 * Since update requires AFDATA WLOCK, function
385 * drops @lle lock, acquires AFDATA lock and then acquires
386 * @lle lock to maintain lock order.
388 * Returns 1 on success.
391 lltable_try_set_entry_addr(struct ifnet
*ifp
, struct llentry
*lle
,
392 const char *linkhdr
, size_t linkhdrsize
, int lladdr_off
)
395 if (!lltable_acquire_wlock(ifp
, lle
))
399 lltable_set_entry_addr(ifp
, lle
, linkhdr
, linkhdrsize
, lladdr_off
);
401 IF_AFDATA_WUNLOCK(ifp
);
407 * Helper function used to pre-compute full/partial link-layer
408 * header data suitable for feeding into if_output().
411 lltable_calc_llheader(struct ifnet
*ifp
, int family
, char *lladdr
,
412 char *buf
, size_t *bufsize
, int *lladdr_off
)
414 struct if_encap_req ereq
;
417 bzero(buf
, *bufsize
);
418 bzero(&ereq
, sizeof(ereq
));
420 ereq
.bufsize
= *bufsize
;
421 ereq
.rtype
= IFENCAP_LL
;
422 ereq
.family
= family
;
423 ereq
.lladdr
= lladdr
;
424 ereq
.lladdr_len
= ifp
->if_addrlen
;
425 error
= ifp
->if_requestencap(ifp
, &ereq
);
427 *bufsize
= ereq
.bufsize
;
428 *lladdr_off
= ereq
.lladdr_off
;
435 * Searches for the child entry matching @family inside @lle.
436 * Returns the entry or NULL.
439 llentry_lookup_family(struct llentry
*lle
, int family
)
441 struct llentry
*child_lle
;
446 CK_SLIST_FOREACH(child_lle
, &lle
->lle_children
, lle_child_next
) {
447 if (child_lle
->r_family
== family
)
455 * Retrieves upper protocol family for the llentry.
456 * By default, all "normal" (e.g. upper_family == transport_family)
457 * llentries have r_family set to 0.
458 * Thus, use @default_family in that regard, otherwise use r_family.
460 * Returns upper protocol family
463 llentry_get_upper_family(const struct llentry
*lle
, int default_family
)
465 return (lle
->r_family
== 0 ? default_family
: lle
->r_family
);
469 * Prints llentry @lle data into provided buffer.
470 * Example: lle/inet/valid/em0/1.2.3.4
475 llentry_print_buf(const struct llentry
*lle
, struct ifnet
*ifp
, int family
,
476 char *buf
, size_t bufsize
)
478 #if defined(INET) || defined(INET6)
479 char abuf
[INET6_ADDRSTRLEN
];
482 const char *valid
= (lle
->r_flags
& RLLE_VALID
) ? "valid" : "no_l2";
483 const char *upper_str
= rib_print_family(llentry_get_upper_family(lle
, family
));
488 inet_ntop(AF_INET
, &lle
->r_l3addr
.addr4
, abuf
, sizeof(abuf
));
489 snprintf(buf
, bufsize
, "lle/%s/%s/%s/%s", upper_str
,
490 valid
, if_name(ifp
), abuf
);
495 inet_ntop(AF_INET6
, &lle
->r_l3addr
.addr6
, abuf
, sizeof(abuf
));
496 snprintf(buf
, bufsize
, "lle/%s/%s/%s/%s", upper_str
,
497 valid
, if_name(ifp
), abuf
);
501 snprintf(buf
, bufsize
, "lle/%s/%s/%s/????", upper_str
,
502 valid
, if_name(ifp
));
510 llentry_print_buf_lltable(const struct llentry
*lle
, char *buf
, size_t bufsize
)
512 struct lltable
*tbl
= lle
->lle_tbl
;
514 return (llentry_print_buf(lle
, lltable_get_ifp(tbl
), lltable_get_af(tbl
), buf
, bufsize
));
518 * Requests feedback from the datapath.
519 * First packet using @lle should result in
520 * setting r_skip_req back to 0 and updating
521 * lle_hittime to the current time_uptime.
524 llentry_request_feedback(struct llentry
*lle
)
526 struct llentry
*child_lle
;
532 CK_SLIST_FOREACH(child_lle
, &lle
->lle_children
, lle_child_next
) {
533 LLE_REQ_LOCK(child_lle
);
534 child_lle
->r_skip_req
= 1;
535 LLE_REQ_UNLOCK(child_lle
);
540 * Updates the lle state to mark it has been used
541 * and record the time.
542 * Used by the llentry_provide_feedback() wrapper.
545 llentry_mark_used(struct llentry
*lle
)
549 lle
->lle_hittime
= time_uptime
;
554 * Fetches the time when lle was used.
555 * Return 0 if the entry was not used, relevant time_uptime
559 llentry_get_hittime_raw(struct llentry
*lle
)
561 time_t lle_hittime
= 0;
564 if ((lle
->r_skip_req
== 0) && (lle_hittime
< lle
->lle_hittime
))
565 lle_hittime
= lle
->lle_hittime
;
568 return (lle_hittime
);
572 llentry_get_hittime(struct llentry
*lle
)
574 time_t lle_hittime
= 0;
575 struct llentry
*child_lle
;
577 lle_hittime
= llentry_get_hittime_raw(lle
);
579 CK_SLIST_FOREACH(child_lle
, &lle
->lle_children
, lle_child_next
) {
580 time_t hittime
= llentry_get_hittime_raw(child_lle
);
581 if (hittime
> lle_hittime
)
582 lle_hittime
= hittime
;
585 return (lle_hittime
);
589 * Update link-layer header for given @lle after
590 * interface lladdr was changed.
593 llentry_update_ifaddr(struct lltable
*llt
, struct llentry
*lle
, void *farg
)
596 u_char linkhdr
[LLE_MAX_LINKHDR
];
601 ifp
= (struct ifnet
*)farg
;
603 lladdr
= lle
->ll_addr
;
606 if ((lle
->la_flags
& LLE_VALID
) == 0) {
611 if ((lle
->la_flags
& LLE_IFADDR
) != 0)
612 lladdr
= IF_LLADDR(ifp
);
614 linkhdrsize
= sizeof(linkhdr
);
615 lltable_calc_llheader(ifp
, llt
->llt_af
, lladdr
, linkhdr
, &linkhdrsize
,
617 memcpy(lle
->r_linkdata
, linkhdr
, linkhdrsize
);
624 * Update all calculated headers for given @llt
627 lltable_update_ifaddr(struct lltable
*llt
)
630 if (llt
->llt_ifp
->if_flags
& IFF_LOOPBACK
)
633 IF_AFDATA_WLOCK(llt
->llt_ifp
);
634 lltable_foreach_lle(llt
, llentry_update_ifaddr
, llt
->llt_ifp
);
635 IF_AFDATA_WUNLOCK(llt
->llt_ifp
);
640 * Performs generic cleanup routines and frees lle.
642 * Called for non-linked entries, with callouts and
643 * other AF-specific cleanups performed.
645 * @lle must be passed WLOCK'ed
647 * Returns the number of held packets, if any, that were dropped.
650 llentry_free(struct llentry
*lle
)
654 LLE_WLOCK_ASSERT(lle
);
656 KASSERT((lle
->la_flags
& LLE_LINKED
) == 0, ("freeing linked lle"));
658 pkts_dropped
= lltable_drop_entry_queue(lle
);
661 if (callout_stop(&lle
->lle_timer
) > 0)
663 LLE_FREE_LOCKED(lle
);
665 return (pkts_dropped
);
669 * Free all entries from given table and free itself.
673 lltable_free_cb(struct lltable
*llt
, struct llentry
*lle
, void *farg
)
675 struct llentries
*dchain
;
677 dchain
= (struct llentries
*)farg
;
680 CK_LIST_INSERT_HEAD(dchain
, lle
, lle_chain
);
686 * Free all entries from given table and free itself.
689 lltable_free(struct lltable
*llt
)
691 struct llentry
*lle
, *next
;
692 struct llentries dchain
;
694 KASSERT(llt
!= NULL
, ("%s: llt is NULL", __func__
));
698 CK_LIST_INIT(&dchain
);
699 IF_AFDATA_WLOCK(llt
->llt_ifp
);
700 /* Push all lles to @dchain */
701 lltable_foreach_lle(llt
, lltable_free_cb
, &dchain
);
702 llentries_unlink(llt
, &dchain
);
703 IF_AFDATA_WUNLOCK(llt
->llt_ifp
);
705 CK_LIST_FOREACH_SAFE(lle
, &dchain
, lle_chain
, next
) {
709 KASSERT(llt
->llt_entries
== 0, ("%s: lltable %p (%s) entries not 0: %d",
710 __func__
, llt
, llt
->llt_ifp
->if_xname
, llt
->llt_entries
));
712 llt
->llt_free_tbl(llt
);
716 * Deletes an address from given lltable.
717 * Used for userland interaction to remove
718 * individual entries. Skips entries added by OS.
721 lltable_delete_addr(struct lltable
*llt
, u_int flags
,
722 const struct sockaddr
*l3addr
)
728 IF_AFDATA_WLOCK(ifp
);
729 lle
= lla_lookup(llt
, LLE_SF(l3addr
->sa_family
, LLE_EXCLUSIVE
), l3addr
);
732 IF_AFDATA_WUNLOCK(ifp
);
735 if ((lle
->la_flags
& LLE_IFADDR
) != 0 && (flags
& LLE_IFADDR
) == 0) {
736 IF_AFDATA_WUNLOCK(ifp
);
741 lltable_unlink_entry(llt
, lle
);
742 IF_AFDATA_WUNLOCK(ifp
);
744 llt
->llt_delete_entry(llt
, lle
);
750 lltable_prefix_free(int af
, struct sockaddr
*addr
, struct sockaddr
*mask
,
755 LLTABLE_LIST_RLOCK();
756 SLIST_FOREACH(llt
, &V_lltables
, llt_link
) {
757 if (llt
->llt_af
!= af
)
760 llt
->llt_prefix_free(llt
, addr
, mask
, flags
);
762 LLTABLE_LIST_RUNLOCK();
766 * Delete llentries that func() returns true.
768 struct lle_match_data
{
769 struct llentries dchain
;
770 llt_match_cb_t
*func
;
775 lltable_delete_conditional_cb(struct lltable
*llt
, struct llentry
*lle
,
778 struct lle_match_data
*lmd
;
780 lmd
= (struct lle_match_data
*)farg
;
781 if (lmd
->func(llt
, lle
, lmd
->farg
)) {
783 CK_LIST_INSERT_HEAD(&lmd
->dchain
, lle
, lle_chain
);
790 lltable_delete_conditional(struct lltable
*llt
, llt_match_cb_t
*func
,
793 struct llentry
*lle
, *next
;
794 struct lle_match_data lmd
;
796 bzero(&lmd
, sizeof(lmd
));
797 CK_LIST_INIT(&lmd
.dchain
);
801 IF_AFDATA_WLOCK(llt
->llt_ifp
);
802 lltable_foreach_lle(llt
, lltable_delete_conditional_cb
, &lmd
);
803 llentries_unlink(llt
, &lmd
.dchain
);
804 IF_AFDATA_WUNLOCK(llt
->llt_ifp
);
806 CK_LIST_FOREACH_SAFE(lle
, &lmd
.dchain
, lle_chain
, next
)
807 llt
->llt_delete_entry(llt
, lle
);
811 lltable_allocate_htbl(uint32_t hsize
)
816 llt
= malloc(sizeof(struct lltable
), M_LLTABLE
, M_WAITOK
| M_ZERO
);
817 llt
->llt_hsize
= hsize
;
818 llt
->lle_head
= malloc(sizeof(struct llentries
) * hsize
,
819 M_LLTABLE
, M_WAITOK
| M_ZERO
);
821 for (i
= 0; i
< llt
->llt_hsize
; i
++)
822 CK_LIST_INIT(&llt
->lle_head
[i
]);
824 /* Set some default callbacks */
825 llt
->llt_link_entry
= htable_link_entry
;
826 llt
->llt_unlink_entry
= htable_unlink_entry
;
827 llt
->llt_prefix_free
= htable_prefix_free
;
828 llt
->llt_foreach_entry
= htable_foreach_lle
;
829 llt
->llt_free_tbl
= htable_free_tbl
;
835 * Links lltable to global llt list.
838 lltable_link(struct lltable
*llt
)
841 LLTABLE_LIST_WLOCK();
842 SLIST_INSERT_HEAD(&V_lltables
, llt
, llt_link
);
843 LLTABLE_LIST_WUNLOCK();
847 lltable_unlink(struct lltable
*llt
)
850 LLTABLE_LIST_WLOCK();
851 SLIST_REMOVE(&V_lltables
, llt
, lltable
, llt_link
);
852 LLTABLE_LIST_WUNLOCK();
857 * Gets interface @ifp lltable for the specified @family
860 lltable_get(struct ifnet
*ifp
, int family
)
865 return (in_lltable_get(ifp
));
869 return (in6_lltable_get(ifp
));
877 * External methods used by lltable consumers
881 lltable_foreach_lle(struct lltable
*llt
, llt_foreach_cb_t
*f
, void *farg
)
884 return (llt
->llt_foreach_entry(llt
, f
, farg
));
888 lltable_alloc_entry(struct lltable
*llt
, u_int flags
,
889 const struct sockaddr
*l3addr
)
892 return (llt
->llt_alloc_entry(llt
, flags
, l3addr
));
896 lltable_free_entry(struct lltable
*llt
, struct llentry
*lle
)
899 llt
->llt_free_entry(llt
, lle
);
903 lltable_link_entry(struct lltable
*llt
, struct llentry
*lle
)
905 int error
= llt
->llt_link_entry(llt
, lle
);
907 if (error
== 0 && (lle
->la_flags
& LLE_PUB
) != 0)
908 llt
->llt_flags
|= LLT_ADDEDPROXY
;
914 lltable_link_child_entry(struct llentry
*lle
, struct llentry
*child_lle
)
916 child_lle
->lle_parent
= lle
;
917 child_lle
->lle_tbl
= lle
->lle_tbl
;
918 child_lle
->la_flags
|= LLE_LINKED
;
919 CK_SLIST_INSERT_HEAD(&lle
->lle_children
, child_lle
, lle_child_next
);
923 lltable_unlink_child_entry(struct llentry
*child_lle
)
925 struct llentry
*lle
= child_lle
->lle_parent
;
927 child_lle
->la_flags
&= ~LLE_LINKED
;
928 child_lle
->lle_parent
= NULL
;
929 CK_SLIST_REMOVE(&lle
->lle_children
, child_lle
, llentry
, lle_child_next
);
933 lltable_unlink_entry(struct lltable
*llt
, struct llentry
*lle
)
936 return (llt
->llt_unlink_entry(lle
));
940 lltable_fill_sa_entry(const struct llentry
*lle
, struct sockaddr
*sa
)
945 llt
->llt_fill_sa_entry(lle
, sa
);
949 lltable_get_ifp(const struct lltable
*llt
)
952 return (llt
->llt_ifp
);
956 lltable_get_af(const struct lltable
*llt
)
959 return (llt
->llt_af
);
963 * Called in route_output when rtm_flags contains RTF_LLDATA.
966 lla_rt_output(struct rt_msghdr
*rtm
, struct rt_addrinfo
*info
)
968 struct sockaddr_dl
*dl
=
969 (struct sockaddr_dl
*)info
->rti_info
[RTAX_GATEWAY
];
970 struct sockaddr
*dst
= (struct sockaddr
*)info
->rti_info
[RTAX_DST
];
973 struct llentry
*lle
, *lle_tmp
;
974 uint8_t linkhdr
[LLE_MAX_LINKHDR
];
980 if (dl
== NULL
|| dl
->sdl_family
!= AF_LINK
)
983 /* XXX: should be ntohs() */
984 ifp
= ifnet_byindex(dl
->sdl_index
);
986 log(LOG_INFO
, "%s: invalid ifp (sdl_index %d)\n",
987 __func__
, dl
->sdl_index
);
991 llt
= lltable_get(ifp
, dst
->sa_family
);
998 switch (rtm
->rtm_type
) {
1000 /* Add static LLE */
1002 if (rtm
->rtm_rmx
.rmx_expire
== 0)
1003 laflags
= LLE_STATIC
;
1004 lle
= lltable_alloc_entry(llt
, laflags
, dst
);
1008 linkhdrsize
= sizeof(linkhdr
);
1009 if (lltable_calc_llheader(ifp
, dst
->sa_family
, LLADDR(dl
),
1010 linkhdr
, &linkhdrsize
, &lladdr_off
) != 0) {
1011 lltable_free_entry(llt
, lle
);
1014 lltable_set_entry_addr(ifp
, lle
, linkhdr
, linkhdrsize
,
1016 if ((rtm
->rtm_flags
& RTF_ANNOUNCE
))
1017 lle
->la_flags
|= LLE_PUB
;
1018 lle
->la_expire
= rtm
->rtm_rmx
.rmx_expire
;
1020 laflags
= lle
->la_flags
;
1022 /* Try to link new entry */
1024 IF_AFDATA_WLOCK(ifp
);
1026 lle_tmp
= lla_lookup(llt
, LLE_EXCLUSIVE
, dst
);
1027 if (lle_tmp
!= NULL
) {
1028 /* Check if we are trying to replace immutable entry */
1029 if ((lle_tmp
->la_flags
& LLE_IFADDR
) != 0) {
1030 IF_AFDATA_WUNLOCK(ifp
);
1031 LLE_WUNLOCK(lle_tmp
);
1032 lltable_free_entry(llt
, lle
);
1035 /* Unlink existing entry from table */
1036 lltable_unlink_entry(llt
, lle_tmp
);
1038 lltable_link_entry(llt
, lle
);
1039 IF_AFDATA_WUNLOCK(ifp
);
1041 if (lle_tmp
!= NULL
) {
1042 EVENTHANDLER_INVOKE(lle_event
, lle_tmp
,LLENTRY_EXPIRED
);
1043 lltable_free_entry(llt
, lle_tmp
);
1047 * By invoking LLE handler here we might get
1048 * two events on static LLE entry insertion
1049 * in routing socket. However, since we might have
1050 * other subscribers we need to generate this event.
1052 EVENTHANDLER_INVOKE(lle_event
, lle
, LLENTRY_RESOLVED
);
1054 llt
->llt_post_resolved(llt
, lle
);
1058 return (lltable_delete_addr(llt
, 0, dst
));
1069 llatbl_lle_show(struct llentry
*lle
)
1072 sa_family_t af
= AF_UNSPEC
;
1073 char l3_addr_fmt
[] = " l3_addr=%s (af=%d)\n";
1075 db_printf("lle=%p\n", lle
);
1076 db_printf(" lle_next=%p\n", lle
->lle_next
.cle_next
);
1077 db_printf(" lle_lock=%p\n", &lle
->lle_lock
);
1078 db_printf(" lle_tbl=%p\n", lle
->lle_tbl
);
1079 db_printf(" lle_head=%p\n", lle
->lle_head
);
1080 db_printf(" la_hold=%p\n", lle
->la_hold
);
1081 db_printf(" la_numheld=%d\n", lle
->la_numheld
);
1082 db_printf(" la_expire=%ju\n", (uintmax_t)lle
->la_expire
);
1083 db_printf(" la_flags=0x%04x\n", lle
->la_flags
);
1084 db_printf(" la_asked=%u\n", lle
->la_asked
);
1085 db_printf(" la_preempt=%u\n", lle
->la_preempt
);
1086 db_printf(" ln_state=%d\n", lle
->ln_state
);
1087 db_printf(" ln_router=%u\n", lle
->ln_router
);
1088 db_printf(" ln_ntick=%ju\n", (uintmax_t)lle
->ln_ntick
);
1089 db_printf(" lle_refcnt=%d\n", lle
->lle_refcnt
);
1090 bcopy(lle
->ll_addr
, octet
, sizeof(octet
));
1091 db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
1092 octet
[0], octet
[1], octet
[2], octet
[3], octet
[4], octet
[5]);
1093 db_printf(" lle_timer=%p\n", &lle
->lle_timer
);
1096 af
= lle
->lle_tbl
->llt_af
;
1103 struct sockaddr_in sin
;
1104 char l3s
[INET_ADDRSTRLEN
];
1106 lltable_fill_sa_entry(lle
, (struct sockaddr
*)&sin
);
1107 (void) inet_ntop(af
, &sin
.sin_addr
, l3s
, sizeof(l3s
));
1108 db_printf(l3_addr_fmt
, l3s
, af
);
1115 struct sockaddr_in6 sin6
;
1116 char l3s
[INET6_ADDRSTRLEN
];
1118 lltable_fill_sa_entry(lle
, (struct sockaddr
*)&sin6
);
1119 (void) inet_ntop(af
, &sin6
.sin6_addr
, l3s
, sizeof(l3s
));
1120 db_printf(l3_addr_fmt
, l3s
, af
);
1125 db_printf(l3_addr_fmt
, "N/A", af
);
1130 DB_SHOW_COMMAND(llentry
, db_show_llentry
)
1134 db_printf("usage: show llentry <struct llentry *>\n");
1138 llatbl_lle_show((struct llentry
*)addr
);
1142 llatbl_llt_show(struct lltable
*llt
)
1145 struct llentry
*lle
;
1147 db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
1148 llt
, llt
->llt_af
, llt
->llt_ifp
);
1150 for (i
= 0; i
< llt
->llt_hsize
; i
++) {
1151 CK_LIST_FOREACH(lle
, &llt
->lle_head
[i
], lle_next
) {
1152 llatbl_lle_show(lle
);
1159 DB_SHOW_COMMAND(lltable
, db_show_lltable
)
1163 db_printf("usage: show lltable <struct lltable *>\n");
1167 llatbl_llt_show((struct lltable
*)addr
);
1170 DB_SHOW_ALL_COMMAND(lltables
, db_show_all_lltables
)
1172 VNET_ITERATOR_DECL(vnet_iter
);
1173 struct lltable
*llt
;
1175 VNET_FOREACH(vnet_iter
) {
1176 CURVNET_SET_QUIET(vnet_iter
);
1178 db_printf("vnet=%p\n", curvnet
);
1180 SLIST_FOREACH(llt
, &V_lltables
, llt_link
) {
1181 db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n",
1182 llt
, llt
->llt_af
, llt
->llt_ifp
,
1183 (llt
->llt_ifp
!= NULL
) ?
1184 llt
->llt_ifp
->if_xname
: "?");
1185 if (have_addr
&& addr
!= 0) /* verbose */
1186 llatbl_llt_show(llt
);
1187 if (db_pager_quit
) {