summaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-03-26 12:39:38 +0000
committerPablo Neira Ayuso <pablo@netfilter.org>2015-04-01 11:17:29 +0200
commitcfed7e1b1f8ed9b3d81ab12203cfb69c3ef24ac6 (patch)
treea16ae3f27a6b9a9b5e547a79dd2b86adbed02454 /include/net
parentc3e1b005ed1cc068fc9d454a6e745830d55d251d (diff)
downloadop-kernel-dev-cfed7e1b1f8ed9b3d81ab12203cfb69c3ef24ac6.zip
op-kernel-dev-cfed7e1b1f8ed9b3d81ab12203cfb69c3ef24ac6.tar.gz
netfilter: nf_tables: add set garbage collection helpers
Add helpers for GC batch destruction: since element destruction needs a RCU grace period for all set implementations, add some helper functions for asynchronous batch destruction. Elements are collected in a batch structure, which is asynchronously released using RCU once its full. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/netfilter/nf_tables.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f2726c5..6fd4495 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -460,6 +460,62 @@ static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
void nft_set_elem_destroy(const struct nft_set *set, void *elem);
/**
+ * struct nft_set_gc_batch_head - nf_tables set garbage collection batch
+ *
+ * @rcu: rcu head
+ * @set: set the elements belong to
+ * @cnt: count of elements
+ */
+struct nft_set_gc_batch_head {
+ struct rcu_head rcu;
+ const struct nft_set *set;
+ unsigned int cnt;
+};
+
+#define NFT_SET_GC_BATCH_SIZE ((PAGE_SIZE - \
+ sizeof(struct nft_set_gc_batch_head)) / \
+ sizeof(void *))
+
+/**
+ * struct nft_set_gc_batch - nf_tables set garbage collection batch
+ *
+ * @head: GC batch head
+ * @elems: garbage collection elements
+ */
+struct nft_set_gc_batch {
+ struct nft_set_gc_batch_head head;
+ void *elems[NFT_SET_GC_BATCH_SIZE];
+};
+
+struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
+ gfp_t gfp);
+void nft_set_gc_batch_release(struct rcu_head *rcu);
+
+static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
+{
+ if (gcb != NULL)
+ call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
+}
+
+static inline struct nft_set_gc_batch *
+nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
+ gfp_t gfp)
+{
+ if (gcb != NULL) {
+ if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
+ return gcb;
+ nft_set_gc_batch_complete(gcb);
+ }
+ return nft_set_gc_batch_alloc(set, gfp);
+}
+
+static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
+ void *elem)
+{
+ gcb->elems[gcb->head.cnt++] = elem;
+}
+
+/**
* struct nft_expr_type - nf_tables expression type
*
* @select_ops: function to select nft_expr_ops
OpenPOWER on IntegriCloud