Skip to content

Commit 761da29

Browse files
kaberummakynes
authored andcommitted
netfilter: nf_tables: add set timeout API support
Add set timeout support to the netlink API. Sets with timeout support enabled can have a default timeout value and garbage collection interval specified. Signed-off-by: Patrick McHardy <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 9911674 commit 761da29

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ void nft_unregister_set(struct nft_set_ops *ops);
258258
* @dtype: data type (verdict or numeric type defined by userspace)
259259
* @size: maximum set size
260260
* @nelems: number of elements
261+
* @timeout: default timeout value in msecs
262+
* @gc_int: garbage collection interval in msecs
261263
* @policy: set parameterization (see enum nft_set_policies)
262264
* @ops: set ops
263265
* @pnet: network namespace
@@ -274,6 +276,8 @@ struct nft_set {
274276
u32 dtype;
275277
u32 size;
276278
u32 nelems;
279+
u64 timeout;
280+
u32 gc_int;
277281
u16 policy;
278282
/* runtime data below here */
279283
const struct nft_set_ops *ops ____cacheline_aligned;
@@ -295,6 +299,11 @@ struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
295299
struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
296300
const struct nlattr *nla);
297301

302+
static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
303+
{
304+
return set->gc_int ? msecs_to_jiffies(set->gc_int) : HZ;
305+
}
306+
298307
/**
299308
* struct nft_set_binding - nf_tables set binding
300309
*

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,14 @@ enum nft_rule_compat_attributes {
208208
* @NFT_SET_CONSTANT: set contents may not change while bound
209209
* @NFT_SET_INTERVAL: set contains intervals
210210
* @NFT_SET_MAP: set is used as a dictionary
211+
* @NFT_SET_TIMEOUT: set uses timeouts
211212
*/
212213
enum nft_set_flags {
213214
NFT_SET_ANONYMOUS = 0x1,
214215
NFT_SET_CONSTANT = 0x2,
215216
NFT_SET_INTERVAL = 0x4,
216217
NFT_SET_MAP = 0x8,
218+
NFT_SET_TIMEOUT = 0x10,
217219
};
218220

219221
/**
@@ -252,6 +254,8 @@ enum nft_set_desc_attributes {
252254
* @NFTA_SET_POLICY: selection policy (NLA_U32)
253255
* @NFTA_SET_DESC: set description (NLA_NESTED)
254256
* @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
257+
* @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
258+
* @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
255259
*/
256260
enum nft_set_attributes {
257261
NFTA_SET_UNSPEC,
@@ -265,6 +269,8 @@ enum nft_set_attributes {
265269
NFTA_SET_POLICY,
266270
NFTA_SET_DESC,
267271
NFTA_SET_ID,
272+
NFTA_SET_TIMEOUT,
273+
NFTA_SET_GC_INTERVAL,
268274
__NFTA_SET_MAX
269275
};
270276
#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)

net/netfilter/nf_tables_api.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2216,6 +2216,8 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
22162216
[NFTA_SET_POLICY] = { .type = NLA_U32 },
22172217
[NFTA_SET_DESC] = { .type = NLA_NESTED },
22182218
[NFTA_SET_ID] = { .type = NLA_U32 },
2219+
[NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
2220+
[NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
22192221
};
22202222

22212223
static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
@@ -2366,6 +2368,13 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
23662368
goto nla_put_failure;
23672369
}
23682370

2371+
if (set->timeout &&
2372+
nla_put_be64(skb, NFTA_SET_TIMEOUT, cpu_to_be64(set->timeout)))
2373+
goto nla_put_failure;
2374+
if (set->gc_int &&
2375+
nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
2376+
goto nla_put_failure;
2377+
23692378
if (set->policy != NFT_SET_POL_PERFORMANCE) {
23702379
if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
23712380
goto nla_put_failure;
@@ -2578,7 +2587,8 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
25782587
char name[IFNAMSIZ];
25792588
unsigned int size;
25802589
bool create;
2581-
u32 ktype, dtype, flags, policy;
2590+
u64 timeout;
2591+
u32 ktype, dtype, flags, policy, gc_int;
25822592
struct nft_set_desc desc;
25832593
int err;
25842594

@@ -2605,7 +2615,8 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
26052615
if (nla[NFTA_SET_FLAGS] != NULL) {
26062616
flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
26072617
if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2608-
NFT_SET_INTERVAL | NFT_SET_MAP))
2618+
NFT_SET_INTERVAL | NFT_SET_MAP |
2619+
NFT_SET_TIMEOUT))
26092620
return -EINVAL;
26102621
}
26112622

@@ -2631,6 +2642,19 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
26312642
} else if (flags & NFT_SET_MAP)
26322643
return -EINVAL;
26332644

2645+
timeout = 0;
2646+
if (nla[NFTA_SET_TIMEOUT] != NULL) {
2647+
if (!(flags & NFT_SET_TIMEOUT))
2648+
return -EINVAL;
2649+
timeout = be64_to_cpu(nla_get_be64(nla[NFTA_SET_TIMEOUT]));
2650+
}
2651+
gc_int = 0;
2652+
if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
2653+
if (!(flags & NFT_SET_TIMEOUT))
2654+
return -EINVAL;
2655+
gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
2656+
}
2657+
26342658
policy = NFT_SET_POL_PERFORMANCE;
26352659
if (nla[NFTA_SET_POLICY] != NULL)
26362660
policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
@@ -2699,6 +2723,8 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
26992723
set->flags = flags;
27002724
set->size = desc.size;
27012725
set->policy = policy;
2726+
set->timeout = timeout;
2727+
set->gc_int = gc_int;
27022728

27032729
err = ops->init(set, &desc, nla);
27042730
if (err < 0)

0 commit comments

Comments
 (0)