To support upcoming changes change internal API for source node handling:
- Removed pf_remove_src_node(). - Introduce pf_unlink_src_node() and pf_unlink_src_node_locked(). These function do not proceed with freeing of a node, just disconnect it from storage. - New function pf_free_src_nodes() works on a list of previously disconnected nodes and frees them. - Utilize new API in pf_purge_expired_src_nodes(). In collaboration with: Kajetan Staszkiewicz <kajetan.staszkiewicz innogames.de> Sponsored by: InnoGames GmbH Sponsored by: Nginx, Inc.
This commit is contained in:
parent
3260ae00be
commit
d77c1b3269
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=258479
@ -1467,8 +1467,9 @@ struct pf_ifspeed {
|
||||
#define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed)
|
||||
|
||||
#ifdef _KERNEL
|
||||
LIST_HEAD(pf_src_node_list, pf_src_node);
|
||||
struct pf_srchash {
|
||||
LIST_HEAD(, pf_src_node) nodes;
|
||||
struct pf_src_node_list nodes;
|
||||
struct mtx lock;
|
||||
};
|
||||
|
||||
@ -1576,6 +1577,9 @@ extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *,
|
||||
u_int, int *);
|
||||
extern struct pf_src_node *pf_find_src_node(struct pf_addr *,
|
||||
struct pf_rule *, sa_family_t, int);
|
||||
extern void pf_unlink_src_node(struct pf_src_node *);
|
||||
extern void pf_unlink_src_node_locked(struct pf_src_node *);
|
||||
extern u_int pf_free_src_nodes(struct pf_src_node_list *);
|
||||
extern void pf_print_state(struct pf_state *);
|
||||
extern void pf_print_flags(u_int8_t);
|
||||
extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
|
||||
|
@ -681,20 +681,54 @@ pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
pf_remove_src_node(struct pf_src_node *src)
|
||||
void
|
||||
pf_unlink_src_node_locked(struct pf_src_node *src)
|
||||
{
|
||||
#ifdef INVARIANTS
|
||||
struct pf_srchash *sh;
|
||||
|
||||
sh = &V_pf_srchash[pf_hashsrc(&src->addr, src->af)];
|
||||
PF_HASHROW_ASSERT(sh);
|
||||
#endif
|
||||
LIST_REMOVE(src, entry);
|
||||
if (src->rule.ptr)
|
||||
src->rule.ptr->src_nodes--;
|
||||
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
|
||||
V_pf_status.src_nodes--;
|
||||
}
|
||||
|
||||
void
|
||||
pf_unlink_src_node(struct pf_src_node *src)
|
||||
{
|
||||
struct pf_srchash *sh;
|
||||
|
||||
sh = &V_pf_srchash[pf_hashsrc(&src->addr, src->af)];
|
||||
PF_HASHROW_LOCK(sh);
|
||||
LIST_REMOVE(src, entry);
|
||||
pf_unlink_src_node_locked(src);
|
||||
PF_HASHROW_UNLOCK(sh);
|
||||
}
|
||||
|
||||
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
|
||||
V_pf_status.src_nodes--;
|
||||
static void
|
||||
pf_free_src_node(struct pf_src_node *sn)
|
||||
{
|
||||
|
||||
uma_zfree(V_pf_sources_z, src);
|
||||
KASSERT(sn->states == 0, ("%s: %p has refs", __func__, sn));
|
||||
LIST_REMOVE(sn, entry);
|
||||
uma_zfree(V_pf_sources_z, sn);
|
||||
}
|
||||
|
||||
u_int
|
||||
pf_free_src_nodes(struct pf_src_node_list *head)
|
||||
{
|
||||
struct pf_src_node *sn, *tmp;
|
||||
u_int count = 0;
|
||||
|
||||
LIST_FOREACH_SAFE(sn, head, entry, tmp) {
|
||||
pf_free_src_node(sn);
|
||||
count++;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* Data storage structures initialization. */
|
||||
@ -1464,24 +1498,24 @@ pf_state_expires(const struct pf_state *state)
|
||||
void
|
||||
pf_purge_expired_src_nodes()
|
||||
{
|
||||
struct pf_src_node_list freelist;
|
||||
struct pf_srchash *sh;
|
||||
struct pf_src_node *cur, *next;
|
||||
int i;
|
||||
|
||||
LIST_INIT(&freelist);
|
||||
for (i = 0, sh = V_pf_srchash; i <= V_pf_srchashmask; i++, sh++) {
|
||||
PF_HASHROW_LOCK(sh);
|
||||
LIST_FOREACH_SAFE(cur, &sh->nodes, entry, next)
|
||||
if (cur->states == 0 && cur->expire <= time_uptime) {
|
||||
if (cur->rule.ptr != NULL)
|
||||
cur->rule.ptr->src_nodes--;
|
||||
LIST_REMOVE(cur, entry);
|
||||
V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
|
||||
V_pf_status.src_nodes--;
|
||||
uma_zfree(V_pf_sources_z, cur);
|
||||
pf_unlink_src_node_locked(cur);
|
||||
LIST_INSERT_HEAD(&freelist, cur, entry);
|
||||
} else if (cur->rule.ptr != NULL)
|
||||
cur->rule.ptr->rule_flag |= PFRULE_REFS;
|
||||
PF_HASHROW_UNLOCK(sh);
|
||||
}
|
||||
|
||||
pf_free_src_nodes(&freelist);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3771,11 +3805,15 @@ pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
|
||||
if (nk != NULL)
|
||||
uma_zfree(V_pf_state_key_z, nk);
|
||||
|
||||
if (sn != NULL && sn->states == 0 && sn->expire == 0)
|
||||
pf_remove_src_node(sn);
|
||||
if (sn != NULL && sn->states == 0 && sn->expire == 0) {
|
||||
pf_unlink_src_node(sn);
|
||||
pf_free_src_node(sn);
|
||||
}
|
||||
|
||||
if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0)
|
||||
pf_remove_src_node(nsn);
|
||||
if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) {
|
||||
pf_unlink_src_node(nsn);
|
||||
pf_free_src_node(nsn);
|
||||
}
|
||||
|
||||
return (PF_DROP);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user