Changeset View
Changeset View
Standalone View
Standalone View
sys/net/if_llatbl.c
Show First 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | CK_LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
static void | /* | ||||
* The htable_[un]link_entry() functions return: | |||||
* 0 if the entry was (un)linked already and nothing changed, | |||||
* 1 if the entry was added/removed to/from the table, and | |||||
* -1 on error (e.g., not being able to add the entry due to limits reached). | |||||
* While the "unlink" operation should never error, callers of | |||||
* lltable_link_entry() need to check for errors and handle them. | |||||
*/ | |||||
static int | |||||
htable_link_entry(struct lltable *llt, struct llentry *lle) | htable_link_entry(struct lltable *llt, struct llentry *lle) | ||||
{ | { | ||||
struct llentries *lleh; | struct llentries *lleh; | ||||
uint32_t hashidx; | uint32_t hashidx; | ||||
if ((lle->la_flags & LLE_LINKED) != 0) | if ((lle->la_flags & LLE_LINKED) != 0) | ||||
return; | return (0); | ||||
IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); | IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); | ||||
if (llt->llt_maxentries > 0 && | |||||
llt->llt_entries >= llt->llt_maxentries) | |||||
return (-1); | |||||
hashidx = llt->llt_hash(lle, llt->llt_hsize); | hashidx = llt->llt_hash(lle, llt->llt_hsize); | ||||
lleh = &llt->lle_head[hashidx]; | lleh = &llt->lle_head[hashidx]; | ||||
lle->lle_tbl = llt; | lle->lle_tbl = llt; | ||||
lle->lle_head = lleh; | lle->lle_head = lleh; | ||||
lle->la_flags |= LLE_LINKED; | lle->la_flags |= LLE_LINKED; | ||||
CK_LIST_INSERT_HEAD(lleh, lle, lle_next); | CK_LIST_INSERT_HEAD(lleh, lle, lle_next); | ||||
llt->llt_entries++; | |||||
return (1); | |||||
} | } | ||||
static void | static int | ||||
htable_unlink_entry(struct llentry *lle) | htable_unlink_entry(struct llentry *lle) | ||||
{ | { | ||||
struct lltable *llt; | |||||
if ((lle->la_flags & LLE_LINKED) == 0) | if ((lle->la_flags & LLE_LINKED) == 0) | ||||
return; | return (0); | ||||
IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp); | llt = lle->lle_tbl; | ||||
IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); | |||||
KASSERT(llt->llt_entries > 0, ("%s: lltable %p (%s) entries %d <= 0", | |||||
__func__, llt, if_name(llt->llt_ifp), llt->llt_entries)); | |||||
CK_LIST_REMOVE(lle, lle_next); | CK_LIST_REMOVE(lle, lle_next); | ||||
lle->la_flags &= ~(LLE_VALID | LLE_LINKED); | lle->la_flags &= ~(LLE_VALID | LLE_LINKED); | ||||
#if 0 | #if 0 | ||||
lle->lle_tbl = NULL; | lle->lle_tbl = NULL; | ||||
lle->lle_head = NULL; | lle->lle_head = NULL; | ||||
#endif | #endif | ||||
llt->llt_entries--; | |||||
return (1); | |||||
} | } | ||||
struct prefix_match_data { | struct prefix_match_data { | ||||
const struct sockaddr *addr; | const struct sockaddr *addr; | ||||
const struct sockaddr *mask; | const struct sockaddr *mask; | ||||
struct llentries dchain; | struct llentries dchain; | ||||
u_int flags; | u_int flags; | ||||
}; | }; | ||||
▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | lltable_free(struct lltable *llt) | ||||
lltable_foreach_lle(llt, lltable_free_cb, &dchain); | lltable_foreach_lle(llt, lltable_free_cb, &dchain); | ||||
llentries_unlink(llt, &dchain); | llentries_unlink(llt, &dchain); | ||||
IF_AFDATA_WUNLOCK(llt->llt_ifp); | IF_AFDATA_WUNLOCK(llt->llt_ifp); | ||||
CK_LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) { | CK_LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) { | ||||
llentry_free(lle); | llentry_free(lle); | ||||
} | } | ||||
KASSERT(llt->llt_entries == 0, ("%s: lltable %p (%s) entires not 0: %d", | |||||
__func__, llt, llt->llt_ifp->if_xname, llt->llt_entries)); | |||||
llt->llt_free_tbl(llt); | llt->llt_free_tbl(llt); | ||||
} | } | ||||
/* | /* | ||||
* Deletes an address from given lltable. | * Deletes an address from given lltable. | ||||
* Used for userland interaction to remove | * Used for userland interaction to remove | ||||
* individual entries. Skips entries added by OS. | * individual entries. Skips entries added by OS. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
lltable_free_entry(struct lltable *llt, struct llentry *lle) | lltable_free_entry(struct lltable *llt, struct llentry *lle) | ||||
{ | { | ||||
llt->llt_free_entry(llt, lle); | llt->llt_free_entry(llt, lle); | ||||
} | } | ||||
void | int | ||||
lltable_link_entry(struct lltable *llt, struct llentry *lle) | lltable_link_entry(struct lltable *llt, struct llentry *lle) | ||||
{ | { | ||||
llt->llt_link_entry(llt, lle); | return (llt->llt_link_entry(llt, lle)); | ||||
} | } | ||||
void | int | ||||
lltable_unlink_entry(struct lltable *llt, struct llentry *lle) | lltable_unlink_entry(struct lltable *llt, struct llentry *lle) | ||||
{ | { | ||||
llt->llt_unlink_entry(lle); | return (llt->llt_unlink_entry(lle)); | ||||
} | } | ||||
void | void | ||||
lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa) | lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa) | ||||
{ | { | ||||
struct lltable *llt; | struct lltable *llt; | ||||
llt = lle->lle_tbl; | llt = lle->lle_tbl; | ||||
▲ Show 20 Lines • Show All 263 Lines • Show Last 20 Lines |