From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 02/20] netfilter: nf_tables: add set element timeout support
Date: Thu, 9 Apr 2015 13:34:46 +0200 [thread overview]
Message-ID: <1428579304-5520-3-git-send-email-pablo@netfilter.org> (raw)
In-Reply-To: <1428579304-5520-1-git-send-email-pablo@netfilter.org>
From: Patrick McHardy <kaber@trash.net>
Add API support for set element timeouts. Elements can have a individual
timeout value specified, overriding the sets' default.
Two new extension types are used for timeouts - the timeout value and
the expiration time. The timeout value only exists if it differs from
the default value.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 20 +++++++++++
include/uapi/linux/netfilter/nf_tables.h | 4 +++
net/netfilter/nf_tables_api.c | 53 ++++++++++++++++++++++++++++--
3 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 8936803..f2726c5 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -329,12 +329,16 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
* @NFT_SET_EXT_KEY: element key
* @NFT_SET_EXT_DATA: mapping data
* @NFT_SET_EXT_FLAGS: element flags
+ * @NFT_SET_EXT_TIMEOUT: element timeout
+ * @NFT_SET_EXT_EXPIRATION: element expiration time
* @NFT_SET_EXT_NUM: number of extension types
*/
enum nft_set_extensions {
NFT_SET_EXT_KEY,
NFT_SET_EXT_DATA,
NFT_SET_EXT_FLAGS,
+ NFT_SET_EXT_TIMEOUT,
+ NFT_SET_EXT_EXPIRATION,
NFT_SET_EXT_NUM
};
@@ -431,6 +435,22 @@ static inline u8 *nft_set_ext_flags(const struct nft_set_ext *ext)
return nft_set_ext(ext, NFT_SET_EXT_FLAGS);
}
+static inline u64 *nft_set_ext_timeout(const struct nft_set_ext *ext)
+{
+ return nft_set_ext(ext, NFT_SET_EXT_TIMEOUT);
+}
+
+static inline unsigned long *nft_set_ext_expiration(const struct nft_set_ext *ext)
+{
+ return nft_set_ext(ext, NFT_SET_EXT_EXPIRATION);
+}
+
+static inline bool nft_set_elem_expired(const struct nft_set_ext *ext)
+{
+ return nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION) &&
+ time_is_before_eq_jiffies(*nft_set_ext_expiration(ext));
+}
+
static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
void *elem)
{
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 971d245..83441cc 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -290,12 +290,16 @@ enum nft_set_elem_flags {
* @NFTA_SET_ELEM_KEY: key value (NLA_NESTED: nft_data)
* @NFTA_SET_ELEM_DATA: data value of mapping (NLA_NESTED: nft_data_attributes)
* @NFTA_SET_ELEM_FLAGS: bitmask of nft_set_elem_flags (NLA_U32)
+ * @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
+ * @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
*/
enum nft_set_elem_attributes {
NFTA_SET_ELEM_UNSPEC,
NFTA_SET_ELEM_KEY,
NFTA_SET_ELEM_DATA,
NFTA_SET_ELEM_FLAGS,
+ NFTA_SET_ELEM_TIMEOUT,
+ NFTA_SET_ELEM_EXPIRATION,
__NFTA_SET_ELEM_MAX
};
#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 6320b64..9e032db 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2863,6 +2863,14 @@ const struct nft_set_ext_type nft_set_ext_types[] = {
.len = sizeof(u8),
.align = __alignof__(u8),
},
+ [NFT_SET_EXT_TIMEOUT] = {
+ .len = sizeof(u64),
+ .align = __alignof__(u64),
+ },
+ [NFT_SET_EXT_EXPIRATION] = {
+ .len = sizeof(unsigned long),
+ .align = __alignof__(unsigned long),
+ },
};
EXPORT_SYMBOL_GPL(nft_set_ext_types);
@@ -2874,6 +2882,7 @@ static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
[NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
[NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
[NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
+ [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
};
static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
@@ -2935,6 +2944,25 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
htonl(*nft_set_ext_flags(ext))))
goto nla_put_failure;
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
+ nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
+ cpu_to_be64(*nft_set_ext_timeout(ext))))
+ goto nla_put_failure;
+
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
+ unsigned long expires, now = jiffies;
+
+ expires = *nft_set_ext_expiration(ext);
+ if (time_before(now, expires))
+ expires -= now;
+ else
+ expires = 0;
+
+ if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
+ cpu_to_be64(jiffies_to_msecs(expires))))
+ goto nla_put_failure;
+ }
+
nla_nest_end(skb, nest);
return 0;
@@ -3158,7 +3186,7 @@ static void *nft_set_elem_init(const struct nft_set *set,
const struct nft_set_ext_tmpl *tmpl,
const struct nft_data *key,
const struct nft_data *data,
- gfp_t gfp)
+ u64 timeout, gfp_t gfp)
{
struct nft_set_ext *ext;
void *elem;
@@ -3173,6 +3201,11 @@ static void *nft_set_elem_init(const struct nft_set *set,
memcpy(nft_set_ext_key(ext), key, set->klen);
if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
memcpy(nft_set_ext_data(ext), data, set->dlen);
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
+ *nft_set_ext_expiration(ext) =
+ jiffies + msecs_to_jiffies(timeout);
+ if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
+ *nft_set_ext_timeout(ext) = timeout;
return elem;
}
@@ -3201,6 +3234,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
struct nft_data data;
enum nft_registers dreg;
struct nft_trans *trans;
+ u64 timeout;
u32 flags;
int err;
@@ -3241,6 +3275,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
return -EINVAL;
}
+ timeout = 0;
+ if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
+ if (!(set->flags & NFT_SET_TIMEOUT))
+ return -EINVAL;
+ timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_ELEM_TIMEOUT]));
+ } else if (set->flags & NFT_SET_TIMEOUT) {
+ timeout = set->timeout;
+ }
+
err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]);
if (err < 0)
goto err1;
@@ -3249,6 +3292,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
goto err2;
nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY);
+ if (timeout > 0) {
+ nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
+ if (timeout != set->timeout)
+ nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
+ }
if (nla[NFTA_SET_ELEM_DATA] != NULL) {
err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]);
@@ -3277,7 +3325,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
}
err = -ENOMEM;
- elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data, GFP_KERNEL);
+ elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data,
+ timeout, GFP_KERNEL);
if (elem.priv == NULL)
goto err3;
--
1.7.10.4
next prev parent reply other threads:[~2015-04-09 11:34 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-09 11:34 [PATCH 00/20] Netfilter updates for net-next Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 01/20] netfilter: nf_tables: add set timeout API support Pablo Neira Ayuso
2015-04-09 11:34 ` Pablo Neira Ayuso [this message]
2015-04-09 11:34 ` [PATCH 03/20] netfilter: nf_tables: add set garbage collection helpers Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 04/20] netfilter: nf_tables: add GC synchronization helpers Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 05/20] netfilter: nft_hash: add support for timeouts Pablo Neira Ayuso
2015-04-09 13:39 ` David Laight
2015-04-11 13:40 ` Pablo Neira Ayuso
2015-04-11 13:45 ` Patrick McHardy
2015-04-09 11:34 ` [PATCH 06/20] netfilter: x_tables: fix cgroup matching on non-full sks Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 07/20] netfilter: nft_meta: fix cgroup matching Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 08/20] netfilter: bridge: really save frag_max_size between PRE and POST_ROUTING Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 09/20] netfilter: x_tables: don't extract flow keys on early demuxed sks in socket match Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 10/20] netfilter: bridge: don't use nf_bridge_info data to store mac header Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 11/20] netfilter: bridge: add helpers for fetching physin/outdev Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 12/20] netfilter: physdev: use helpers Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 13/20] netfilter: bridge: add and use nf_bridge_info_get helper Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 14/20] netfilter: bridge: start splitting mask into public/private chunks Pablo Neira Ayuso
2015-04-09 11:34 ` [PATCH 15/20] netfilter: bridge: make BRNF_PKT_TYPE flag a bool Pablo Neira Ayuso
2015-04-09 11:35 ` [PATCH 16/20] netfilter: nf_tables: fix set selection when timeouts are requested Pablo Neira Ayuso
2015-04-09 11:35 ` [PATCH 17/20] netfilter: nf_tables: prepare set element accounting for async updates Pablo Neira Ayuso
2015-04-09 11:35 ` [PATCH 18/20] netfilter: nf_tables: support different set binding types Pablo Neira Ayuso
2015-04-09 11:35 ` [PATCH 19/20] netfilter: nf_tables: add support for dynamic set updates Pablo Neira Ayuso
2015-04-09 11:35 ` [PATCH 20/20] netfilter: nf_tables: support optional userdata for set elements Pablo Neira Ayuso
2015-04-09 18:46 ` [PATCH 00/20] Netfilter updates for net-next David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1428579304-5520-3-git-send-email-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.