aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/ipset/ip_set.h46
-rw-r--r--include/linux/netfilter/ipset/ip_set_timeout.h102
-rw-r--r--net/netfilter/ipset/ip_set_core.c24
-rw-r--r--net/netfilter/xt_set.c24
-rw-r--r--net/sched/em_ipset.c2
5 files changed, 87 insertions, 111 deletions
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 970187187f5b..bf0220cbf46a 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -1,7 +1,7 @@
1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de> 2 * Patrick Schaaf <bof@bof.de>
3 * Martin Josefsson <gandalf@wlug.westbo.se> 3 * Martin Josefsson <gandalf@wlug.westbo.se>
4 * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -47,10 +47,30 @@ enum ip_set_feature {
47 IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG), 47 IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG),
48}; 48};
49 49
50/* Set extensions */
51enum ip_set_extension {
52 IPSET_EXT_NONE = 0,
53 IPSET_EXT_BIT_TIMEOUT = 1,
54 IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT),
55};
56
57/* Extension offsets */
58enum ip_set_offset {
59 IPSET_OFFSET_TIMEOUT = 0,
60 IPSET_OFFSET_MAX,
61};
62
63#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
64
65struct ip_set_ext {
66 unsigned long timeout;
67};
68
50struct ip_set; 69struct ip_set;
51 70
52typedef int (*ipset_adtfn)(struct ip_set *set, void *value, 71typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
53 u32 timeout, u32 flags); 72 const struct ip_set_ext *ext,
73 struct ip_set_ext *mext, u32 flags);
54 74
55/* Kernel API function options */ 75/* Kernel API function options */
56struct ip_set_adt_opt { 76struct ip_set_adt_opt {
@@ -58,7 +78,7 @@ struct ip_set_adt_opt {
58 u8 dim; /* Dimension of match/target */ 78 u8 dim; /* Dimension of match/target */
59 u8 flags; /* Direction and negation flags */ 79 u8 flags; /* Direction and negation flags */
60 u32 cmdflags; /* Command-like flags */ 80 u32 cmdflags; /* Command-like flags */
61 u32 timeout; /* Timeout value */ 81 struct ip_set_ext ext; /* Extensions */
62}; 82};
63 83
64/* Set type, variant-specific part */ 84/* Set type, variant-specific part */
@@ -69,7 +89,7 @@ struct ip_set_type_variant {
69 * positive for matching element */ 89 * positive for matching element */
70 int (*kadt)(struct ip_set *set, const struct sk_buff *skb, 90 int (*kadt)(struct ip_set *set, const struct sk_buff *skb,
71 const struct xt_action_param *par, 91 const struct xt_action_param *par,
72 enum ipset_adt adt, const struct ip_set_adt_opt *opt); 92 enum ipset_adt adt, struct ip_set_adt_opt *opt);
73 93
74 /* Userspace: test/add/del entries 94 /* Userspace: test/add/del entries
75 * returns negative error code, 95 * returns negative error code,
@@ -151,6 +171,8 @@ struct ip_set {
151 u8 family; 171 u8 family;
152 /* The type revision */ 172 /* The type revision */
153 u8 revision; 173 u8 revision;
174 /* Extensions */
175 u8 extensions;
154 /* The type specific data */ 176 /* The type specific data */
155 void *data; 177 void *data;
156}; 178};
@@ -167,19 +189,21 @@ extern void ip_set_nfnl_put(ip_set_id_t index);
167 189
168extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb, 190extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb,
169 const struct xt_action_param *par, 191 const struct xt_action_param *par,
170 const struct ip_set_adt_opt *opt); 192 struct ip_set_adt_opt *opt);
171extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb, 193extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb,
172 const struct xt_action_param *par, 194 const struct xt_action_param *par,
173 const struct ip_set_adt_opt *opt); 195 struct ip_set_adt_opt *opt);
174extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb, 196extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb,
175 const struct xt_action_param *par, 197 const struct xt_action_param *par,
176 const struct ip_set_adt_opt *opt); 198 struct ip_set_adt_opt *opt);
177 199
178/* Utility functions */ 200/* Utility functions */
179extern void *ip_set_alloc(size_t size); 201extern void *ip_set_alloc(size_t size);
180extern void ip_set_free(void *members); 202extern void ip_set_free(void *members);
181extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); 203extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr);
182extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); 204extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
205extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
206 struct ip_set_ext *ext);
183 207
184static inline int 208static inline int
185ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr) 209ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
@@ -292,4 +316,12 @@ bitmap_bytes(u32 a, u32 b)
292 return 4 * ((((b - a + 8) / 8) + 3) / 4); 316 return 4 * ((((b - a + 8) / 8) + 3) / 4);
293} 317}
294 318
319#include <linux/netfilter/ipset/ip_set_timeout.h>
320
321#define IP_SET_INIT_KEXT(skb, opt, map) \
322 { .timeout = ip_set_adt_opt_timeout(opt, map) }
323
324#define IP_SET_INIT_UEXT(map) \
325 { .timeout = (map)->timeout }
326
295#endif /*_IP_SET_H */ 327#endif /*_IP_SET_H */
diff --git a/include/linux/netfilter/ipset/ip_set_timeout.h b/include/linux/netfilter/ipset/ip_set_timeout.h
index 41d9cfa08167..3aac04167ca7 100644
--- a/include/linux/netfilter/ipset/ip_set_timeout.h
+++ b/include/linux/netfilter/ipset/ip_set_timeout.h
@@ -1,7 +1,7 @@
1#ifndef _IP_SET_TIMEOUT_H 1#ifndef _IP_SET_TIMEOUT_H
2#define _IP_SET_TIMEOUT_H 2#define _IP_SET_TIMEOUT_H
3 3
4/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -17,13 +17,14 @@
17#define IPSET_GC_PERIOD(timeout) \ 17#define IPSET_GC_PERIOD(timeout) \
18 ((timeout/3) ? min_t(u32, (timeout)/3, IPSET_GC_TIME) : 1) 18 ((timeout/3) ? min_t(u32, (timeout)/3, IPSET_GC_TIME) : 1)
19 19
20/* Set is defined without timeout support: timeout value may be 0 */ 20/* Entry is set with no timeout value */
21#define IPSET_NO_TIMEOUT UINT_MAX 21#define IPSET_ELEM_PERMANENT 0
22 22
23#define with_timeout(timeout) ((timeout) != IPSET_NO_TIMEOUT) 23/* Set is defined with timeout support: timeout value may be 0 */
24#define IPSET_NO_TIMEOUT UINT_MAX
24 25
25#define opt_timeout(opt, map) \ 26#define ip_set_adt_opt_timeout(opt, map) \
26 (with_timeout((opt)->timeout) ? (opt)->timeout : (map)->timeout) 27((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (map)->timeout)
27 28
28static inline unsigned int 29static inline unsigned int
29ip_set_timeout_uget(struct nlattr *tb) 30ip_set_timeout_uget(struct nlattr *tb)
@@ -38,61 +39,6 @@ ip_set_timeout_uget(struct nlattr *tb)
38 return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout; 39 return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;
39} 40}
40 41
41#ifdef IP_SET_BITMAP_TIMEOUT
42
43/* Bitmap specific timeout constants and macros for the entries */
44
45/* Bitmap entry is unset */
46#define IPSET_ELEM_UNSET 0
47/* Bitmap entry is set with no timeout value */
48#define IPSET_ELEM_PERMANENT (UINT_MAX/2)
49
50static inline bool
51ip_set_timeout_test(unsigned long timeout)
52{
53 return timeout != IPSET_ELEM_UNSET &&
54 (timeout == IPSET_ELEM_PERMANENT ||
55 time_is_after_jiffies(timeout));
56}
57
58static inline bool
59ip_set_timeout_expired(unsigned long timeout)
60{
61 return timeout != IPSET_ELEM_UNSET &&
62 timeout != IPSET_ELEM_PERMANENT &&
63 time_is_before_jiffies(timeout);
64}
65
66static inline unsigned long
67ip_set_timeout_set(u32 timeout)
68{
69 unsigned long t;
70
71 if (!timeout)
72 return IPSET_ELEM_PERMANENT;
73
74 t = msecs_to_jiffies(timeout * 1000) + jiffies;
75 if (t == IPSET_ELEM_UNSET || t == IPSET_ELEM_PERMANENT)
76 /* Bingo! */
77 t++;
78
79 return t;
80}
81
82static inline u32
83ip_set_timeout_get(unsigned long timeout)
84{
85 return timeout == IPSET_ELEM_PERMANENT ? 0 :
86 jiffies_to_msecs(timeout - jiffies)/1000;
87}
88
89#else
90
91/* Hash specific timeout constants and macros for the entries */
92
93/* Hash entry is set with no timeout value */
94#define IPSET_ELEM_PERMANENT 0
95
96static inline bool 42static inline bool
97ip_set_timeout_test(unsigned long timeout) 43ip_set_timeout_test(unsigned long timeout)
98{ 44{
@@ -101,36 +47,32 @@ ip_set_timeout_test(unsigned long timeout)
101} 47}
102 48
103static inline bool 49static inline bool
104ip_set_timeout_expired(unsigned long timeout) 50ip_set_timeout_expired(unsigned long *timeout)
105{ 51{
106 return timeout != IPSET_ELEM_PERMANENT && 52 return *timeout != IPSET_ELEM_PERMANENT &&
107 time_is_before_jiffies(timeout); 53 time_is_before_jiffies(*timeout);
108} 54}
109 55
110static inline unsigned long 56static inline void
111ip_set_timeout_set(u32 timeout) 57ip_set_timeout_set(unsigned long *timeout, u32 t)
112{ 58{
113 unsigned long t; 59 if (!t) {
114 60 *timeout = IPSET_ELEM_PERMANENT;
115 if (!timeout) 61 return;
116 return IPSET_ELEM_PERMANENT; 62 }
117 63
118 t = msecs_to_jiffies(timeout * 1000) + jiffies; 64 *timeout = msecs_to_jiffies(t * 1000) + jiffies;
119 if (t == IPSET_ELEM_PERMANENT) 65 if (*timeout == IPSET_ELEM_PERMANENT)
120 /* Bingo! :-) */ 66 /* Bingo! :-) */
121 t++; 67 (*timeout)--;
122
123 return t;
124} 68}
125 69
126static inline u32 70static inline u32
127ip_set_timeout_get(unsigned long timeout) 71ip_set_timeout_get(unsigned long *timeout)
128{ 72{
129 return timeout == IPSET_ELEM_PERMANENT ? 0 : 73 return *timeout == IPSET_ELEM_PERMANENT ? 0 :
130 jiffies_to_msecs(timeout - jiffies)/1000; 74 jiffies_to_msecs(*timeout - jiffies)/1000;
131} 75}
132#endif /* ! IP_SET_BITMAP_TIMEOUT */
133 76
134#endif /* __KERNEL__ */ 77#endif /* __KERNEL__ */
135
136#endif /* _IP_SET_TIMEOUT_H */ 78#endif /* _IP_SET_TIMEOUT_H */
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 86f5e26f39d3..4486285d10da 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1,6 +1,6 @@
1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de> 2 * Patrick Schaaf <bof@bof.de>
3 * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
@@ -315,6 +315,19 @@ ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr)
315} 315}
316EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6); 316EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6);
317 317
318int
319ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
320 struct ip_set_ext *ext)
321{
322 if (tb[IPSET_ATTR_TIMEOUT]) {
323 if (!(set->extensions & IPSET_EXT_TIMEOUT))
324 return -IPSET_ERR_TIMEOUT;
325 ext->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
326 }
327 return 0;
328}
329EXPORT_SYMBOL_GPL(ip_set_get_extensions);
330
318/* 331/*
319 * Creating/destroying/renaming/swapping affect the existence and 332 * Creating/destroying/renaming/swapping affect the existence and
320 * the properties of a set. All of these can be executed from userspace 333 * the properties of a set. All of these can be executed from userspace
@@ -365,8 +378,7 @@ ip_set_rcu_get(ip_set_id_t index)
365 378
366int 379int
367ip_set_test(ip_set_id_t index, const struct sk_buff *skb, 380ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
368 const struct xt_action_param *par, 381 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
369 const struct ip_set_adt_opt *opt)
370{ 382{
371 struct ip_set *set = ip_set_rcu_get(index); 383 struct ip_set *set = ip_set_rcu_get(index);
372 int ret = 0; 384 int ret = 0;
@@ -404,8 +416,7 @@ EXPORT_SYMBOL_GPL(ip_set_test);
404 416
405int 417int
406ip_set_add(ip_set_id_t index, const struct sk_buff *skb, 418ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
407 const struct xt_action_param *par, 419 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
408 const struct ip_set_adt_opt *opt)
409{ 420{
410 struct ip_set *set = ip_set_rcu_get(index); 421 struct ip_set *set = ip_set_rcu_get(index);
411 int ret; 422 int ret;
@@ -427,8 +438,7 @@ EXPORT_SYMBOL_GPL(ip_set_add);
427 438
428int 439int
429ip_set_del(ip_set_id_t index, const struct sk_buff *skb, 440ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
430 const struct xt_action_param *par, 441 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
431 const struct ip_set_adt_opt *opt)
432{ 442{
433 struct ip_set *set = ip_set_rcu_get(index); 443 struct ip_set *set = ip_set_rcu_get(index);
434 int ret = 0; 444 int ret = 0;
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c
index 865a9e54f3ad..636c5199ff35 100644
--- a/net/netfilter/xt_set.c
+++ b/net/netfilter/xt_set.c
@@ -1,7 +1,7 @@
1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 1/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
2 * Patrick Schaaf <bof@bof.de> 2 * Patrick Schaaf <bof@bof.de>
3 * Martin Josefsson <gandalf@wlug.westbo.se> 3 * Martin Josefsson <gandalf@wlug.westbo.se>
4 * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
@@ -30,7 +30,7 @@ MODULE_ALIAS("ip6t_SET");
30static inline int 30static inline int
31match_set(ip_set_id_t index, const struct sk_buff *skb, 31match_set(ip_set_id_t index, const struct sk_buff *skb,
32 const struct xt_action_param *par, 32 const struct xt_action_param *par,
33 const struct ip_set_adt_opt *opt, int inv) 33 struct ip_set_adt_opt *opt, int inv)
34{ 34{
35 if (ip_set_test(index, skb, par, opt)) 35 if (ip_set_test(index, skb, par, opt))
36 inv = !inv; 36 inv = !inv;
@@ -38,20 +38,12 @@ match_set(ip_set_id_t index, const struct sk_buff *skb,
38} 38}
39 39
40#define ADT_OPT(n, f, d, fs, cfs, t) \ 40#define ADT_OPT(n, f, d, fs, cfs, t) \
41const struct ip_set_adt_opt n = { \
42 .family = f, \
43 .dim = d, \
44 .flags = fs, \
45 .cmdflags = cfs, \
46 .timeout = t, \
47}
48#define ADT_MOPT(n, f, d, fs, cfs, t) \
49struct ip_set_adt_opt n = { \ 41struct ip_set_adt_opt n = { \
50 .family = f, \ 42 .family = f, \
51 .dim = d, \ 43 .dim = d, \
52 .flags = fs, \ 44 .flags = fs, \
53 .cmdflags = cfs, \ 45 .cmdflags = cfs, \
54 .timeout = t, \ 46 .ext.timeout = t, \
55} 47}
56 48
57/* Revision 0 interface: backward compatible with netfilter/iptables */ 49/* Revision 0 interface: backward compatible with netfilter/iptables */
@@ -305,15 +297,15 @@ static unsigned int
305set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) 297set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
306{ 298{
307 const struct xt_set_info_target_v2 *info = par->targinfo; 299 const struct xt_set_info_target_v2 *info = par->targinfo;
308 ADT_MOPT(add_opt, par->family, info->add_set.dim, 300 ADT_OPT(add_opt, par->family, info->add_set.dim,
309 info->add_set.flags, info->flags, info->timeout); 301 info->add_set.flags, info->flags, info->timeout);
310 ADT_OPT(del_opt, par->family, info->del_set.dim, 302 ADT_OPT(del_opt, par->family, info->del_set.dim,
311 info->del_set.flags, 0, UINT_MAX); 303 info->del_set.flags, 0, UINT_MAX);
312 304
313 /* Normalize to fit into jiffies */ 305 /* Normalize to fit into jiffies */
314 if (add_opt.timeout != IPSET_NO_TIMEOUT && 306 if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
315 add_opt.timeout > UINT_MAX/MSEC_PER_SEC) 307 add_opt.ext.timeout > UINT_MAX/MSEC_PER_SEC)
316 add_opt.timeout = UINT_MAX/MSEC_PER_SEC; 308 add_opt.ext.timeout = UINT_MAX/MSEC_PER_SEC;
317 if (info->add_set.index != IPSET_INVALID_ID) 309 if (info->add_set.index != IPSET_INVALID_ID)
318 ip_set_add(info->add_set.index, skb, par, &add_opt); 310 ip_set_add(info->add_set.index, skb, par, &add_opt);
319 if (info->del_set.index != IPSET_INVALID_ID) 311 if (info->del_set.index != IPSET_INVALID_ID)
diff --git a/net/sched/em_ipset.c b/net/sched/em_ipset.c
index 3130320997e2..938b7cbf5627 100644
--- a/net/sched/em_ipset.c
+++ b/net/sched/em_ipset.c
@@ -83,7 +83,7 @@ static int em_ipset_match(struct sk_buff *skb, struct tcf_ematch *em,
83 opt.dim = set->dim; 83 opt.dim = set->dim;
84 opt.flags = set->flags; 84 opt.flags = set->flags;
85 opt.cmdflags = 0; 85 opt.cmdflags = 0;
86 opt.timeout = ~0u; 86 opt.ext.timeout = ~0u;
87 87
88 network_offset = skb_network_offset(skb); 88 network_offset = skb_network_offset(skb);
89 skb_pull(skb, network_offset); 89 skb_pull(skb, network_offset);