Date: Wed, 4 Mar 2020 17:17:02 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r358625 - head/sys/net Message-ID: <202003041717.024HH2eC081810@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Wed Mar 4 17:17:02 2020 New Revision: 358625 URL: https://svnweb.freebsd.org/changeset/base/358625 Log: Implement optional table entry limits for if_llatbl. Implement counting of table entries linked on a per-table base with an optional (if set > 0) limit of the maximum number of table entries. For that the public lltable_link_entry() and lltable_unlink_entry() functions as well as the internal function pointers change from void to having an int return type. Given no consumer currently sets the new llt_maxentries this can be committed on its own. The moment we make use of the table limits, the callers of the link function must check the return value as it can change and entries might not be added. Adjustments for IPv6 (and possibly IPv4) will follow. Sponsored by: Netflix (originally) Reviewed by: melifaro MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D22713 Modified: head/sys/net/if_llatbl.c head/sys/net/if_llatbl.h Modified: head/sys/net/if_llatbl.c ============================================================================== --- head/sys/net/if_llatbl.c Wed Mar 4 17:13:35 2020 (r358624) +++ head/sys/net/if_llatbl.c Wed Mar 4 17:17:02 2020 (r358625) @@ -153,17 +153,29 @@ htable_foreach_lle(struct lltable *llt, llt_foreach_cb 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) { struct llentries *lleh; uint32_t hashidx; if ((lle->la_flags & LLE_LINKED) != 0) - return; + return (0); 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); lleh = &llt->lle_head[hashidx]; @@ -171,22 +183,33 @@ htable_link_entry(struct lltable *llt, struct llentry lle->lle_head = lleh; lle->la_flags |= LLE_LINKED; CK_LIST_INSERT_HEAD(lleh, lle, lle_next); + llt->llt_entries++; + + return (1); } -static void +static int htable_unlink_entry(struct llentry *lle) { + struct lltable *llt; 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); lle->la_flags &= ~(LLE_VALID | LLE_LINKED); #if 0 lle->lle_tbl = NULL; lle->lle_head = NULL; #endif + llt->llt_entries--; + + return (1); } struct prefix_match_data { @@ -483,6 +506,9 @@ lltable_free(struct lltable *llt) 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); } @@ -608,18 +634,18 @@ lltable_free_entry(struct lltable *llt, struct llentry llt->llt_free_entry(llt, lle); } -void +int 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) { - llt->llt_unlink_entry(lle); + return (llt->llt_unlink_entry(lle)); } void Modified: head/sys/net/if_llatbl.h ============================================================================== --- head/sys/net/if_llatbl.h Wed Mar 4 17:13:35 2020 (r358624) +++ head/sys/net/if_llatbl.h Wed Mar 4 17:17:02 2020 (r358625) @@ -151,8 +151,8 @@ typedef int (llt_match_prefix_t)(const struct sockaddr 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 *); +typedef int (llt_link_entry_t)(struct lltable *, struct llentry *); +typedef int (llt_unlink_entry_t)(struct llentry *); typedef void (llt_mark_used_t)(struct llentry *); typedef int (llt_foreach_cb_t)(struct lltable *, struct llentry *, void *); @@ -162,6 +162,8 @@ struct lltable { SLIST_ENTRY(lltable) llt_link; int llt_af; int llt_hsize; + int llt_entries; + int llt_maxentries; struct llentries *lle_head; struct ifnet *llt_ifp; @@ -230,8 +232,8 @@ struct llentry *lltable_alloc_entry(struct lltable *ll void lltable_free_entry(struct lltable *llt, struct llentry *lle); int lltable_delete_addr(struct lltable *llt, u_int flags, const struct sockaddr *l3addr); -void lltable_link_entry(struct lltable *llt, struct llentry *lle); -void lltable_unlink_entry(struct lltable *llt, struct llentry *lle); +int lltable_link_entry(struct lltable *llt, struct llentry *lle); +int lltable_unlink_entry(struct lltable *llt, struct llentry *lle); void lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa); struct ifnet *lltable_get_ifp(const struct lltable *llt); int lltable_get_af(const struct lltable *llt);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202003041717.024HH2eC081810>