mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Do not enforce particular lle storage scheme:
* move lltable allocation to per-domain callbacks. * make llentry_link/unlink functions overridable llt methods. * make hash table traversal another overridable llt method.
This commit is contained in:
parent
a743ccd468
commit
721cd2e032
7 changed files with 193 additions and 89 deletions
|
|
@ -71,14 +71,46 @@ static void vnet_lltable_init(void);
|
|||
struct rwlock lltable_rwlock;
|
||||
RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
|
||||
|
||||
static void lltable_unlink(struct lltable *llt);
|
||||
static void llentries_unlink(struct lltable *llt, struct llentries *head);
|
||||
/* Default lltable methods */
|
||||
static void llentry_link(struct lltable *llt, struct llentry *lle);
|
||||
static void llentry_unlink(struct llentry *lle);
|
||||
static int lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
|
||||
void *farg);
|
||||
static void lltable_free_tbl(struct lltable *llt);
|
||||
|
||||
/*
|
||||
* Runs specified callback for each entry in @llt.
|
||||
* Called does the locking.
|
||||
*
|
||||
*/
|
||||
static int
|
||||
lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
|
||||
{
|
||||
struct llentry *lle, *next;
|
||||
int i, error;
|
||||
|
||||
error = 0;
|
||||
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
error = f(llt, lle, farg);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Dump lle state for a specific address family.
|
||||
*/
|
||||
static int
|
||||
lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
|
||||
{
|
||||
struct llentry *lle;
|
||||
int i, error;
|
||||
int error;
|
||||
|
||||
LLTABLE_LOCK_ASSERT();
|
||||
|
||||
|
|
@ -87,13 +119,8 @@ lltable_dump_af(struct lltable *llt, struct sysctl_req *wr)
|
|||
error = 0;
|
||||
|
||||
IF_AFDATA_CFG_RLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
|
||||
error = llt->llt_dump_entry(llt, lle, wr);
|
||||
if (error != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
error = lltable_foreach_lle(llt,
|
||||
(llt_foreach_cb_t *)llt->llt_dump_entry, wr);
|
||||
IF_AFDATA_CFG_RUNLOCK(llt->llt_ifp);
|
||||
|
||||
return (error);
|
||||
|
|
@ -119,7 +146,7 @@ done:
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
static void
|
||||
llentry_link(struct lltable *llt, struct llentry *lle)
|
||||
{
|
||||
struct llentries *lleh;
|
||||
|
|
@ -139,7 +166,7 @@ llentry_link(struct lltable *llt, struct llentry *lle)
|
|||
LIST_INSERT_HEAD(lleh, lle, lle_next);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
llentry_unlink(struct llentry *lle)
|
||||
{
|
||||
|
||||
|
|
@ -152,14 +179,13 @@ llentry_unlink(struct llentry *lle)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
llentries_unlink(struct llentries *head)
|
||||
static void
|
||||
llentries_unlink(struct lltable *llt, struct llentries *head)
|
||||
{
|
||||
struct llentry *lle, *next;
|
||||
|
||||
LIST_FOREACH_SAFE(lle, head, lle_chain, next) {
|
||||
llentry_unlink(lle);
|
||||
}
|
||||
LIST_FOREACH_SAFE(lle, head, lle_chain, next)
|
||||
llt->llt_unlink_entry(lle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -236,36 +262,73 @@ llentry_alloc(struct ifnet *ifp, struct lltable *lt,
|
|||
/*
|
||||
* Free all entries from given table and free itself.
|
||||
*/
|
||||
|
||||
static int
|
||||
lltable_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
|
||||
{
|
||||
struct llentries *dchain;
|
||||
|
||||
dchain = (struct llentries *)farg;
|
||||
|
||||
LLE_WLOCK(lle);
|
||||
LIST_INSERT_HEAD(dchain, lle, lle_chain);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
lltable_free_tbl(struct lltable *llt)
|
||||
{
|
||||
|
||||
free(llt, M_LLTABLE);
|
||||
}
|
||||
|
||||
void
|
||||
lltable_free(struct lltable *llt)
|
||||
{
|
||||
struct llentry *lle, *next;
|
||||
struct llentries dchain;
|
||||
int i;
|
||||
|
||||
KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
|
||||
|
||||
LLTABLE_WLOCK();
|
||||
SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
|
||||
LLTABLE_WUNLOCK();
|
||||
lltable_unlink(llt);
|
||||
|
||||
LIST_INIT(&dchain);
|
||||
IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
LLE_WLOCK(lle);
|
||||
LIST_INSERT_HEAD(&dchain, lle, lle_chain);
|
||||
}
|
||||
}
|
||||
/* Push all lles to @dchain */
|
||||
lltable_foreach_lle(llt, lltable_free_cb, &dchain);
|
||||
|
||||
IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
|
||||
llentries_unlink(&dchain);
|
||||
llentries_unlink(llt, &dchain);
|
||||
IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
|
||||
IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
|
||||
|
||||
LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
|
||||
llt->llt_clear_entry(llt, lle);
|
||||
|
||||
free(llt, M_LLTABLE);
|
||||
llt->llt_free_tbl(llt);
|
||||
}
|
||||
|
||||
struct prefix_match_data {
|
||||
const struct sockaddr *prefix;
|
||||
const struct sockaddr *mask;
|
||||
struct llentries *dchain;
|
||||
u_int flags;
|
||||
};
|
||||
|
||||
static int
|
||||
lltable_prefix_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
|
||||
{
|
||||
struct prefix_match_data *pmd;
|
||||
|
||||
pmd = (struct prefix_match_data *)farg;
|
||||
|
||||
if (llt->llt_match_prefix(pmd->prefix, pmd->mask, pmd->flags, lle)) {
|
||||
LLE_WLOCK(lle);
|
||||
LIST_INSERT_HEAD(pmd->dchain, lle, lle_chain);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -274,20 +337,21 @@ lltable_prefix_free_af(struct lltable *llt, const struct sockaddr *prefix,
|
|||
{
|
||||
struct llentries dchain;
|
||||
struct llentry *lle, *next;
|
||||
int i;
|
||||
struct prefix_match_data pmd;
|
||||
|
||||
LIST_INIT(&dchain);
|
||||
memset(&pmd, 0, sizeof(pmd));
|
||||
pmd.prefix = prefix;
|
||||
pmd.mask = mask;
|
||||
pmd.flags = flags;
|
||||
pmd.dchain = &dchain;
|
||||
|
||||
IF_AFDATA_CFG_WLOCK(llt->llt_ifp);
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
if (llt->llt_match_prefix(prefix, mask, flags, lle)) {
|
||||
LLE_WLOCK(lle);
|
||||
LIST_INSERT_HEAD(&dchain, lle, lle_chain);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Push matching lles to chain */
|
||||
lltable_foreach_lle(llt, lltable_prefix_free_cb, &pmd);
|
||||
|
||||
IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
|
||||
llentries_unlink(&dchain);
|
||||
llentries_unlink(llt, &dchain);
|
||||
IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
|
||||
IF_AFDATA_CFG_WUNLOCK(llt->llt_ifp);
|
||||
|
||||
|
|
@ -339,29 +403,36 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask,
|
|||
LLTABLE_RUNLOCK();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Create a new lltable.
|
||||
* Links lltable to global llt list.
|
||||
*/
|
||||
struct lltable *
|
||||
lltable_init(struct ifnet *ifp, int af)
|
||||
void
|
||||
lltable_link(struct lltable *llt)
|
||||
{
|
||||
struct lltable *llt;
|
||||
register int i;
|
||||
|
||||
llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK);
|
||||
|
||||
llt->llt_af = af;
|
||||
llt->llt_ifp = ifp;
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
|
||||
LIST_INIT(&llt->lle_head[i]);
|
||||
/* Provide default verions of hash table methods */
|
||||
if (llt->llt_link_entry == NULL)
|
||||
llt->llt_link_entry = llentry_link;
|
||||
if (llt->llt_unlink_entry == NULL)
|
||||
llt->llt_unlink_entry = llentry_unlink;
|
||||
if (llt->llt_foreach_entry == NULL)
|
||||
llt->llt_foreach_entry = lltable_foreach_lle;
|
||||
if (llt->llt_free_tbl == NULL)
|
||||
llt->llt_free_tbl = lltable_free_tbl;
|
||||
|
||||
LLTABLE_WLOCK();
|
||||
SLIST_INSERT_HEAD(&V_lltables, llt, llt_link);
|
||||
LLTABLE_WUNLOCK();
|
||||
}
|
||||
|
||||
static void
|
||||
lltable_unlink(struct lltable *llt)
|
||||
{
|
||||
|
||||
LLTABLE_WLOCK();
|
||||
SLIST_REMOVE(&V_lltables, llt, lltable, llt_link);
|
||||
LLTABLE_WUNLOCK();
|
||||
|
||||
return (llt);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -159,6 +159,13 @@ typedef uint32_t (llt_hash_t)(const struct llentry *);
|
|||
typedef int (llt_match_prefix_t)(const struct sockaddr *,
|
||||
const struct sockaddr *, u_int, struct llentry *);
|
||||
typedef void (llt_clear_entry_t)(struct lltable *, struct llentry *);
|
||||
typedef void (llt_free_tbl_t)(struct lltable *);
|
||||
typedef void (llt_link_entry_t)(struct lltable *, struct llentry *);
|
||||
typedef void (llt_unlink_entry_t)(struct llentry *);
|
||||
|
||||
typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *);
|
||||
typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
|
||||
|
||||
|
||||
struct lltable {
|
||||
SLIST_ENTRY(lltable) llt_link;
|
||||
|
|
@ -173,6 +180,10 @@ struct lltable {
|
|||
llt_hash_t *llt_hash;
|
||||
llt_match_prefix_t *llt_match_prefix;
|
||||
llt_clear_entry_t *llt_clear_entry;
|
||||
llt_foreach_entry_t *llt_foreach_entry;
|
||||
llt_link_entry_t *llt_link_entry;
|
||||
llt_unlink_entry_t *llt_unlink_entry;
|
||||
llt_free_tbl_t *llt_free_tbl;
|
||||
};
|
||||
|
||||
MALLOC_DECLARE(M_LLTABLE);
|
||||
|
|
@ -199,7 +210,7 @@ MALLOC_DECLARE(M_LLTABLE);
|
|||
#define LLATBL_HASH(key, mask) \
|
||||
(((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
|
||||
|
||||
struct lltable *lltable_init(struct ifnet *, int);
|
||||
void lltable_link(struct lltable *);
|
||||
void lltable_free(struct lltable *);
|
||||
void lltable_prefix_free(int, struct sockaddr *,
|
||||
struct sockaddr *, u_int);
|
||||
|
|
@ -208,9 +219,6 @@ void lltable_drain(int);
|
|||
#endif
|
||||
int lltable_sysctl_dumparp(int, struct sysctl_req *);
|
||||
|
||||
void llentry_link(struct lltable *, struct llentry *);
|
||||
void llentry_unlink(struct llentry *);
|
||||
void llentries_unlink(struct llentries *);
|
||||
size_t llentry_free(struct llentry *);
|
||||
struct llentry *llentry_alloc(struct ifnet *, struct lltable *,
|
||||
struct sockaddr_storage *);
|
||||
|
|
@ -242,6 +250,19 @@ lltable_delete_lle(struct lltable *llt, u_int flags,
|
|||
return llt->llt_delete(llt, flags, l3addr);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
lltable_link_entry(struct lltable *llt, struct llentry *lle)
|
||||
{
|
||||
|
||||
llt->llt_link_entry(llt, lle);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
lltable_unlink_entry(struct lltable *llt, struct llentry *lle)
|
||||
{
|
||||
|
||||
llt->llt_unlink_entry(lle);
|
||||
}
|
||||
|
||||
int lla_rt_output(struct rt_msghdr *, struct rt_addrinfo *);
|
||||
|
||||
|
|
|
|||
|
|
@ -291,7 +291,7 @@ arp_lltable_clear_entry(struct lltable *llt, struct llentry *lle)
|
|||
LLE_REMREF(lle);
|
||||
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_unlink(lle);
|
||||
lltable_unlink_entry(llt, lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
|
@ -544,7 +544,7 @@ arpresolve_slow(struct ifnet *ifp, int is_gw, struct mbuf *m,
|
|||
* No entry has been found. Link new one.
|
||||
*/
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_link(LLTABLE(ifp), la);
|
||||
lltable_link_entry(LLTABLE(ifp), la);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
}
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
|
@ -1076,7 +1076,7 @@ arp_update_lle_addr(struct arphdr *ah, struct ifnet *ifp, struct llentry *la)
|
|||
la->r_flags |= RLLE_VALID;
|
||||
if ((la->la_flags & LLE_STATIC) == 0)
|
||||
la->la_expire = time_uptime + V_arpt_keep;
|
||||
llentry_link(LLTABLE(ifp), la);
|
||||
lltable_link_entry(LLTABLE(ifp), la);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
}
|
||||
|
||||
|
|
@ -1254,7 +1254,7 @@ arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
|
|||
bcopy(IF_LLADDR(ifp), &lle->ll_addr, ifp->if_addrlen);
|
||||
lle->la_flags |= (LLE_VALID | LLE_STATIC);
|
||||
lle->r_flags |= RLLE_VALID;
|
||||
llentry_link(LLTABLE(ifp), lle);
|
||||
lltable_link_entry(LLTABLE(ifp), lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
|
|
|||
|
|
@ -1154,7 +1154,7 @@ in_lltable_delete(struct lltable *llt, u_int flags,
|
|||
lle->la_flags |= LLE_DELETED;
|
||||
EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_unlink(lle);
|
||||
lltable_unlink_entry(llt, lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
#ifdef DIAGNOSTIC
|
||||
log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
|
||||
|
|
@ -1294,21 +1294,25 @@ in_domifattach(struct ifnet *ifp)
|
|||
{
|
||||
struct in_ifinfo *ii;
|
||||
struct lltable *llt;
|
||||
int i;
|
||||
|
||||
llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
|
||||
llt->llt_af = AF_INET;
|
||||
llt->llt_ifp = ifp;
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
|
||||
LIST_INIT(&llt->lle_head[i]);
|
||||
|
||||
llt->llt_lookup = in_lltable_lookup;
|
||||
llt->llt_create = in_lltable_create;
|
||||
llt->llt_delete = in_lltable_delete;
|
||||
llt->llt_dump_entry = in_lltable_dump_entry;
|
||||
llt->llt_hash = in_lltable_hash;
|
||||
llt->llt_clear_entry = arp_lltable_clear_entry;
|
||||
llt->llt_match_prefix = in_lltable_match_prefix;
|
||||
lltable_link(llt);
|
||||
|
||||
ii = malloc(sizeof(struct in_ifinfo), M_IFADDR, M_WAITOK|M_ZERO);
|
||||
|
||||
llt = lltable_init(ifp, AF_INET);
|
||||
if (llt != NULL) {
|
||||
llt->llt_lookup = in_lltable_lookup;
|
||||
llt->llt_create = in_lltable_create;
|
||||
llt->llt_delete = in_lltable_delete;
|
||||
llt->llt_dump_entry = in_lltable_dump_entry;
|
||||
llt->llt_hash = in_lltable_hash;
|
||||
llt->llt_clear_entry = arp_lltable_clear_entry;
|
||||
llt->llt_match_prefix = in_lltable_match_prefix;
|
||||
}
|
||||
ii->ii_llt = llt;
|
||||
|
||||
ii->ii_igmp = igmp_domifattach(ifp);
|
||||
|
||||
return ii;
|
||||
|
|
|
|||
|
|
@ -477,7 +477,7 @@ restart:
|
|||
* No entry has been found. Link new one.
|
||||
*/
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_link(LLTABLE6(ifp), lle);
|
||||
lltable_link_entry(LLTABLE6(ifp), lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
}
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
|
|
|||
|
|
@ -2188,7 +2188,7 @@ in6_lltable_delete(struct lltable *llt, u_int flags,
|
|||
LLE_WLOCK(lle);
|
||||
lle->la_flags |= LLE_DELETED;
|
||||
IF_AFDATA_RUN_WLOCK(llt->llt_ifp);
|
||||
llentry_unlink(lle);
|
||||
lltable_unlink_entry(llt, lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(llt->llt_ifp);
|
||||
#ifdef DIAGNOSTIC
|
||||
log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
|
||||
|
|
@ -2330,6 +2330,8 @@ void *
|
|||
in6_domifattach(struct ifnet *ifp)
|
||||
{
|
||||
struct in6_ifextra *ext;
|
||||
struct lltable *llt;
|
||||
int i;
|
||||
|
||||
/* There are not IPv6-capable interfaces. */
|
||||
switch (ifp->if_type) {
|
||||
|
|
@ -2354,16 +2356,22 @@ in6_domifattach(struct ifnet *ifp)
|
|||
|
||||
ext->nd_ifinfo = nd6_ifattach(ifp);
|
||||
ext->scope6_id = scope6_ifattach(ifp);
|
||||
ext->lltable = lltable_init(ifp, AF_INET6);
|
||||
if (ext->lltable != NULL) {
|
||||
ext->lltable->llt_lookup = in6_lltable_lookup;
|
||||
ext->lltable->llt_create = in6_lltable_create;
|
||||
ext->lltable->llt_delete = in6_lltable_delete;
|
||||
ext->lltable->llt_dump_entry = in6_lltable_dump_entry;
|
||||
ext->lltable->llt_hash = in6_lltable_hash;
|
||||
ext->lltable->llt_clear_entry = nd6_lltable_clear_entry;
|
||||
ext->lltable->llt_match_prefix = in6_lltable_match_prefix;
|
||||
}
|
||||
|
||||
llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
|
||||
llt->llt_af = AF_INET6;
|
||||
llt->llt_ifp = ifp;
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
|
||||
LIST_INIT(&llt->lle_head[i]);
|
||||
|
||||
llt->llt_lookup = in6_lltable_lookup;
|
||||
llt->llt_create = in6_lltable_create;
|
||||
llt->llt_delete = in6_lltable_delete;
|
||||
llt->llt_dump_entry = in6_lltable_dump_entry;
|
||||
llt->llt_hash = in6_lltable_hash;
|
||||
llt->llt_clear_entry = nd6_lltable_clear_entry;
|
||||
llt->llt_match_prefix = in6_lltable_match_prefix;
|
||||
lltable_link(llt);
|
||||
ext->lltable = llt;
|
||||
|
||||
ext->mld_ifinfo = mld_domifattach(ifp);
|
||||
|
||||
|
|
|
|||
|
|
@ -1120,7 +1120,7 @@ nd6_lltable_clear_entry(struct lltable *llt, struct llentry *ln)
|
|||
LLE_REMREF(ln);
|
||||
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_unlink(ln);
|
||||
lltable_unlink_entry(llt, ln);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
|
@ -1892,7 +1892,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
|
|||
if (r_update != 0) {
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
if (is_newentry != 0)
|
||||
llentry_link(LLTABLE6(ifp), ln);
|
||||
lltable_link_entry(LLTABLE6(ifp), ln);
|
||||
if (lladdr != NULL) {
|
||||
bcopy(lladdr, &ln->ll_addr, ifp->if_addrlen);
|
||||
ln->la_flags |= LLE_VALID;
|
||||
|
|
@ -2197,7 +2197,7 @@ nd6_output_lle(struct ifnet *ifp, struct ifnet *origifp, struct mbuf *m,
|
|||
* Link new one.
|
||||
*/
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_link(LLTABLE6(ifp), lle);
|
||||
lltable_link_entry(LLTABLE6(ifp), lle);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
}
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
|
@ -2485,7 +2485,7 @@ nd6_add_ifa_lle(struct in6_ifaddr *ia)
|
|||
bcopy(IF_LLADDR(ifp), &ln->ll_addr, ifp->if_addrlen);
|
||||
/* Finally, link our lle to the list */
|
||||
IF_AFDATA_RUN_WLOCK(ifp);
|
||||
llentry_link(LLTABLE6(ifp), ln);
|
||||
lltable_link_entry(LLTABLE6(ifp), ln);
|
||||
IF_AFDATA_RUN_WUNLOCK(ifp);
|
||||
IF_AFDATA_CFG_WUNLOCK(ifp);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue