* [PATCH nf-next] netfilter: meta: add PRANDOM support
@ 2016-02-16 12:09 Florian Westphal
2016-02-16 12:48 ` Daniel Borkmann
0 siblings, 1 reply; 5+ messages in thread
From: Florian Westphal @ 2016-02-16 12:09 UTC (permalink / raw)
To: netfilter-devel; +Cc: Florian Westphal, Daniel Borkmann
Can be used to randomly match a packet, e.g. for statistical traffic
sampling.
See commit 3ad0040573b0c00f8848
("bpf: split state from prandom_u32() and consolidate {c, e}BPF prngs")
for more info why this doesn't use prandom_u32 directly.
Unlike bpf nft_meta can be built as a module, so add an EXPORT_SYMBOL
for prandom_seed_full_state too.
Cc: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/uapi/linux/netfilter/nf_tables.h | 2 ++
lib/random32.c | 1 +
net/netfilter/nft_meta.c | 15 +++++++++++++++
3 files changed, 18 insertions(+)
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index be41ffc..b19be0a 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -681,6 +681,7 @@ enum nft_exthdr_attributes {
* @NFT_META_IIFGROUP: packet input interface group
* @NFT_META_OIFGROUP: packet output interface group
* @NFT_META_CGROUP: socket control group (skb->sk->sk_classid)
+ * @NFT_META_PRANDOM: a 32bit pseudo-random number
*/
enum nft_meta_keys {
NFT_META_LEN,
@@ -707,6 +708,7 @@ enum nft_meta_keys {
NFT_META_IIFGROUP,
NFT_META_OIFGROUP,
NFT_META_CGROUP,
+ NFT_META_PRANDOM,
};
/**
diff --git a/lib/random32.c b/lib/random32.c
index 1211191..510d1ce 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -255,6 +255,7 @@ void prandom_seed_full_state(struct rnd_state __percpu *pcpu_state)
prandom_warmup(state);
}
}
+EXPORT_SYMBOL(prandom_seed_full_state);
/*
* Generate better values after random number generator
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index fe885bf..6c46671 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -28,6 +28,8 @@
#include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
+static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
+
void nft_meta_get_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
@@ -181,6 +183,11 @@ void nft_meta_get_eval(const struct nft_expr *expr,
*dest = sock_cgroup_classid(&sk->sk_cgrp_data);
break;
#endif
+ case NFT_META_PRANDOM: {
+ struct rnd_state *state = this_cpu_ptr(&nft_prandom_state);
+ *dest = prandom_u32_state(state);
+ break;
+ }
default:
WARN_ON(1);
goto err;
@@ -241,6 +248,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
{
struct nft_meta *priv = nft_expr_priv(expr);
unsigned int len;
+ static bool prand_inited __read_mostly;
priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
switch (priv->key) {
@@ -277,6 +285,13 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
case NFT_META_OIFNAME:
len = IFNAMSIZ;
break;
+ case NFT_META_PRANDOM:
+ if (!prand_inited) {
+ prandom_seed_full_state(&nft_prandom_state);
+ prand_inited = true;
+ }
+ len = sizeof(u32);
+ break;
default:
return -EOPNOTSUPP;
}
--
2.4.10
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH nf-next] netfilter: meta: add PRANDOM support
2016-02-16 12:09 [PATCH nf-next] netfilter: meta: add PRANDOM support Florian Westphal
@ 2016-02-16 12:48 ` Daniel Borkmann
2016-02-16 13:19 ` Florian Westphal
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Borkmann @ 2016-02-16 12:48 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
Hi Florian,
On 02/16/2016 01:09 PM, Florian Westphal wrote:
> Can be used to randomly match a packet, e.g. for statistical traffic
> sampling.
>
> See commit 3ad0040573b0c00f8848
> ("bpf: split state from prandom_u32() and consolidate {c, e}BPF prngs")
> for more info why this doesn't use prandom_u32 directly.
>
> Unlike bpf nft_meta can be built as a module, so add an EXPORT_SYMBOL
> for prandom_seed_full_state too.
>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: Florian Westphal <fw@strlen.de>
[...]
> @@ -241,6 +248,7 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
> {
> struct nft_meta *priv = nft_expr_priv(expr);
> unsigned int len;
> + static bool prand_inited __read_mostly;
>
> priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
> switch (priv->key) {
> @@ -277,6 +285,13 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
> case NFT_META_OIFNAME:
> len = IFNAMSIZ;
> break;
> + case NFT_META_PRANDOM:
> + if (!prand_inited) {
> + prandom_seed_full_state(&nft_prandom_state);
> + prand_inited = true;
> + }
Should this be: prandom_init_once() ?
> + len = sizeof(u32);
> + break;
> default:
> return -EOPNOTSUPP;
> }
>
Thanks,
Daniel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH nf-next] netfilter: meta: add PRANDOM support
2016-02-16 12:48 ` Daniel Borkmann
@ 2016-02-16 13:19 ` Florian Westphal
2016-02-16 13:56 ` Daniel Borkmann
0 siblings, 1 reply; 5+ messages in thread
From: Florian Westphal @ 2016-02-16 13:19 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Florian Westphal, netfilter-devel
Daniel Borkmann <daniel@iogearbox.net> wrote:
> >+ case NFT_META_PRANDOM:
> >+ if (!prand_inited) {
> >+ prandom_seed_full_state(&nft_prandom_state);
> >+ prand_inited = true;
> >+ }
>
> Should this be: prandom_init_once() ?
Thought about that but this is slowpath so I considered
the use of static key magic a bit overkill....
I don't mind, if you think prandom_init_once is prefereable I'll respin.
Let me know, thanks!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH nf-next] netfilter: meta: add PRANDOM support
2016-02-16 13:19 ` Florian Westphal
@ 2016-02-16 13:56 ` Daniel Borkmann
2016-02-16 14:09 ` Florian Westphal
0 siblings, 1 reply; 5+ messages in thread
From: Daniel Borkmann @ 2016-02-16 13:56 UTC (permalink / raw)
To: Florian Westphal; +Cc: netfilter-devel
On 02/16/2016 02:19 PM, Florian Westphal wrote:
> Daniel Borkmann <daniel@iogearbox.net> wrote:
>>> + case NFT_META_PRANDOM:
>>> + if (!prand_inited) {
>>> + prandom_seed_full_state(&nft_prandom_state);
>>> + prand_inited = true;
>>> + }
>>
>> Should this be: prandom_init_once() ?
>
> Thought about that but this is slowpath so I considered
> the use of static key magic a bit overkill....
>
> I don't mind, if you think prandom_init_once is prefereable I'll respin.
You'd have the benefit that the prng init would be race free. nft_meta_get_init()
could be called in parallel from multiple CPUs, right?
> Let me know, thanks!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH nf-next] netfilter: meta: add PRANDOM support
2016-02-16 13:56 ` Daniel Borkmann
@ 2016-02-16 14:09 ` Florian Westphal
0 siblings, 0 replies; 5+ messages in thread
From: Florian Westphal @ 2016-02-16 14:09 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Florian Westphal, netfilter-devel
Daniel Borkmann <daniel@iogearbox.net> wrote:
> On 02/16/2016 02:19 PM, Florian Westphal wrote:
> >Daniel Borkmann <daniel@iogearbox.net> wrote:
> >>>+ case NFT_META_PRANDOM:
> >>>+ if (!prand_inited) {
> >>>+ prandom_seed_full_state(&nft_prandom_state);
> >>>+ prand_inited = true;
> >>>+ }
> >>
> >>Should this be: prandom_init_once() ?
> >
> >Thought about that but this is slowpath so I considered
> >the use of static key magic a bit overkill....
> >
> >I don't mind, if you think prandom_init_once is prefereable I'll respin.
>
> You'd have the benefit that the prng init would be race free. nft_meta_get_init()
> could be called in parallel from multiple CPUs, right?
We're serialized by nftables' nfnetlink mutex.
I guess I'll just send a V2 and use prandom_init_once after all.
Thanks!
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-02-16 14:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-16 12:09 [PATCH nf-next] netfilter: meta: add PRANDOM support Florian Westphal
2016-02-16 12:48 ` Daniel Borkmann
2016-02-16 13:19 ` Florian Westphal
2016-02-16 13:56 ` Daniel Borkmann
2016-02-16 14:09 ` Florian Westphal
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.