MFP r276712.
* Split lltable_init() into lltable_allocate_htbl() (alloc hash table with default callbacks) and lltable_link() ( links any lltable to the list). * Switch from LLTBL_HASHTBL_SIZE to per-lltable hash size field. * Move lltable setup to separate functions in in[6]_domifattach.
This commit is contained in:
commit
41cb42a633
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286616
@ -70,6 +70,7 @@ 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);
|
||||
|
||||
static void htable_unlink_entry(struct llentry *lle);
|
||||
@ -138,7 +139,7 @@ htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
|
||||
|
||||
error = 0;
|
||||
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
for (i = 0; i < llt->llt_hsize; i++) {
|
||||
LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
|
||||
error = f(llt, lle, farg);
|
||||
if (error != 0)
|
||||
@ -160,7 +161,7 @@ htable_link_entry(struct lltable *llt, struct llentry *lle)
|
||||
|
||||
IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
|
||||
|
||||
hashidx = llt->llt_hash(lle, LLTBL_HASHTBL_SIZE);
|
||||
hashidx = llt->llt_hash(lle, llt->llt_hsize);
|
||||
lleh = &llt->lle_head[hashidx];
|
||||
|
||||
lle->lle_tbl = llt;
|
||||
@ -230,6 +231,14 @@ htable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
|
||||
llt->llt_free_entry(llt, lle);
|
||||
}
|
||||
|
||||
static void
|
||||
htable_free_tbl(struct lltable *llt)
|
||||
{
|
||||
|
||||
free(llt->lle_head, M_LLTABLE);
|
||||
free(llt, M_LLTABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
llentries_unlink(struct lltable *llt, struct llentries *head)
|
||||
{
|
||||
@ -355,9 +364,7 @@ lltable_free(struct lltable *llt)
|
||||
|
||||
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_WLOCK(llt->llt_ifp);
|
||||
@ -372,7 +379,7 @@ lltable_free(struct lltable *llt)
|
||||
llentry_free(lle);
|
||||
}
|
||||
|
||||
free(llt, M_LLTABLE);
|
||||
llt->llt_free_tbl(llt);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -388,7 +395,7 @@ lltable_drain(int af)
|
||||
if (llt->llt_af != af)
|
||||
continue;
|
||||
|
||||
for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
for (i=0; i < llt->llt_hsize; i++) {
|
||||
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
|
||||
LLE_WLOCK(lle);
|
||||
if (lle->la_hold) {
|
||||
@ -419,20 +426,18 @@ lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask,
|
||||
LLTABLE_RUNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new lltable.
|
||||
*/
|
||||
struct lltable *
|
||||
lltable_init(struct ifnet *ifp, int af)
|
||||
lltable_allocate_htbl(uint32_t hsize)
|
||||
{
|
||||
struct lltable *llt;
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK);
|
||||
llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
|
||||
llt->llt_hsize = hsize;
|
||||
llt->lle_head = malloc(sizeof(struct llentries) * hsize,
|
||||
M_LLTABLE, M_WAITOK | M_ZERO);
|
||||
|
||||
llt->llt_af = af;
|
||||
llt->llt_ifp = ifp;
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
|
||||
for (i = 0; i < llt->llt_hsize; i++)
|
||||
LIST_INIT(&llt->lle_head[i]);
|
||||
|
||||
/* Set some default callbacks */
|
||||
@ -440,12 +445,31 @@ lltable_init(struct ifnet *ifp, int af)
|
||||
llt->llt_unlink_entry = htable_unlink_entry;
|
||||
llt->llt_prefix_free = htable_prefix_free;
|
||||
llt->llt_foreach_entry = htable_foreach_lle;
|
||||
llt->llt_free_tbl = htable_free_tbl;
|
||||
|
||||
return (llt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Links lltable to global llt list.
|
||||
*/
|
||||
void
|
||||
lltable_link(struct lltable *llt)
|
||||
{
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -685,7 +709,7 @@ llatbl_llt_show(struct lltable *llt)
|
||||
db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
|
||||
llt, llt->llt_af, llt->llt_ifp);
|
||||
|
||||
for (i = 0; i < LLTBL_HASHTBL_SIZE; i++) {
|
||||
for (i = 0; i < llt->llt_hsize; i++) {
|
||||
LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
|
||||
|
||||
llatbl_lle_show((struct llentry_sa *)lle);
|
||||
|
@ -138,14 +138,6 @@ struct llentry {
|
||||
#define L3_ADDR(lle) ((struct sockaddr *)(&lle[1]))
|
||||
#define L3_ADDR_LEN(lle) (((struct sockaddr *)(&lle[1]))->sa_len)
|
||||
|
||||
#ifndef LLTBL_HASHTBL_SIZE
|
||||
#define LLTBL_HASHTBL_SIZE 32 /* default 32 ? */
|
||||
#endif
|
||||
|
||||
#ifndef LLTBL_HASHMASK
|
||||
#define LLTBL_HASHMASK (LLTBL_HASHTBL_SIZE - 1)
|
||||
#endif
|
||||
|
||||
typedef struct llentry *(llt_lookup_t)(struct lltable *, u_int flags,
|
||||
const struct sockaddr *l3addr);
|
||||
typedef struct llentry *(llt_create_t)(struct lltable *, u_int flags,
|
||||
@ -161,6 +153,7 @@ typedef int (llt_match_prefix_t)(const struct sockaddr *,
|
||||
const struct sockaddr *, u_int, struct llentry *);
|
||||
typedef void (llt_free_entry_t)(struct lltable *, struct llentry *);
|
||||
typedef void (llt_fill_sa_entry_t)(const struct llentry *, struct sockaddr *);
|
||||
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 *);
|
||||
|
||||
@ -169,8 +162,9 @@ typedef int (llt_foreach_entry_t)(struct lltable *, llt_foreach_cb_t *, void *);
|
||||
|
||||
struct lltable {
|
||||
SLIST_ENTRY(lltable) llt_link;
|
||||
struct llentries lle_head[LLTBL_HASHTBL_SIZE];
|
||||
int llt_af;
|
||||
int llt_hsize;
|
||||
struct llentries *lle_head;
|
||||
struct ifnet *llt_ifp;
|
||||
|
||||
llt_lookup_t *llt_lookup;
|
||||
@ -185,6 +179,7 @@ struct lltable {
|
||||
llt_link_entry_t *llt_link_entry;
|
||||
llt_unlink_entry_t *llt_unlink_entry;
|
||||
llt_fill_sa_entry_t *llt_fill_sa_entry;
|
||||
llt_free_tbl_t *llt_free_tbl;
|
||||
};
|
||||
|
||||
MALLOC_DECLARE(M_LLTABLE);
|
||||
@ -204,8 +199,9 @@ MALLOC_DECLARE(M_LLTABLE);
|
||||
#define LLATBL_HASH(key, mask) \
|
||||
(((((((key >> 8) ^ key) >> 8) ^ key) >> 8) ^ key) & mask)
|
||||
|
||||
struct lltable *lltable_init(struct ifnet *, int);
|
||||
struct lltable *lltable_allocate_htbl(uint32_t hsize);
|
||||
void lltable_free(struct lltable *);
|
||||
void lltable_link(struct lltable *llt);
|
||||
void lltable_prefix_free(int, struct sockaddr *,
|
||||
struct sockaddr *, u_int);
|
||||
#if 0
|
||||
|
@ -1159,7 +1159,7 @@ in_lltable_find_dst(struct lltable *llt, struct in_addr dst)
|
||||
struct sockaddr_in *sin;
|
||||
u_int hashidx;
|
||||
|
||||
hashidx = in_lltable_hash_dst(dst, LLTBL_HASHTBL_SIZE);
|
||||
hashidx = in_lltable_hash_dst(dst, llt->llt_hsize);
|
||||
lleh = &llt->lle_head[hashidx];
|
||||
LIST_FOREACH(lle, lleh, lle_next) {
|
||||
sin = satosin(L3_ADDR(lle));
|
||||
@ -1342,30 +1342,39 @@ in_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
return (error);
|
||||
}
|
||||
|
||||
static struct lltable *
|
||||
in_lltattach(struct ifnet *ifp)
|
||||
{
|
||||
struct lltable *llt;
|
||||
|
||||
llt = lltable_allocate_htbl(IN_LLTBL_DEFAULT_HSIZE);
|
||||
llt->llt_af = AF_INET;
|
||||
llt->llt_ifp = ifp;
|
||||
|
||||
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_fill_sa_entry = in_lltable_fill_sa_entry;
|
||||
llt->llt_free_entry = in_lltable_free_entry;
|
||||
llt->llt_match_prefix = in_lltable_match_prefix;
|
||||
lltable_link(llt);
|
||||
|
||||
return (llt);
|
||||
}
|
||||
|
||||
void *
|
||||
in_domifattach(struct ifnet *ifp)
|
||||
{
|
||||
struct in_ifinfo *ii;
|
||||
struct lltable *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_fill_sa_entry = in_lltable_fill_sa_entry;
|
||||
llt->llt_free_entry = in_lltable_free_entry;
|
||||
llt->llt_match_prefix = in_lltable_match_prefix;
|
||||
}
|
||||
ii->ii_llt = llt;
|
||||
|
||||
ii->ii_llt = in_lltattach(ifp);
|
||||
ii->ii_igmp = igmp_domifattach(ifp);
|
||||
|
||||
return ii;
|
||||
return (ii);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2199,7 +2199,7 @@ in6_lltable_find_dst(struct lltable *llt, const struct in6_addr *dst)
|
||||
const struct sockaddr_in6 *sin6;
|
||||
u_int hashidx;
|
||||
|
||||
hashidx = in6_lltable_hash_dst(dst, LLTBL_HASHTBL_SIZE);
|
||||
hashidx = in6_lltable_hash_dst(dst, llt->llt_hsize);
|
||||
lleh = &llt->lle_head[hashidx];
|
||||
LIST_FOREACH(lle, lleh, lle_next) {
|
||||
sin6 = (const struct sockaddr_in6 *)L3_CADDR(lle);
|
||||
@ -2378,6 +2378,28 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle,
|
||||
return (error);
|
||||
}
|
||||
|
||||
static struct lltable *
|
||||
in6_lltattach(struct ifnet *ifp)
|
||||
{
|
||||
struct lltable *llt;
|
||||
|
||||
llt = lltable_allocate_htbl(IN6_LLTBL_DEFAULT_HSIZE);
|
||||
llt->llt_af = AF_INET6;
|
||||
llt->llt_ifp = ifp;
|
||||
|
||||
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_fill_sa_entry = in6_lltable_fill_sa_entry;
|
||||
llt->llt_free_entry = in6_lltable_free_entry;
|
||||
llt->llt_match_prefix = in6_lltable_match_prefix;
|
||||
lltable_link(llt);
|
||||
|
||||
return (llt);
|
||||
}
|
||||
|
||||
void *
|
||||
in6_domifattach(struct ifnet *ifp)
|
||||
{
|
||||
@ -2406,17 +2428,7 @@ 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_fill_sa_entry = in6_lltable_fill_sa_entry;
|
||||
ext->lltable->llt_free_entry = in6_lltable_free_entry;
|
||||
ext->lltable->llt_match_prefix = in6_lltable_match_prefix;
|
||||
}
|
||||
ext->lltable = in6_lltattach(ifp);
|
||||
|
||||
ext->mld_ifinfo = mld_domifattach(ifp);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user