diff options
author | Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> | 2013-04-27 08:28:55 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-04-29 14:08:54 -0400 |
commit | 075e64c041b5d3c29651965608e1e76505e01d54 (patch) | |
tree | 471cbca37506311f347a673335aba37040591d88 /include | |
parent | 8672d4d1a00b59057bb1f9659259967d2a19e086 (diff) |
netfilter: ipset: Introduce extensions to elements in the core
Introduce extensions to elements in the core and prepare timeout as
the first one.
This patch also modifies the em_ipset classifier to use the new
extension struct layout.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/netfilter/ipset/ip_set.h | 46 | ||||
-rw-r--r-- | include/linux/netfilter/ipset/ip_set_timeout.h | 102 |
2 files changed, 61 insertions, 87 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 */ | ||
51 | enum 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 */ | ||
58 | enum 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 | |||
65 | struct ip_set_ext { | ||
66 | unsigned long timeout; | ||
67 | }; | ||
68 | |||
50 | struct ip_set; | 69 | struct ip_set; |
51 | 70 | ||
52 | typedef int (*ipset_adtfn)(struct ip_set *set, void *value, | 71 | typedef 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 */ |
56 | struct ip_set_adt_opt { | 76 | struct 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 | ||
168 | extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb, | 190 | extern 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); |
171 | extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb, | 193 | extern 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); |
174 | extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb, | 196 | extern 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 */ |
179 | extern void *ip_set_alloc(size_t size); | 201 | extern void *ip_set_alloc(size_t size); |
180 | extern void ip_set_free(void *members); | 202 | extern void ip_set_free(void *members); |
181 | extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); | 203 | extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); |
182 | extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); | 204 | extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); |
205 | extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[], | ||
206 | struct ip_set_ext *ext); | ||
183 | 207 | ||
184 | static inline int | 208 | static inline int |
185 | ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr) | 209 | ip_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 | ||
28 | static inline unsigned int | 29 | static inline unsigned int |
29 | ip_set_timeout_uget(struct nlattr *tb) | 30 | ip_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 | |||
50 | static inline bool | ||
51 | ip_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 | |||
58 | static inline bool | ||
59 | ip_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 | |||
66 | static inline unsigned long | ||
67 | ip_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 | |||
82 | static inline u32 | ||
83 | ip_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 | |||
96 | static inline bool | 42 | static inline bool |
97 | ip_set_timeout_test(unsigned long timeout) | 43 | ip_set_timeout_test(unsigned long timeout) |
98 | { | 44 | { |
@@ -101,36 +47,32 @@ ip_set_timeout_test(unsigned long timeout) | |||
101 | } | 47 | } |
102 | 48 | ||
103 | static inline bool | 49 | static inline bool |
104 | ip_set_timeout_expired(unsigned long timeout) | 50 | ip_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 | ||
110 | static inline unsigned long | 56 | static inline void |
111 | ip_set_timeout_set(u32 timeout) | 57 | ip_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 | ||
126 | static inline u32 | 70 | static inline u32 |
127 | ip_set_timeout_get(unsigned long timeout) | 71 | ip_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 */ |