summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables/nft.c36
-rw-r--r--iptables/nft.h1
2 files changed, 25 insertions, 12 deletions
diff --git a/iptables/nft.c b/iptables/nft.c
index f1f0d9d6..fee91bc7 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -780,8 +780,18 @@ int nft_init(struct nft_handle *h, struct builtin_table *t)
return 0;
}
+static void flush_rule_cache(struct nft_handle *h)
+{
+ if (!h->rule_cache)
+ return;
+
+ nftnl_rule_list_free(h->rule_cache);
+ h->rule_cache = NULL;
+}
+
void nft_fini(struct nft_handle *h)
{
+ flush_rule_cache(h);
mnl_socket_close(h->nl);
free(mnl_nlmsg_batch_head(h->batch));
mnl_nlmsg_batch_stop(h->batch);
@@ -1121,6 +1131,7 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
if (batch_rule_add(h, type, r) < 0)
nftnl_rule_free(r);
+ flush_rule_cache(h);
return 1;
}
@@ -1284,6 +1295,9 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
struct nftnl_rule_list *list;
int ret;
+ if (h->rule_cache)
+ return h->rule_cache;
+
list = nftnl_rule_list_alloc();
if (list == NULL)
return 0;
@@ -1297,6 +1311,7 @@ static struct nftnl_rule_list *nft_rule_list_get(struct nft_handle *h)
return NULL;
}
+ h->rule_cache = list;
return list;
}
@@ -1333,7 +1348,6 @@ next:
}
nftnl_rule_list_iter_destroy(iter);
- nftnl_rule_list_free(list);
/* the core expects 1 for success and 0 for error */
return 1;
@@ -1396,6 +1410,7 @@ next:
}
nftnl_chain_list_iter_destroy(iter);
+ flush_rule_cache(h);
err:
nftnl_chain_list_free(list);
@@ -1829,8 +1844,6 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
if (ret == 0)
errno = ENOENT;
- nftnl_rule_list_free(list);
-
return ret;
}
@@ -1855,7 +1868,7 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
} else
errno = ENOENT;
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
return ret;
}
@@ -1879,6 +1892,7 @@ nft_rule_add(struct nft_handle *h, const char *chain,
return 0;
}
+ flush_rule_cache(h);
return 1;
}
@@ -1908,7 +1922,7 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
r = nft_rule_find(h, list, chain, table, data,
rulenum - 1);
if (r != NULL) {
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
return nft_rule_append(h, chain, table, data,
0, verbose);
}
@@ -1920,12 +1934,12 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
handle = nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE);
DEBUGP("adding after rule handle %"PRIu64"\n", handle);
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
}
return nft_rule_add(h, chain, table, data, handle, verbose);
err:
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
return 0;
}
@@ -1953,7 +1967,7 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
} else
errno = ENOENT;
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
return ret;
}
@@ -1983,7 +1997,7 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
} else
errno = ENOENT;
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
return ret;
}
@@ -2037,8 +2051,6 @@ next:
nftnl_rule_list_iter_destroy(iter);
err:
- nftnl_rule_list_free(list);
-
if (ret == 0)
errno = ENOENT;
@@ -2266,7 +2278,7 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
false);
error:
- nftnl_rule_list_free(list);
+ flush_rule_cache(h);
return ret;
}
diff --git a/iptables/nft.h b/iptables/nft.h
index f5449db4..41265930 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -35,6 +35,7 @@ struct nft_handle {
struct mnl_nlmsg_batch *batch;
struct nft_family_ops *ops;
struct builtin_table *tables;
+ struct nftnl_rule_list *rule_cache;
bool restore;
bool batch_support;
};