* [PATCH nf-next] netfilter: nft_dynset: allow to invert match criteria
@ 2016-08-18 16:22 Pablo Neira Ayuso
2016-08-22 9:16 ` kbuild test robot
0 siblings, 1 reply; 2+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-18 16:22 UTC (permalink / raw)
To: netfilter-devel
The dynset expression matches if we can fit a new entry into the set.
If there is not room for it, then it breaks the rule evaluation.
This patch introduces the inversion flag to obtain the opposite
behaviour, ie. explicity drop packets that don't fit into set.
For example:
# nft filter input set update ip saddr timeout 10s over size 24 @myset drop
This allows us to express the logic in a similar fashion to iptables
connlimit. Basically, every new entry uses the IPv4 address as key in
the set, this entry gets a timeout of 10 seconds that gets refresh on
every packet seen. If we get a packet and our set contains 24 entries
already, then this packet is dropped.
You can also express this in positive logic, assuming default policy to
drop:
# nft filter input set update ip saddr timeout 10s size 24 @myset accept
Specifically, the plan is that 'over size' enables this flag inversion.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/uapi/linux/netfilter/nf_tables.h | 6 ++++++
net/netfilter/nft_dynset.c | 20 +++++++++++++++++++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 6ce0a6d..7859a91 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -575,6 +575,10 @@ enum nft_dynset_ops {
NFT_DYNSET_OP_UPDATE,
};
+enum nft_dynset_flags {
+ NFT_DYNSET_F_INV = (1 << 0),
+};
+
/**
* enum nft_dynset_attributes - dynset expression attributes
*
@@ -585,6 +589,7 @@ enum nft_dynset_ops {
* @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
* @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
* @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
+ * @NFTA_DYNSET_FLAGS: flags (NLA_U32)
*/
enum nft_dynset_attributes {
NFTA_DYNSET_UNSPEC,
@@ -596,6 +601,7 @@ enum nft_dynset_attributes {
NFTA_DYNSET_TIMEOUT,
NFTA_DYNSET_EXPR,
NFTA_DYNSET_PAD,
+ NFTA_DYNSET_FLAGS,
__NFTA_DYNSET_MAX,
};
#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 0af2669..8fb567a 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -22,6 +22,7 @@ struct nft_dynset {
enum nft_dynset_ops op:8;
enum nft_registers sreg_key:8;
enum nft_registers sreg_data:8;
+ bool invert;
u64 timeout;
struct nft_expr *expr;
struct nft_set_binding binding;
@@ -82,10 +83,14 @@ static void nft_dynset_eval(const struct nft_expr *expr,
if (sexpr != NULL)
sexpr->ops->eval(sexpr, regs, pkt);
+
+ if (priv->invert)
+ regs->verdict.code = NFT_BREAK;
return;
}
out:
- regs->verdict.code = NFT_BREAK;
+ if (!priv->invert)
+ regs->verdict.code = NFT_BREAK;
}
static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
@@ -96,6 +101,7 @@ static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
[NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
[NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
[NFTA_DYNSET_EXPR] = { .type = NLA_NESTED },
+ [NFTA_DYNSET_FLAGS] = { .type = NLA_U32 },
};
static int nft_dynset_init(const struct nft_ctx *ctx,
@@ -113,6 +119,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
tb[NFTA_DYNSET_SREG_KEY] == NULL)
return -EINVAL;
+ if (tb[NFTA_DYNSET_FLAGS]) {
+ u32 flags = ntonl(nla_get_be32(tb[NFTA_DYNSET_FLAGS]));
+
+ if (flags & ~NFT_DYNSET_F_INV)
+ return -EINVAL;
+ if (flags & NFT_DYNSET_F_INV)
+ priv->invert = true;
+ }
+
set = nf_tables_set_lookup(ctx->table, tb[NFTA_DYNSET_SET_NAME],
genmask);
if (IS_ERR(set)) {
@@ -220,6 +235,7 @@ static void nft_dynset_destroy(const struct nft_ctx *ctx,
static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
const struct nft_dynset *priv = nft_expr_priv(expr);
+ u32 flags = priv->invert ? NFT_DYNSET_F_INV : 0;
if (nft_dump_register(skb, NFTA_DYNSET_SREG_KEY, priv->sreg_key))
goto nla_put_failure;
@@ -235,6 +251,8 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
goto nla_put_failure;
if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
goto nla_put_failure;
+ if (nla_put_be32(skb, NFTA_DYNSET_FLAGS, htonl(flags)))
+ goto nla_put_failure;
return 0;
nla_put_failure:
--
2.1.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH nf-next] netfilter: nft_dynset: allow to invert match criteria
2016-08-18 16:22 [PATCH nf-next] netfilter: nft_dynset: allow to invert match criteria Pablo Neira Ayuso
@ 2016-08-22 9:16 ` kbuild test robot
0 siblings, 0 replies; 2+ messages in thread
From: kbuild test robot @ 2016-08-22 9:16 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: kbuild-all, netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 1365 bytes --]
Hi Pablo,
[auto build test ERROR on nf-next/master]
url: https://github.com/0day-ci/linux/commits/Pablo-Neira-Ayuso/netfilter-nft_dynset-allow-to-invert-match-criteria/20160819-114223
base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master
config: x86_64-rhel (attached as .config)
compiler: gcc-6 (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
net/netfilter/nft_dynset.c: In function 'nft_dynset_init':
>> net/netfilter/nft_dynset.c:123:15: error: implicit declaration of function 'ntonl' [-Werror=implicit-function-declaration]
u32 flags = ntonl(nla_get_be32(tb[NFTA_DYNSET_FLAGS]));
^~~~~
cc1: some warnings being treated as errors
vim +/ntonl +123 net/netfilter/nft_dynset.c
117 if (tb[NFTA_DYNSET_SET_NAME] == NULL ||
118 tb[NFTA_DYNSET_OP] == NULL ||
119 tb[NFTA_DYNSET_SREG_KEY] == NULL)
120 return -EINVAL;
121
122 if (tb[NFTA_DYNSET_FLAGS]) {
> 123 u32 flags = ntonl(nla_get_be32(tb[NFTA_DYNSET_FLAGS]));
124
125 if (flags & ~NFT_DYNSET_F_INV)
126 return -EINVAL;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 37512 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-08-22 9:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-18 16:22 [PATCH nf-next] netfilter: nft_dynset: allow to invert match criteria Pablo Neira Ayuso
2016-08-22 9:16 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).