summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/rule.h3
-rw-r--r--src/rule.c9
2 files changed, 12 insertions, 0 deletions
diff --git a/include/rule.h b/include/rule.h
index 4e688794..f137a4c8 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -110,6 +110,7 @@ enum chain_flags {
* @list: list node in table list
* @handle: chain handle
* @location: location the chain was defined at
+ * @refcnt: reference counter
* @flags: chain flags
* @hookstr: unified and human readable hook name (base chains)
* @hooknum: hook number (base chains)
@@ -123,6 +124,7 @@ struct chain {
struct list_head list;
struct handle handle;
struct location location;
+ unsigned int refcnt;
uint32_t flags;
const char *hookstr;
unsigned int hooknum;
@@ -137,6 +139,7 @@ struct chain {
extern const char *chain_type_name_lookup(const char *name);
extern const char *chain_hookname_lookup(const char *name);
extern struct chain *chain_alloc(const char *name);
+extern struct chain *chain_get(struct chain *chain);
extern void chain_free(struct chain *chain);
extern void chain_add_hash(struct chain *chain, struct table *table);
extern struct chain *chain_lookup(const struct table *table,
diff --git a/src/rule.c b/src/rule.c
index 6e1b823a..6887a1a7 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -444,6 +444,7 @@ struct chain *chain_alloc(const char *name)
struct chain *chain;
chain = xzalloc(sizeof(*chain));
+ chain->refcnt = 1;
init_list_head(&chain->rules);
init_list_head(&chain->scope.symbols);
if (name != NULL)
@@ -453,10 +454,18 @@ struct chain *chain_alloc(const char *name)
return chain;
}
+struct chain *chain_get(struct chain *chain)
+{
+ chain->refcnt++;
+ return chain;
+}
+
void chain_free(struct chain *chain)
{
struct rule *rule, *next;
+ if (--chain->refcnt > 0)
+ return;
list_for_each_entry_safe(rule, next, &chain->rules, list)
rule_free(rule);
handle_free(&chain->handle);