summaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-03-25 14:08:50 +0000
committerPablo Neira Ayuso <pablo@netfilter.org>2015-03-26 11:09:35 +0100
commitcc02e457bb86f7b6ffee3651bab22d104b60effb (patch)
tree49f656039fee513e2ae6eeba06e141993c15ab9f /include/net
parentea4bd995b0f2fc5677ff8085e92a5d2544b9937c (diff)
downloadlinux-cc02e457bb86f7b6ffee3651bab22d104b60effb.tar.gz
linux-cc02e457bb86f7b6ffee3651bab22d104b60effb.tar.bz2
linux-cc02e457bb86f7b6ffee3651bab22d104b60effb.zip
netfilter: nf_tables: implement set transaction support
Set elements are the last object type not supporting transaction support. Implement similar to the existing rule transactions: The global transaction counter keeps track of two generations, current and next. Each element contains a bitmask specifying in which generations it is inactive. New elements start out as inactive in the current generation and active in the next. On commit, the previous next generation becomes the current generation and the element becomes active. The bitmask is then cleared to indicate that the element is active in all future generations. If the transaction is aborted, the element is removed from the set before it becomes active. When removing an element, it gets marked as inactive in the next generation. On commit the next generation becomes active and the therefor the element inactive. It is then taken out of then set and released. On abort, the element is marked as active for the next generation again. Lookups ignore elements not active in the current generation. The current set types (hash/rbtree) both use a field in the extension area to store the generation mask. This (currently) does not require any additional memory since we have some free space in there. 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.h33
1 files changed, 26 insertions, 7 deletions
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 4c46a325874e..b8cd60dcb4e1 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -138,15 +138,10 @@ struct nft_userdata {
/**
* struct nft_set_elem - generic representation of set elements
*
- * @cookie: implementation specific element cookie
* @key: element key
* @priv: element private data and extensions
- *
- * The cookie can be used to store a handle to the element for subsequent
- * removal.
*/
struct nft_set_elem {
- void *cookie;
struct nft_data key;
void *priv;
};
@@ -207,6 +202,8 @@ struct nft_set_ext;
*
* @lookup: look up an element within the set
* @insert: insert new element into set
+ * @activate: activate new element in the next generation
+ * @deactivate: deactivate element in the next generation
* @remove: remove element from set
* @walk: iterate over all set elemeennts
* @privsize: function to return size of set private data
@@ -221,10 +218,12 @@ struct nft_set_ops {
bool (*lookup)(const struct nft_set *set,
const struct nft_data *key,
const struct nft_set_ext **ext);
- int (*get)(const struct nft_set *set,
- struct nft_set_elem *elem);
int (*insert)(const struct nft_set *set,
const struct nft_set_elem *elem);
+ void (*activate)(const struct nft_set *set,
+ const struct nft_set_elem *elem);
+ void * (*deactivate)(const struct nft_set *set,
+ const struct nft_set_elem *elem);
void (*remove)(const struct nft_set *set,
const struct nft_set_elem *elem);
void (*walk)(const struct nft_ctx *ctx,
@@ -261,6 +260,7 @@ void nft_unregister_set(struct nft_set_ops *ops);
* @nelems: number of elements
* @policy: set parameterization (see enum nft_set_policies)
* @ops: set ops
+ * @pnet: network namespace
* @flags: set flags
* @klen: key length
* @dlen: data length
@@ -277,6 +277,7 @@ struct nft_set {
u16 policy;
/* runtime data below here */
const struct nft_set_ops *ops ____cacheline_aligned;
+ possible_net_t pnet;
u16 flags;
u8 klen;
u8 dlen;
@@ -355,10 +356,12 @@ struct nft_set_ext_tmpl {
/**
* struct nft_set_ext - set extensions
*
+ * @genmask: generation mask
* @offset: offsets of individual extension types
* @data: beginning of extension data
*/
struct nft_set_ext {
+ u8 genmask;
u8 offset[NFT_SET_EXT_NUM];
char data[0];
};
@@ -748,6 +751,22 @@ static inline u8 nft_genmask_cur(const struct net *net)
return 1 << ACCESS_ONCE(net->nft.gencursor);
}
+/*
+ * Set element transaction helpers
+ */
+
+static inline bool nft_set_elem_active(const struct nft_set_ext *ext,
+ u8 genmask)
+{
+ return !(ext->genmask & genmask);
+}
+
+static inline void nft_set_elem_change_active(const struct nft_set *set,
+ struct nft_set_ext *ext)
+{
+ ext->genmask ^= nft_genmask_next(read_pnet(&set->pnet));
+}
+
/**
* struct nft_trans - nf_tables object update in transaction
*