aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-04-29 14:29:06 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-29 14:29:06 -0400
commit14d3692f04a050a0d1e4637b56f997a168c591f6 (patch)
tree995b4c8ad7e1269fec39f1e92b865ac36493cec3
parent674853b222168f2066db028cad89ab52cbcdeee5 (diff)
parenteee1d5a14780b9391ec51f3feaf4cffb521ddbb1 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== The following patchset contains relevant updates for the Netfilter tree, they are: * Enhancements for ipset: Add the counter extension for sets, this information can be used from the iptables set match, to change the matching behaviour. Jozsef required to add the extension infrastructure and moved the existing timeout support upon it. This also includes a change in net/sched/em_ipset to adapt it to the new extension structure. * Enhancements for performance boosting in nfnetlink_queue: Add new configuration flags that allows user-space to receive big packets (GRO) and to disable checksumming calculation. This were proposed by Eric Dumazet during the Netfilter Workshop 2013 in Copenhagen. Florian Westphal was kind enough to find the time to materialize the proposal. * A sparse fix from Simon, he noticed it in the SCTP NAT helper, the fix required a change in the interface of sctp_end_cksum. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter/ipset/ip_set.h126
-rw-r--r--include/linux/netfilter/ipset/ip_set_ahash.h1241
-rw-r--r--include/linux/netfilter/ipset/ip_set_bitmap.h6
-rw-r--r--include/linux/netfilter/ipset/ip_set_timeout.h102
-rw-r--r--include/linux/netfilter/ipset/pfxlen.h9
-rw-r--r--include/net/netfilter/nf_queue.h6
-rw-r--r--include/net/sctp/checksum.h2
-rw-r--r--include/uapi/linux/netfilter/ipset/ip_set.h36
-rw-r--r--include/uapi/linux/netfilter/nfnetlink_queue.h10
-rw-r--r--include/uapi/linux/netfilter/xt_set.h9
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_gen.h277
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ip.c411
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_ipmac.c624
-rw-r--r--net/netfilter/ipset/ip_set_bitmap_port.c414
-rw-r--r--net/netfilter/ipset/ip_set_core.c36
-rw-r--r--net/netfilter/ipset/ip_set_hash_gen.h1100
-rw-r--r--net/netfilter/ipset/ip_set_hash_ip.c344
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipport.c362
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportip.c368
-rw-r--r--net/netfilter/ipset/ip_set_hash_ipportnet.c469
-rw-r--r--net/netfilter/ipset/ip_set_hash_net.c402
-rw-r--r--net/netfilter/ipset/ip_set_hash_netiface.c478
-rw-r--r--net/netfilter/ipset/ip_set_hash_netport.c456
-rw-r--r--net/netfilter/ipset/ip_set_list_set.c622
-rw-r--r--net/netfilter/nf_nat_proto_sctp.c5
-rw-r--r--net/netfilter/nf_queue.c143
-rw-r--r--net/netfilter/nfnetlink_queue_core.c173
-rw-r--r--net/netfilter/xt_set.c94
-rw-r--r--net/sched/em_ipset.c2
29 files changed, 3688 insertions, 4639 deletions
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 7958e84a65af..d80e2753847c 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,36 @@ 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 IPSET_EXT_BIT_COUNTER = 2,
56 IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER),
57};
58
59/* Extension offsets */
60enum ip_set_offset {
61 IPSET_OFFSET_TIMEOUT = 0,
62 IPSET_OFFSET_COUNTER,
63 IPSET_OFFSET_MAX,
64};
65
66#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
67#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
68
69struct ip_set_ext {
70 unsigned long timeout;
71 u64 packets;
72 u64 bytes;
73};
74
50struct ip_set; 75struct ip_set;
51 76
52typedef int (*ipset_adtfn)(struct ip_set *set, void *value, 77typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
53 u32 timeout, u32 flags); 78 const struct ip_set_ext *ext,
79 struct ip_set_ext *mext, u32 cmdflags);
54 80
55/* Kernel API function options */ 81/* Kernel API function options */
56struct ip_set_adt_opt { 82struct ip_set_adt_opt {
@@ -58,7 +84,7 @@ struct ip_set_adt_opt {
58 u8 dim; /* Dimension of match/target */ 84 u8 dim; /* Dimension of match/target */
59 u8 flags; /* Direction and negation flags */ 85 u8 flags; /* Direction and negation flags */
60 u32 cmdflags; /* Command-like flags */ 86 u32 cmdflags; /* Command-like flags */
61 u32 timeout; /* Timeout value */ 87 struct ip_set_ext ext; /* Extensions */
62}; 88};
63 89
64/* Set type, variant-specific part */ 90/* Set type, variant-specific part */
@@ -69,7 +95,7 @@ struct ip_set_type_variant {
69 * positive for matching element */ 95 * positive for matching element */
70 int (*kadt)(struct ip_set *set, const struct sk_buff *skb, 96 int (*kadt)(struct ip_set *set, const struct sk_buff *skb,
71 const struct xt_action_param *par, 97 const struct xt_action_param *par,
72 enum ipset_adt adt, const struct ip_set_adt_opt *opt); 98 enum ipset_adt adt, struct ip_set_adt_opt *opt);
73 99
74 /* Userspace: test/add/del entries 100 /* Userspace: test/add/del entries
75 * returns negative error code, 101 * returns negative error code,
@@ -151,10 +177,76 @@ struct ip_set {
151 u8 family; 177 u8 family;
152 /* The type revision */ 178 /* The type revision */
153 u8 revision; 179 u8 revision;
180 /* Extensions */
181 u8 extensions;
154 /* The type specific data */ 182 /* The type specific data */
155 void *data; 183 void *data;
156}; 184};
157 185
186struct ip_set_counter {
187 atomic64_t bytes;
188 atomic64_t packets;
189};
190
191static inline void
192ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
193{
194 atomic64_add((long long)bytes, &(counter)->bytes);
195}
196
197static inline void
198ip_set_add_packets(u64 packets, struct ip_set_counter *counter)
199{
200 atomic64_add((long long)packets, &(counter)->packets);
201}
202
203static inline u64
204ip_set_get_bytes(const struct ip_set_counter *counter)
205{
206 return (u64)atomic64_read(&(counter)->bytes);
207}
208
209static inline u64
210ip_set_get_packets(const struct ip_set_counter *counter)
211{
212 return (u64)atomic64_read(&(counter)->packets);
213}
214
215static inline void
216ip_set_update_counter(struct ip_set_counter *counter,
217 const struct ip_set_ext *ext,
218 struct ip_set_ext *mext, u32 flags)
219{
220 if (ext->packets != ULLONG_MAX &&
221 !(flags & IPSET_FLAG_SKIP_COUNTER_UPDATE)) {
222 ip_set_add_bytes(ext->bytes, counter);
223 ip_set_add_packets(ext->packets, counter);
224 }
225 if (flags & IPSET_FLAG_MATCH_COUNTERS) {
226 mext->packets = ip_set_get_packets(counter);
227 mext->bytes = ip_set_get_bytes(counter);
228 }
229}
230
231static inline bool
232ip_set_put_counter(struct sk_buff *skb, struct ip_set_counter *counter)
233{
234 return nla_put_net64(skb, IPSET_ATTR_BYTES,
235 cpu_to_be64(ip_set_get_bytes(counter))) ||
236 nla_put_net64(skb, IPSET_ATTR_PACKETS,
237 cpu_to_be64(ip_set_get_packets(counter)));
238}
239
240static inline void
241ip_set_init_counter(struct ip_set_counter *counter,
242 const struct ip_set_ext *ext)
243{
244 if (ext->bytes != ULLONG_MAX)
245 atomic64_set(&(counter)->bytes, (long long)(ext->bytes));
246 if (ext->packets != ULLONG_MAX)
247 atomic64_set(&(counter)->packets, (long long)(ext->packets));
248}
249
158/* register and unregister set references */ 250/* register and unregister set references */
159extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set); 251extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set);
160extern void ip_set_put_byindex(ip_set_id_t index); 252extern void ip_set_put_byindex(ip_set_id_t index);
@@ -167,19 +259,21 @@ extern void ip_set_nfnl_put(ip_set_id_t index);
167 259
168extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb, 260extern int ip_set_add(ip_set_id_t id, const struct sk_buff *skb,
169 const struct xt_action_param *par, 261 const struct xt_action_param *par,
170 const struct ip_set_adt_opt *opt); 262 struct ip_set_adt_opt *opt);
171extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb, 263extern int ip_set_del(ip_set_id_t id, const struct sk_buff *skb,
172 const struct xt_action_param *par, 264 const struct xt_action_param *par,
173 const struct ip_set_adt_opt *opt); 265 struct ip_set_adt_opt *opt);
174extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb, 266extern int ip_set_test(ip_set_id_t id, const struct sk_buff *skb,
175 const struct xt_action_param *par, 267 const struct xt_action_param *par,
176 const struct ip_set_adt_opt *opt); 268 struct ip_set_adt_opt *opt);
177 269
178/* Utility functions */ 270/* Utility functions */
179extern void *ip_set_alloc(size_t size); 271extern void *ip_set_alloc(size_t size);
180extern void ip_set_free(void *members); 272extern void ip_set_free(void *members);
181extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); 273extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr);
182extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); 274extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
275extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
276 struct ip_set_ext *ext);
183 277
184static inline int 278static inline int
185ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr) 279ip_set_get_hostipaddr4(struct nlattr *nla, u32 *ipaddr)
@@ -200,6 +294,14 @@ ip_set_eexist(int ret, u32 flags)
200 return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST); 294 return ret == -IPSET_ERR_EXIST && (flags & IPSET_FLAG_EXIST);
201} 295}
202 296
297/* Match elements marked with nomatch */
298static inline bool
299ip_set_enomatch(int ret, u32 flags, enum ipset_adt adt)
300{
301 return adt == IPSET_TEST &&
302 ret == -ENOTEMPTY && ((flags >> 16) & IPSET_FLAG_NOMATCH);
303}
304
203/* Check the NLA_F_NET_BYTEORDER flag */ 305/* Check the NLA_F_NET_BYTEORDER flag */
204static inline bool 306static inline bool
205ip_set_attr_netorder(struct nlattr *tb[], int type) 307ip_set_attr_netorder(struct nlattr *tb[], int type)
@@ -284,4 +386,14 @@ bitmap_bytes(u32 a, u32 b)
284 return 4 * ((((b - a + 8) / 8) + 3) / 4); 386 return 4 * ((((b - a + 8) / 8) + 3) / 4);
285} 387}
286 388
389#include <linux/netfilter/ipset/ip_set_timeout.h>
390
391#define IP_SET_INIT_KEXT(skb, opt, map) \
392 { .bytes = (skb)->len, .packets = 1, \
393 .timeout = ip_set_adt_opt_timeout(opt, map) }
394
395#define IP_SET_INIT_UEXT(map) \
396 { .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \
397 .timeout = (map)->timeout }
398
287#endif /*_IP_SET_H */ 399#endif /*_IP_SET_H */
diff --git a/include/linux/netfilter/ipset/ip_set_ahash.h b/include/linux/netfilter/ipset/ip_set_ahash.h
deleted file mode 100644
index 0214c4c146fa..000000000000
--- a/include/linux/netfilter/ipset/ip_set_ahash.h
+++ /dev/null
@@ -1,1241 +0,0 @@
1#ifndef _IP_SET_AHASH_H
2#define _IP_SET_AHASH_H
3
4#include <linux/rcupdate.h>
5#include <linux/jhash.h>
6#include <linux/netfilter/ipset/ip_set_timeout.h>
7
8#define CONCAT(a, b, c) a##b##c
9#define TOKEN(a, b, c) CONCAT(a, b, c)
10
11#define type_pf_next TOKEN(TYPE, PF, _elem)
12
13/* Hashing which uses arrays to resolve clashing. The hash table is resized
14 * (doubled) when searching becomes too long.
15 * Internally jhash is used with the assumption that the size of the
16 * stored data is a multiple of sizeof(u32). If storage supports timeout,
17 * the timeout field must be the last one in the data structure - that field
18 * is ignored when computing the hash key.
19 *
20 * Readers and resizing
21 *
22 * Resizing can be triggered by userspace command only, and those
23 * are serialized by the nfnl mutex. During resizing the set is
24 * read-locked, so the only possible concurrent operations are
25 * the kernel side readers. Those must be protected by proper RCU locking.
26 */
27
28/* Number of elements to store in an initial array block */
29#define AHASH_INIT_SIZE 4
30/* Max number of elements to store in an array block */
31#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE)
32
33/* Max number of elements can be tuned */
34#ifdef IP_SET_HASH_WITH_MULTI
35#define AHASH_MAX(h) ((h)->ahash_max)
36
37static inline u8
38tune_ahash_max(u8 curr, u32 multi)
39{
40 u32 n;
41
42 if (multi < curr)
43 return curr;
44
45 n = curr + AHASH_INIT_SIZE;
46 /* Currently, at listing one hash bucket must fit into a message.
47 * Therefore we have a hard limit here.
48 */
49 return n > curr && n <= 64 ? n : curr;
50}
51#define TUNE_AHASH_MAX(h, multi) \
52 ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi))
53#else
54#define AHASH_MAX(h) AHASH_MAX_SIZE
55#define TUNE_AHASH_MAX(h, multi)
56#endif
57
58/* A hash bucket */
59struct hbucket {
60 void *value; /* the array of the values */
61 u8 size; /* size of the array */
62 u8 pos; /* position of the first free entry */
63};
64
65/* The hash table: the table size stored here in order to make resizing easy */
66struct htable {
67 u8 htable_bits; /* size of hash table == 2^htable_bits */
68 struct hbucket bucket[0]; /* hashtable buckets */
69};
70
71#define hbucket(h, i) (&((h)->bucket[i]))
72
73/* Book-keeping of the prefixes added to the set */
74struct ip_set_hash_nets {
75 u8 cidr; /* the different cidr values in the set */
76 u32 nets; /* number of elements per cidr */
77};
78
79/* The generic ip_set hash structure */
80struct ip_set_hash {
81 struct htable *table; /* the hash table */
82 u32 maxelem; /* max elements in the hash */
83 u32 elements; /* current element (vs timeout) */
84 u32 initval; /* random jhash init value */
85 u32 timeout; /* timeout value, if enabled */
86 struct timer_list gc; /* garbage collection when timeout enabled */
87 struct type_pf_next next; /* temporary storage for uadd */
88#ifdef IP_SET_HASH_WITH_MULTI
89 u8 ahash_max; /* max elements in an array block */
90#endif
91#ifdef IP_SET_HASH_WITH_NETMASK
92 u8 netmask; /* netmask value for subnets to store */
93#endif
94#ifdef IP_SET_HASH_WITH_RBTREE
95 struct rb_root rbtree;
96#endif
97#ifdef IP_SET_HASH_WITH_NETS
98 struct ip_set_hash_nets nets[0]; /* book-keeping of prefixes */
99#endif
100};
101
102static size_t
103htable_size(u8 hbits)
104{
105 size_t hsize;
106
107 /* We must fit both into u32 in jhash and size_t */
108 if (hbits > 31)
109 return 0;
110 hsize = jhash_size(hbits);
111 if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket)
112 < hsize)
113 return 0;
114
115 return hsize * sizeof(struct hbucket) + sizeof(struct htable);
116}
117
118/* Compute htable_bits from the user input parameter hashsize */
119static u8
120htable_bits(u32 hashsize)
121{
122 /* Assume that hashsize == 2^htable_bits */
123 u8 bits = fls(hashsize - 1);
124 if (jhash_size(bits) != hashsize)
125 /* Round up to the first 2^n value */
126 bits = fls(hashsize);
127
128 return bits;
129}
130
131#ifdef IP_SET_HASH_WITH_NETS
132#ifdef IP_SET_HASH_WITH_NETS_PACKED
133/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */
134#define CIDR(cidr) (cidr + 1)
135#else
136#define CIDR(cidr) (cidr)
137#endif
138
139#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
140#ifdef IP_SET_HASH_WITH_MULTI
141#define NETS_LENGTH(family) (SET_HOST_MASK(family) + 1)
142#else
143#define NETS_LENGTH(family) SET_HOST_MASK(family)
144#endif
145
146/* Network cidr size book keeping when the hash stores different
147 * sized networks */
148static void
149add_cidr(struct ip_set_hash *h, u8 cidr, u8 nets_length)
150{
151 int i, j;
152
153 /* Add in increasing prefix order, so larger cidr first */
154 for (i = 0, j = -1; i < nets_length && h->nets[i].nets; i++) {
155 if (j != -1)
156 continue;
157 else if (h->nets[i].cidr < cidr)
158 j = i;
159 else if (h->nets[i].cidr == cidr) {
160 h->nets[i].nets++;
161 return;
162 }
163 }
164 if (j != -1) {
165 for (; i > j; i--) {
166 h->nets[i].cidr = h->nets[i - 1].cidr;
167 h->nets[i].nets = h->nets[i - 1].nets;
168 }
169 }
170 h->nets[i].cidr = cidr;
171 h->nets[i].nets = 1;
172}
173
174static void
175del_cidr(struct ip_set_hash *h, u8 cidr, u8 nets_length)
176{
177 u8 i, j;
178
179 for (i = 0; i < nets_length - 1 && h->nets[i].cidr != cidr; i++)
180 ;
181 h->nets[i].nets--;
182
183 if (h->nets[i].nets != 0)
184 return;
185
186 for (j = i; j < nets_length - 1 && h->nets[j].nets; j++) {
187 h->nets[j].cidr = h->nets[j + 1].cidr;
188 h->nets[j].nets = h->nets[j + 1].nets;
189 }
190}
191#else
192#define NETS_LENGTH(family) 0
193#endif
194
195/* Destroy the hashtable part of the set */
196static void
197ahash_destroy(struct htable *t)
198{
199 struct hbucket *n;
200 u32 i;
201
202 for (i = 0; i < jhash_size(t->htable_bits); i++) {
203 n = hbucket(t, i);
204 if (n->size)
205 /* FIXME: use slab cache */
206 kfree(n->value);
207 }
208
209 ip_set_free(t);
210}
211
212/* Calculate the actual memory size of the set data */
213static size_t
214ahash_memsize(const struct ip_set_hash *h, size_t dsize, u8 nets_length)
215{
216 u32 i;
217 struct htable *t = h->table;
218 size_t memsize = sizeof(*h)
219 + sizeof(*t)
220#ifdef IP_SET_HASH_WITH_NETS
221 + sizeof(struct ip_set_hash_nets) * nets_length
222#endif
223 + jhash_size(t->htable_bits) * sizeof(struct hbucket);
224
225 for (i = 0; i < jhash_size(t->htable_bits); i++)
226 memsize += t->bucket[i].size * dsize;
227
228 return memsize;
229}
230
231/* Flush a hash type of set: destroy all elements */
232static void
233ip_set_hash_flush(struct ip_set *set)
234{
235 struct ip_set_hash *h = set->data;
236 struct htable *t = h->table;
237 struct hbucket *n;
238 u32 i;
239
240 for (i = 0; i < jhash_size(t->htable_bits); i++) {
241 n = hbucket(t, i);
242 if (n->size) {
243 n->size = n->pos = 0;
244 /* FIXME: use slab cache */
245 kfree(n->value);
246 }
247 }
248#ifdef IP_SET_HASH_WITH_NETS
249 memset(h->nets, 0, sizeof(struct ip_set_hash_nets)
250 * NETS_LENGTH(set->family));
251#endif
252 h->elements = 0;
253}
254
255/* Destroy a hash type of set */
256static void
257ip_set_hash_destroy(struct ip_set *set)
258{
259 struct ip_set_hash *h = set->data;
260
261 if (with_timeout(h->timeout))
262 del_timer_sync(&h->gc);
263
264 ahash_destroy(h->table);
265#ifdef IP_SET_HASH_WITH_RBTREE
266 rbtree_destroy(&h->rbtree);
267#endif
268 kfree(h);
269
270 set->data = NULL;
271}
272
273#endif /* _IP_SET_AHASH_H */
274
275#ifndef HKEY_DATALEN
276#define HKEY_DATALEN sizeof(struct type_pf_elem)
277#endif
278
279#define HKEY(data, initval, htable_bits) \
280(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \
281 & jhash_mask(htable_bits))
282
283/* Type/family dependent function prototypes */
284
285#define type_pf_data_equal TOKEN(TYPE, PF, _data_equal)
286#define type_pf_data_isnull TOKEN(TYPE, PF, _data_isnull)
287#define type_pf_data_copy TOKEN(TYPE, PF, _data_copy)
288#define type_pf_data_zero_out TOKEN(TYPE, PF, _data_zero_out)
289#define type_pf_data_netmask TOKEN(TYPE, PF, _data_netmask)
290#define type_pf_data_list TOKEN(TYPE, PF, _data_list)
291#define type_pf_data_tlist TOKEN(TYPE, PF, _data_tlist)
292#define type_pf_data_next TOKEN(TYPE, PF, _data_next)
293#define type_pf_data_flags TOKEN(TYPE, PF, _data_flags)
294#define type_pf_data_reset_flags TOKEN(TYPE, PF, _data_reset_flags)
295#ifdef IP_SET_HASH_WITH_NETS
296#define type_pf_data_match TOKEN(TYPE, PF, _data_match)
297#else
298#define type_pf_data_match(d) 1
299#endif
300
301#define type_pf_elem TOKEN(TYPE, PF, _elem)
302#define type_pf_telem TOKEN(TYPE, PF, _telem)
303#define type_pf_data_timeout TOKEN(TYPE, PF, _data_timeout)
304#define type_pf_data_expired TOKEN(TYPE, PF, _data_expired)
305#define type_pf_data_timeout_set TOKEN(TYPE, PF, _data_timeout_set)
306
307#define type_pf_elem_add TOKEN(TYPE, PF, _elem_add)
308#define type_pf_add TOKEN(TYPE, PF, _add)
309#define type_pf_del TOKEN(TYPE, PF, _del)
310#define type_pf_test_cidrs TOKEN(TYPE, PF, _test_cidrs)
311#define type_pf_test TOKEN(TYPE, PF, _test)
312
313#define type_pf_elem_tadd TOKEN(TYPE, PF, _elem_tadd)
314#define type_pf_del_telem TOKEN(TYPE, PF, _ahash_del_telem)
315#define type_pf_expire TOKEN(TYPE, PF, _expire)
316#define type_pf_tadd TOKEN(TYPE, PF, _tadd)
317#define type_pf_tdel TOKEN(TYPE, PF, _tdel)
318#define type_pf_ttest_cidrs TOKEN(TYPE, PF, _ahash_ttest_cidrs)
319#define type_pf_ttest TOKEN(TYPE, PF, _ahash_ttest)
320
321#define type_pf_resize TOKEN(TYPE, PF, _resize)
322#define type_pf_tresize TOKEN(TYPE, PF, _tresize)
323#define type_pf_flush ip_set_hash_flush
324#define type_pf_destroy ip_set_hash_destroy
325#define type_pf_head TOKEN(TYPE, PF, _head)
326#define type_pf_list TOKEN(TYPE, PF, _list)
327#define type_pf_tlist TOKEN(TYPE, PF, _tlist)
328#define type_pf_same_set TOKEN(TYPE, PF, _same_set)
329#define type_pf_kadt TOKEN(TYPE, PF, _kadt)
330#define type_pf_uadt TOKEN(TYPE, PF, _uadt)
331#define type_pf_gc TOKEN(TYPE, PF, _gc)
332#define type_pf_gc_init TOKEN(TYPE, PF, _gc_init)
333#define type_pf_variant TOKEN(TYPE, PF, _variant)
334#define type_pf_tvariant TOKEN(TYPE, PF, _tvariant)
335
336/* Flavour without timeout */
337
338/* Get the ith element from the array block n */
339#define ahash_data(n, i) \
340 ((struct type_pf_elem *)((n)->value) + (i))
341
342/* Add an element to the hash table when resizing the set:
343 * we spare the maintenance of the internal counters. */
344static int
345type_pf_elem_add(struct hbucket *n, const struct type_pf_elem *value,
346 u8 ahash_max, u32 cadt_flags)
347{
348 struct type_pf_elem *data;
349
350 if (n->pos >= n->size) {
351 void *tmp;
352
353 if (n->size >= ahash_max)
354 /* Trigger rehashing */
355 return -EAGAIN;
356
357 tmp = kzalloc((n->size + AHASH_INIT_SIZE)
358 * sizeof(struct type_pf_elem),
359 GFP_ATOMIC);
360 if (!tmp)
361 return -ENOMEM;
362 if (n->size) {
363 memcpy(tmp, n->value,
364 sizeof(struct type_pf_elem) * n->size);
365 kfree(n->value);
366 }
367 n->value = tmp;
368 n->size += AHASH_INIT_SIZE;
369 }
370 data = ahash_data(n, n->pos++);
371 type_pf_data_copy(data, value);
372#ifdef IP_SET_HASH_WITH_NETS
373 /* Resizing won't overwrite stored flags */
374 if (cadt_flags)
375 type_pf_data_flags(data, cadt_flags);
376#endif
377 return 0;
378}
379
380/* Resize a hash: create a new hash table with doubling the hashsize
381 * and inserting the elements to it. Repeat until we succeed or
382 * fail due to memory pressures. */
383static int
384type_pf_resize(struct ip_set *set, bool retried)
385{
386 struct ip_set_hash *h = set->data;
387 struct htable *t, *orig = h->table;
388 u8 htable_bits = orig->htable_bits;
389 struct type_pf_elem *data;
390 struct hbucket *n, *m;
391 u32 i, j, flags = 0;
392 int ret;
393
394retry:
395 ret = 0;
396 htable_bits++;
397 pr_debug("attempt to resize set %s from %u to %u, t %p\n",
398 set->name, orig->htable_bits, htable_bits, orig);
399 if (!htable_bits) {
400 /* In case we have plenty of memory :-) */
401 pr_warning("Cannot increase the hashsize of set %s further\n",
402 set->name);
403 return -IPSET_ERR_HASH_FULL;
404 }
405 t = ip_set_alloc(sizeof(*t)
406 + jhash_size(htable_bits) * sizeof(struct hbucket));
407 if (!t)
408 return -ENOMEM;
409 t->htable_bits = htable_bits;
410
411 read_lock_bh(&set->lock);
412 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
413 n = hbucket(orig, i);
414 for (j = 0; j < n->pos; j++) {
415 data = ahash_data(n, j);
416#ifdef IP_SET_HASH_WITH_NETS
417 flags = 0;
418 type_pf_data_reset_flags(data, &flags);
419#endif
420 m = hbucket(t, HKEY(data, h->initval, htable_bits));
421 ret = type_pf_elem_add(m, data, AHASH_MAX(h), flags);
422 if (ret < 0) {
423#ifdef IP_SET_HASH_WITH_NETS
424 type_pf_data_flags(data, flags);
425#endif
426 read_unlock_bh(&set->lock);
427 ahash_destroy(t);
428 if (ret == -EAGAIN)
429 goto retry;
430 return ret;
431 }
432 }
433 }
434
435 rcu_assign_pointer(h->table, t);
436 read_unlock_bh(&set->lock);
437
438 /* Give time to other readers of the set */
439 synchronize_rcu_bh();
440
441 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
442 orig->htable_bits, orig, t->htable_bits, t);
443 ahash_destroy(orig);
444
445 return 0;
446}
447
448static inline void
449type_pf_data_next(struct ip_set_hash *h, const struct type_pf_elem *d);
450
451/* Add an element to a hash and update the internal counters when succeeded,
452 * otherwise report the proper error code. */
453static int
454type_pf_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
455{
456 struct ip_set_hash *h = set->data;
457 struct htable *t;
458 const struct type_pf_elem *d = value;
459 struct hbucket *n;
460 int i, ret = 0;
461 u32 key, multi = 0;
462 u32 cadt_flags = flags >> 16;
463
464 if (h->elements >= h->maxelem) {
465 if (net_ratelimit())
466 pr_warning("Set %s is full, maxelem %u reached\n",
467 set->name, h->maxelem);
468 return -IPSET_ERR_HASH_FULL;
469 }
470
471 rcu_read_lock_bh();
472 t = rcu_dereference_bh(h->table);
473 key = HKEY(value, h->initval, t->htable_bits);
474 n = hbucket(t, key);
475 for (i = 0; i < n->pos; i++)
476 if (type_pf_data_equal(ahash_data(n, i), d, &multi)) {
477#ifdef IP_SET_HASH_WITH_NETS
478 if (flags & IPSET_FLAG_EXIST)
479 /* Support overwriting just the flags */
480 type_pf_data_flags(ahash_data(n, i),
481 cadt_flags);
482#endif
483 ret = -IPSET_ERR_EXIST;
484 goto out;
485 }
486 TUNE_AHASH_MAX(h, multi);
487 ret = type_pf_elem_add(n, value, AHASH_MAX(h), cadt_flags);
488 if (ret != 0) {
489 if (ret == -EAGAIN)
490 type_pf_data_next(h, d);
491 goto out;
492 }
493
494#ifdef IP_SET_HASH_WITH_NETS
495 add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
496#endif
497 h->elements++;
498out:
499 rcu_read_unlock_bh();
500 return ret;
501}
502
503/* Delete an element from the hash: swap it with the last element
504 * and free up space if possible.
505 */
506static int
507type_pf_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
508{
509 struct ip_set_hash *h = set->data;
510 struct htable *t = h->table;
511 const struct type_pf_elem *d = value;
512 struct hbucket *n;
513 int i;
514 struct type_pf_elem *data;
515 u32 key, multi = 0;
516
517 key = HKEY(value, h->initval, t->htable_bits);
518 n = hbucket(t, key);
519 for (i = 0; i < n->pos; i++) {
520 data = ahash_data(n, i);
521 if (!type_pf_data_equal(data, d, &multi))
522 continue;
523 if (i != n->pos - 1)
524 /* Not last one */
525 type_pf_data_copy(data, ahash_data(n, n->pos - 1));
526
527 n->pos--;
528 h->elements--;
529#ifdef IP_SET_HASH_WITH_NETS
530 del_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
531#endif
532 if (n->pos + AHASH_INIT_SIZE < n->size) {
533 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
534 * sizeof(struct type_pf_elem),
535 GFP_ATOMIC);
536 if (!tmp)
537 return 0;
538 n->size -= AHASH_INIT_SIZE;
539 memcpy(tmp, n->value,
540 n->size * sizeof(struct type_pf_elem));
541 kfree(n->value);
542 n->value = tmp;
543 }
544 return 0;
545 }
546
547 return -IPSET_ERR_EXIST;
548}
549
550#ifdef IP_SET_HASH_WITH_NETS
551
552/* Special test function which takes into account the different network
553 * sizes added to the set */
554static int
555type_pf_test_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
556{
557 struct ip_set_hash *h = set->data;
558 struct htable *t = h->table;
559 struct hbucket *n;
560 const struct type_pf_elem *data;
561 int i, j = 0;
562 u32 key, multi = 0;
563 u8 nets_length = NETS_LENGTH(set->family);
564
565 pr_debug("test by nets\n");
566 for (; j < nets_length && h->nets[j].nets && !multi; j++) {
567 type_pf_data_netmask(d, h->nets[j].cidr);
568 key = HKEY(d, h->initval, t->htable_bits);
569 n = hbucket(t, key);
570 for (i = 0; i < n->pos; i++) {
571 data = ahash_data(n, i);
572 if (type_pf_data_equal(data, d, &multi))
573 return type_pf_data_match(data);
574 }
575 }
576 return 0;
577}
578#endif
579
580/* Test whether the element is added to the set */
581static int
582type_pf_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
583{
584 struct ip_set_hash *h = set->data;
585 struct htable *t = h->table;
586 struct type_pf_elem *d = value;
587 struct hbucket *n;
588 const struct type_pf_elem *data;
589 int i;
590 u32 key, multi = 0;
591
592#ifdef IP_SET_HASH_WITH_NETS
593 /* If we test an IP address and not a network address,
594 * try all possible network sizes */
595 if (CIDR(d->cidr) == SET_HOST_MASK(set->family))
596 return type_pf_test_cidrs(set, d, timeout);
597#endif
598
599 key = HKEY(d, h->initval, t->htable_bits);
600 n = hbucket(t, key);
601 for (i = 0; i < n->pos; i++) {
602 data = ahash_data(n, i);
603 if (type_pf_data_equal(data, d, &multi))
604 return type_pf_data_match(data);
605 }
606 return 0;
607}
608
609/* Reply a HEADER request: fill out the header part of the set */
610static int
611type_pf_head(struct ip_set *set, struct sk_buff *skb)
612{
613 const struct ip_set_hash *h = set->data;
614 struct nlattr *nested;
615 size_t memsize;
616
617 read_lock_bh(&set->lock);
618 memsize = ahash_memsize(h, with_timeout(h->timeout)
619 ? sizeof(struct type_pf_telem)
620 : sizeof(struct type_pf_elem),
621 NETS_LENGTH(set->family));
622 read_unlock_bh(&set->lock);
623
624 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
625 if (!nested)
626 goto nla_put_failure;
627 if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE,
628 htonl(jhash_size(h->table->htable_bits))) ||
629 nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)))
630 goto nla_put_failure;
631#ifdef IP_SET_HASH_WITH_NETMASK
632 if (h->netmask != HOST_MASK &&
633 nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask))
634 goto nla_put_failure;
635#endif
636 if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
637 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
638 (with_timeout(h->timeout) &&
639 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))))
640 goto nla_put_failure;
641 ipset_nest_end(skb, nested);
642
643 return 0;
644nla_put_failure:
645 return -EMSGSIZE;
646}
647
648/* Reply a LIST/SAVE request: dump the elements of the specified set */
649static int
650type_pf_list(const struct ip_set *set,
651 struct sk_buff *skb, struct netlink_callback *cb)
652{
653 const struct ip_set_hash *h = set->data;
654 const struct htable *t = h->table;
655 struct nlattr *atd, *nested;
656 const struct hbucket *n;
657 const struct type_pf_elem *data;
658 u32 first = cb->args[2];
659 /* We assume that one hash bucket fills into one page */
660 void *incomplete;
661 int i;
662
663 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
664 if (!atd)
665 return -EMSGSIZE;
666 pr_debug("list hash set %s\n", set->name);
667 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
668 incomplete = skb_tail_pointer(skb);
669 n = hbucket(t, cb->args[2]);
670 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
671 for (i = 0; i < n->pos; i++) {
672 data = ahash_data(n, i);
673 pr_debug("list hash %lu hbucket %p i %u, data %p\n",
674 cb->args[2], n, i, data);
675 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
676 if (!nested) {
677 if (cb->args[2] == first) {
678 nla_nest_cancel(skb, atd);
679 return -EMSGSIZE;
680 } else
681 goto nla_put_failure;
682 }
683 if (type_pf_data_list(skb, data))
684 goto nla_put_failure;
685 ipset_nest_end(skb, nested);
686 }
687 }
688 ipset_nest_end(skb, atd);
689 /* Set listing finished */
690 cb->args[2] = 0;
691
692 return 0;
693
694nla_put_failure:
695 nlmsg_trim(skb, incomplete);
696 ipset_nest_end(skb, atd);
697 if (unlikely(first == cb->args[2])) {
698 pr_warning("Can't list set %s: one bucket does not fit into "
699 "a message. Please report it!\n", set->name);
700 cb->args[2] = 0;
701 return -EMSGSIZE;
702 }
703 return 0;
704}
705
706static int
707type_pf_kadt(struct ip_set *set, const struct sk_buff *skb,
708 const struct xt_action_param *par,
709 enum ipset_adt adt, const struct ip_set_adt_opt *opt);
710static int
711type_pf_uadt(struct ip_set *set, struct nlattr *tb[],
712 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
713
714static const struct ip_set_type_variant type_pf_variant = {
715 .kadt = type_pf_kadt,
716 .uadt = type_pf_uadt,
717 .adt = {
718 [IPSET_ADD] = type_pf_add,
719 [IPSET_DEL] = type_pf_del,
720 [IPSET_TEST] = type_pf_test,
721 },
722 .destroy = type_pf_destroy,
723 .flush = type_pf_flush,
724 .head = type_pf_head,
725 .list = type_pf_list,
726 .resize = type_pf_resize,
727 .same_set = type_pf_same_set,
728};
729
730/* Flavour with timeout support */
731
732#define ahash_tdata(n, i) \
733 (struct type_pf_elem *)((struct type_pf_telem *)((n)->value) + (i))
734
735static inline u32
736type_pf_data_timeout(const struct type_pf_elem *data)
737{
738 const struct type_pf_telem *tdata =
739 (const struct type_pf_telem *) data;
740
741 return tdata->timeout;
742}
743
744static inline bool
745type_pf_data_expired(const struct type_pf_elem *data)
746{
747 const struct type_pf_telem *tdata =
748 (const struct type_pf_telem *) data;
749
750 return ip_set_timeout_expired(tdata->timeout);
751}
752
753static inline void
754type_pf_data_timeout_set(struct type_pf_elem *data, u32 timeout)
755{
756 struct type_pf_telem *tdata = (struct type_pf_telem *) data;
757
758 tdata->timeout = ip_set_timeout_set(timeout);
759}
760
761static int
762type_pf_elem_tadd(struct hbucket *n, const struct type_pf_elem *value,
763 u8 ahash_max, u32 cadt_flags, u32 timeout)
764{
765 struct type_pf_elem *data;
766
767 if (n->pos >= n->size) {
768 void *tmp;
769
770 if (n->size >= ahash_max)
771 /* Trigger rehashing */
772 return -EAGAIN;
773
774 tmp = kzalloc((n->size + AHASH_INIT_SIZE)
775 * sizeof(struct type_pf_telem),
776 GFP_ATOMIC);
777 if (!tmp)
778 return -ENOMEM;
779 if (n->size) {
780 memcpy(tmp, n->value,
781 sizeof(struct type_pf_telem) * n->size);
782 kfree(n->value);
783 }
784 n->value = tmp;
785 n->size += AHASH_INIT_SIZE;
786 }
787 data = ahash_tdata(n, n->pos++);
788 type_pf_data_copy(data, value);
789 type_pf_data_timeout_set(data, timeout);
790#ifdef IP_SET_HASH_WITH_NETS
791 /* Resizing won't overwrite stored flags */
792 if (cadt_flags)
793 type_pf_data_flags(data, cadt_flags);
794#endif
795 return 0;
796}
797
798/* Delete expired elements from the hashtable */
799static void
800type_pf_expire(struct ip_set_hash *h, u8 nets_length)
801{
802 struct htable *t = h->table;
803 struct hbucket *n;
804 struct type_pf_elem *data;
805 u32 i;
806 int j;
807
808 for (i = 0; i < jhash_size(t->htable_bits); i++) {
809 n = hbucket(t, i);
810 for (j = 0; j < n->pos; j++) {
811 data = ahash_tdata(n, j);
812 if (type_pf_data_expired(data)) {
813 pr_debug("expired %u/%u\n", i, j);
814#ifdef IP_SET_HASH_WITH_NETS
815 del_cidr(h, CIDR(data->cidr), nets_length);
816#endif
817 if (j != n->pos - 1)
818 /* Not last one */
819 type_pf_data_copy(data,
820 ahash_tdata(n, n->pos - 1));
821 n->pos--;
822 h->elements--;
823 }
824 }
825 if (n->pos + AHASH_INIT_SIZE < n->size) {
826 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
827 * sizeof(struct type_pf_telem),
828 GFP_ATOMIC);
829 if (!tmp)
830 /* Still try to delete expired elements */
831 continue;
832 n->size -= AHASH_INIT_SIZE;
833 memcpy(tmp, n->value,
834 n->size * sizeof(struct type_pf_telem));
835 kfree(n->value);
836 n->value = tmp;
837 }
838 }
839}
840
841static int
842type_pf_tresize(struct ip_set *set, bool retried)
843{
844 struct ip_set_hash *h = set->data;
845 struct htable *t, *orig = h->table;
846 u8 htable_bits = orig->htable_bits;
847 struct type_pf_elem *data;
848 struct hbucket *n, *m;
849 u32 i, j, flags = 0;
850 int ret;
851
852 /* Try to cleanup once */
853 if (!retried) {
854 i = h->elements;
855 write_lock_bh(&set->lock);
856 type_pf_expire(set->data, NETS_LENGTH(set->family));
857 write_unlock_bh(&set->lock);
858 if (h->elements < i)
859 return 0;
860 }
861
862retry:
863 ret = 0;
864 htable_bits++;
865 pr_debug("attempt to resize set %s from %u to %u, t %p\n",
866 set->name, orig->htable_bits, htable_bits, orig);
867 if (!htable_bits) {
868 /* In case we have plenty of memory :-) */
869 pr_warning("Cannot increase the hashsize of set %s further\n",
870 set->name);
871 return -IPSET_ERR_HASH_FULL;
872 }
873 t = ip_set_alloc(sizeof(*t)
874 + jhash_size(htable_bits) * sizeof(struct hbucket));
875 if (!t)
876 return -ENOMEM;
877 t->htable_bits = htable_bits;
878
879 read_lock_bh(&set->lock);
880 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
881 n = hbucket(orig, i);
882 for (j = 0; j < n->pos; j++) {
883 data = ahash_tdata(n, j);
884#ifdef IP_SET_HASH_WITH_NETS
885 flags = 0;
886 type_pf_data_reset_flags(data, &flags);
887#endif
888 m = hbucket(t, HKEY(data, h->initval, htable_bits));
889 ret = type_pf_elem_tadd(m, data, AHASH_MAX(h), flags,
890 ip_set_timeout_get(type_pf_data_timeout(data)));
891 if (ret < 0) {
892#ifdef IP_SET_HASH_WITH_NETS
893 type_pf_data_flags(data, flags);
894#endif
895 read_unlock_bh(&set->lock);
896 ahash_destroy(t);
897 if (ret == -EAGAIN)
898 goto retry;
899 return ret;
900 }
901 }
902 }
903
904 rcu_assign_pointer(h->table, t);
905 read_unlock_bh(&set->lock);
906
907 /* Give time to other readers of the set */
908 synchronize_rcu_bh();
909
910 ahash_destroy(orig);
911
912 return 0;
913}
914
915static int
916type_pf_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags)
917{
918 struct ip_set_hash *h = set->data;
919 struct htable *t = h->table;
920 const struct type_pf_elem *d = value;
921 struct hbucket *n;
922 struct type_pf_elem *data;
923 int ret = 0, i, j = AHASH_MAX(h) + 1;
924 bool flag_exist = flags & IPSET_FLAG_EXIST;
925 u32 key, multi = 0;
926 u32 cadt_flags = flags >> 16;
927
928 if (h->elements >= h->maxelem)
929 /* FIXME: when set is full, we slow down here */
930 type_pf_expire(h, NETS_LENGTH(set->family));
931 if (h->elements >= h->maxelem) {
932 if (net_ratelimit())
933 pr_warning("Set %s is full, maxelem %u reached\n",
934 set->name, h->maxelem);
935 return -IPSET_ERR_HASH_FULL;
936 }
937
938 rcu_read_lock_bh();
939 t = rcu_dereference_bh(h->table);
940 key = HKEY(d, h->initval, t->htable_bits);
941 n = hbucket(t, key);
942 for (i = 0; i < n->pos; i++) {
943 data = ahash_tdata(n, i);
944 if (type_pf_data_equal(data, d, &multi)) {
945 if (type_pf_data_expired(data) || flag_exist)
946 /* Just timeout value may be updated */
947 j = i;
948 else {
949 ret = -IPSET_ERR_EXIST;
950 goto out;
951 }
952 } else if (j == AHASH_MAX(h) + 1 &&
953 type_pf_data_expired(data))
954 j = i;
955 }
956 if (j != AHASH_MAX(h) + 1) {
957 data = ahash_tdata(n, j);
958#ifdef IP_SET_HASH_WITH_NETS
959 del_cidr(h, CIDR(data->cidr), NETS_LENGTH(set->family));
960 add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
961#endif
962 type_pf_data_copy(data, d);
963 type_pf_data_timeout_set(data, timeout);
964#ifdef IP_SET_HASH_WITH_NETS
965 type_pf_data_flags(data, cadt_flags);
966#endif
967 goto out;
968 }
969 TUNE_AHASH_MAX(h, multi);
970 ret = type_pf_elem_tadd(n, d, AHASH_MAX(h), cadt_flags, timeout);
971 if (ret != 0) {
972 if (ret == -EAGAIN)
973 type_pf_data_next(h, d);
974 goto out;
975 }
976
977#ifdef IP_SET_HASH_WITH_NETS
978 add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
979#endif
980 h->elements++;
981out:
982 rcu_read_unlock_bh();
983 return ret;
984}
985
986static int
987type_pf_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags)
988{
989 struct ip_set_hash *h = set->data;
990 struct htable *t = h->table;
991 const struct type_pf_elem *d = value;
992 struct hbucket *n;
993 int i;
994 struct type_pf_elem *data;
995 u32 key, multi = 0;
996
997 key = HKEY(value, h->initval, t->htable_bits);
998 n = hbucket(t, key);
999 for (i = 0; i < n->pos; i++) {
1000 data = ahash_tdata(n, i);
1001 if (!type_pf_data_equal(data, d, &multi))
1002 continue;
1003 if (type_pf_data_expired(data))
1004 return -IPSET_ERR_EXIST;
1005 if (i != n->pos - 1)
1006 /* Not last one */
1007 type_pf_data_copy(data, ahash_tdata(n, n->pos - 1));
1008
1009 n->pos--;
1010 h->elements--;
1011#ifdef IP_SET_HASH_WITH_NETS
1012 del_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
1013#endif
1014 if (n->pos + AHASH_INIT_SIZE < n->size) {
1015 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
1016 * sizeof(struct type_pf_telem),
1017 GFP_ATOMIC);
1018 if (!tmp)
1019 return 0;
1020 n->size -= AHASH_INIT_SIZE;
1021 memcpy(tmp, n->value,
1022 n->size * sizeof(struct type_pf_telem));
1023 kfree(n->value);
1024 n->value = tmp;
1025 }
1026 return 0;
1027 }
1028
1029 return -IPSET_ERR_EXIST;
1030}
1031
1032#ifdef IP_SET_HASH_WITH_NETS
1033static int
1034type_pf_ttest_cidrs(struct ip_set *set, struct type_pf_elem *d, u32 timeout)
1035{
1036 struct ip_set_hash *h = set->data;
1037 struct htable *t = h->table;
1038 struct type_pf_elem *data;
1039 struct hbucket *n;
1040 int i, j = 0;
1041 u32 key, multi = 0;
1042 u8 nets_length = NETS_LENGTH(set->family);
1043
1044 for (; j < nets_length && h->nets[j].nets && !multi; j++) {
1045 type_pf_data_netmask(d, h->nets[j].cidr);
1046 key = HKEY(d, h->initval, t->htable_bits);
1047 n = hbucket(t, key);
1048 for (i = 0; i < n->pos; i++) {
1049 data = ahash_tdata(n, i);
1050#ifdef IP_SET_HASH_WITH_MULTI
1051 if (type_pf_data_equal(data, d, &multi)) {
1052 if (!type_pf_data_expired(data))
1053 return type_pf_data_match(data);
1054 multi = 0;
1055 }
1056#else
1057 if (type_pf_data_equal(data, d, &multi) &&
1058 !type_pf_data_expired(data))
1059 return type_pf_data_match(data);
1060#endif
1061 }
1062 }
1063 return 0;
1064}
1065#endif
1066
1067static int
1068type_pf_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
1069{
1070 struct ip_set_hash *h = set->data;
1071 struct htable *t = h->table;
1072 struct type_pf_elem *data, *d = value;
1073 struct hbucket *n;
1074 int i;
1075 u32 key, multi = 0;
1076
1077#ifdef IP_SET_HASH_WITH_NETS
1078 if (CIDR(d->cidr) == SET_HOST_MASK(set->family))
1079 return type_pf_ttest_cidrs(set, d, timeout);
1080#endif
1081 key = HKEY(d, h->initval, t->htable_bits);
1082 n = hbucket(t, key);
1083 for (i = 0; i < n->pos; i++) {
1084 data = ahash_tdata(n, i);
1085 if (type_pf_data_equal(data, d, &multi) &&
1086 !type_pf_data_expired(data))
1087 return type_pf_data_match(data);
1088 }
1089 return 0;
1090}
1091
1092static int
1093type_pf_tlist(const struct ip_set *set,
1094 struct sk_buff *skb, struct netlink_callback *cb)
1095{
1096 const struct ip_set_hash *h = set->data;
1097 const struct htable *t = h->table;
1098 struct nlattr *atd, *nested;
1099 const struct hbucket *n;
1100 const struct type_pf_elem *data;
1101 u32 first = cb->args[2];
1102 /* We assume that one hash bucket fills into one page */
1103 void *incomplete;
1104 int i;
1105
1106 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
1107 if (!atd)
1108 return -EMSGSIZE;
1109 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
1110 incomplete = skb_tail_pointer(skb);
1111 n = hbucket(t, cb->args[2]);
1112 for (i = 0; i < n->pos; i++) {
1113 data = ahash_tdata(n, i);
1114 pr_debug("list %p %u\n", n, i);
1115 if (type_pf_data_expired(data))
1116 continue;
1117 pr_debug("do list %p %u\n", n, i);
1118 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
1119 if (!nested) {
1120 if (cb->args[2] == first) {
1121 nla_nest_cancel(skb, atd);
1122 return -EMSGSIZE;
1123 } else
1124 goto nla_put_failure;
1125 }
1126 if (type_pf_data_tlist(skb, data))
1127 goto nla_put_failure;
1128 ipset_nest_end(skb, nested);
1129 }
1130 }
1131 ipset_nest_end(skb, atd);
1132 /* Set listing finished */
1133 cb->args[2] = 0;
1134
1135 return 0;
1136
1137nla_put_failure:
1138 nlmsg_trim(skb, incomplete);
1139 ipset_nest_end(skb, atd);
1140 if (unlikely(first == cb->args[2])) {
1141 pr_warning("Can't list set %s: one bucket does not fit into "
1142 "a message. Please report it!\n", set->name);
1143 cb->args[2] = 0;
1144 return -EMSGSIZE;
1145 }
1146 return 0;
1147}
1148
1149static const struct ip_set_type_variant type_pf_tvariant = {
1150 .kadt = type_pf_kadt,
1151 .uadt = type_pf_uadt,
1152 .adt = {
1153 [IPSET_ADD] = type_pf_tadd,
1154 [IPSET_DEL] = type_pf_tdel,
1155 [IPSET_TEST] = type_pf_ttest,
1156 },
1157 .destroy = type_pf_destroy,
1158 .flush = type_pf_flush,
1159 .head = type_pf_head,
1160 .list = type_pf_tlist,
1161 .resize = type_pf_tresize,
1162 .same_set = type_pf_same_set,
1163};
1164
1165static void
1166type_pf_gc(unsigned long ul_set)
1167{
1168 struct ip_set *set = (struct ip_set *) ul_set;
1169 struct ip_set_hash *h = set->data;
1170
1171 pr_debug("called\n");
1172 write_lock_bh(&set->lock);
1173 type_pf_expire(h, NETS_LENGTH(set->family));
1174 write_unlock_bh(&set->lock);
1175
1176 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
1177 add_timer(&h->gc);
1178}
1179
1180static void
1181type_pf_gc_init(struct ip_set *set)
1182{
1183 struct ip_set_hash *h = set->data;
1184
1185 init_timer(&h->gc);
1186 h->gc.data = (unsigned long) set;
1187 h->gc.function = type_pf_gc;
1188 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
1189 add_timer(&h->gc);
1190 pr_debug("gc initialized, run in every %u\n",
1191 IPSET_GC_PERIOD(h->timeout));
1192}
1193
1194#undef HKEY_DATALEN
1195#undef HKEY
1196#undef type_pf_data_equal
1197#undef type_pf_data_isnull
1198#undef type_pf_data_copy
1199#undef type_pf_data_zero_out
1200#undef type_pf_data_netmask
1201#undef type_pf_data_list
1202#undef type_pf_data_tlist
1203#undef type_pf_data_next
1204#undef type_pf_data_flags
1205#undef type_pf_data_reset_flags
1206#undef type_pf_data_match
1207
1208#undef type_pf_elem
1209#undef type_pf_telem
1210#undef type_pf_data_timeout
1211#undef type_pf_data_expired
1212#undef type_pf_data_timeout_set
1213
1214#undef type_pf_elem_add
1215#undef type_pf_add
1216#undef type_pf_del
1217#undef type_pf_test_cidrs
1218#undef type_pf_test
1219
1220#undef type_pf_elem_tadd
1221#undef type_pf_del_telem
1222#undef type_pf_expire
1223#undef type_pf_tadd
1224#undef type_pf_tdel
1225#undef type_pf_ttest_cidrs
1226#undef type_pf_ttest
1227
1228#undef type_pf_resize
1229#undef type_pf_tresize
1230#undef type_pf_flush
1231#undef type_pf_destroy
1232#undef type_pf_head
1233#undef type_pf_list
1234#undef type_pf_tlist
1235#undef type_pf_same_set
1236#undef type_pf_kadt
1237#undef type_pf_uadt
1238#undef type_pf_gc
1239#undef type_pf_gc_init
1240#undef type_pf_variant
1241#undef type_pf_tvariant
diff --git a/include/linux/netfilter/ipset/ip_set_bitmap.h b/include/linux/netfilter/ipset/ip_set_bitmap.h
index 1a30646d5be8..5e4662a71e01 100644
--- a/include/linux/netfilter/ipset/ip_set_bitmap.h
+++ b/include/linux/netfilter/ipset/ip_set_bitmap.h
@@ -5,6 +5,12 @@
5 5
6#define IPSET_BITMAP_MAX_RANGE 0x0000FFFF 6#define IPSET_BITMAP_MAX_RANGE 0x0000FFFF
7 7
8enum {
9 IPSET_ADD_FAILED = 1,
10 IPSET_ADD_STORE_PLAIN_TIMEOUT,
11 IPSET_ADD_START_STORED_TIMEOUT,
12};
13
8/* Common functions */ 14/* Common functions */
9 15
10static inline u32 16static inline u32
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/include/linux/netfilter/ipset/pfxlen.h b/include/linux/netfilter/ipset/pfxlen.h
index 199fd11fedc0..1afbb94b4b65 100644
--- a/include/linux/netfilter/ipset/pfxlen.h
+++ b/include/linux/netfilter/ipset/pfxlen.h
@@ -41,4 +41,13 @@ do { \
41 to = from | ~ip_set_hostmask(cidr); \ 41 to = from | ~ip_set_hostmask(cidr); \
42} while (0) 42} while (0)
43 43
44static inline void
45ip6_netmask(union nf_inet_addr *ip, u8 prefix)
46{
47 ip->ip6[0] &= ip_set_netmask6(prefix)[0];
48 ip->ip6[1] &= ip_set_netmask6(prefix)[1];
49 ip->ip6[2] &= ip_set_netmask6(prefix)[2];
50 ip->ip6[3] &= ip_set_netmask6(prefix)[3];
51}
52
44#endif /*_PFXLEN_H */ 53#endif /*_PFXLEN_H */
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
index fb1c0be38b6d..aaba4bbcdda0 100644
--- a/include/net/netfilter/nf_queue.h
+++ b/include/net/netfilter/nf_queue.h
@@ -9,10 +9,13 @@ struct nf_queue_entry {
9 9
10 struct nf_hook_ops *elem; 10 struct nf_hook_ops *elem;
11 u_int8_t pf; 11 u_int8_t pf;
12 u16 size; /* sizeof(entry) + saved route keys */
12 unsigned int hook; 13 unsigned int hook;
13 struct net_device *indev; 14 struct net_device *indev;
14 struct net_device *outdev; 15 struct net_device *outdev;
15 int (*okfn)(struct sk_buff *); 16 int (*okfn)(struct sk_buff *);
17
18 /* extra space to store route keys */
16}; 19};
17 20
18#define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry)) 21#define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
@@ -27,4 +30,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh);
27void nf_unregister_queue_handler(void); 30void nf_unregister_queue_handler(void);
28extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); 31extern void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
29 32
33bool nf_queue_entry_get_refs(struct nf_queue_entry *entry);
34void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
35
30#endif /* _NF_QUEUE_H */ 36#endif /* _NF_QUEUE_H */
diff --git a/include/net/sctp/checksum.h b/include/net/sctp/checksum.h
index befc8d2a1b9f..5a2110d3176d 100644
--- a/include/net/sctp/checksum.h
+++ b/include/net/sctp/checksum.h
@@ -77,7 +77,7 @@ static inline __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
77 return sctp_crc32c(crc32, buffer, length); 77 return sctp_crc32c(crc32, buffer, length);
78} 78}
79 79
80static inline __le32 sctp_end_cksum(__be32 crc32) 80static inline __le32 sctp_end_cksum(__u32 crc32)
81{ 81{
82 return cpu_to_le32(~crc32); 82 return cpu_to_le32(~crc32);
83} 83}
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index fbee42807a11..8024cdf13b70 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -108,6 +108,8 @@ enum {
108 IPSET_ATTR_CIDR2, 108 IPSET_ATTR_CIDR2,
109 IPSET_ATTR_IP2_TO, 109 IPSET_ATTR_IP2_TO,
110 IPSET_ATTR_IFACE, 110 IPSET_ATTR_IFACE,
111 IPSET_ATTR_BYTES,
112 IPSET_ATTR_PACKETS,
111 __IPSET_ATTR_ADT_MAX, 113 __IPSET_ATTR_ADT_MAX,
112}; 114};
113#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1) 115#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
@@ -137,12 +139,13 @@ enum ipset_errno {
137 IPSET_ERR_REFERENCED, 139 IPSET_ERR_REFERENCED,
138 IPSET_ERR_IPADDR_IPV4, 140 IPSET_ERR_IPADDR_IPV4,
139 IPSET_ERR_IPADDR_IPV6, 141 IPSET_ERR_IPADDR_IPV6,
142 IPSET_ERR_COUNTER,
140 143
141 /* Type specific error codes */ 144 /* Type specific error codes */
142 IPSET_ERR_TYPE_SPECIFIC = 4352, 145 IPSET_ERR_TYPE_SPECIFIC = 4352,
143}; 146};
144 147
145/* Flags at command level */ 148/* Flags at command level or match/target flags, lower half of cmdattrs*/
146enum ipset_cmd_flags { 149enum ipset_cmd_flags {
147 IPSET_FLAG_BIT_EXIST = 0, 150 IPSET_FLAG_BIT_EXIST = 0,
148 IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST), 151 IPSET_FLAG_EXIST = (1 << IPSET_FLAG_BIT_EXIST),
@@ -150,10 +153,20 @@ enum ipset_cmd_flags {
150 IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME), 153 IPSET_FLAG_LIST_SETNAME = (1 << IPSET_FLAG_BIT_LIST_SETNAME),
151 IPSET_FLAG_BIT_LIST_HEADER = 2, 154 IPSET_FLAG_BIT_LIST_HEADER = 2,
152 IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER), 155 IPSET_FLAG_LIST_HEADER = (1 << IPSET_FLAG_BIT_LIST_HEADER),
153 IPSET_FLAG_CMD_MAX = 15, /* Lower half */ 156 IPSET_FLAG_BIT_SKIP_COUNTER_UPDATE = 3,
157 IPSET_FLAG_SKIP_COUNTER_UPDATE =
158 (1 << IPSET_FLAG_BIT_SKIP_COUNTER_UPDATE),
159 IPSET_FLAG_BIT_SKIP_SUBCOUNTER_UPDATE = 4,
160 IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE =
161 (1 << IPSET_FLAG_BIT_SKIP_SUBCOUNTER_UPDATE),
162 IPSET_FLAG_BIT_MATCH_COUNTERS = 5,
163 IPSET_FLAG_MATCH_COUNTERS = (1 << IPSET_FLAG_BIT_MATCH_COUNTERS),
164 IPSET_FLAG_BIT_RETURN_NOMATCH = 7,
165 IPSET_FLAG_RETURN_NOMATCH = (1 << IPSET_FLAG_BIT_RETURN_NOMATCH),
166 IPSET_FLAG_CMD_MAX = 15,
154}; 167};
155 168
156/* Flags at CADT attribute level */ 169/* Flags at CADT attribute level, upper half of cmdattrs */
157enum ipset_cadt_flags { 170enum ipset_cadt_flags {
158 IPSET_FLAG_BIT_BEFORE = 0, 171 IPSET_FLAG_BIT_BEFORE = 0,
159 IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE), 172 IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE),
@@ -161,7 +174,9 @@ enum ipset_cadt_flags {
161 IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV), 174 IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV),
162 IPSET_FLAG_BIT_NOMATCH = 2, 175 IPSET_FLAG_BIT_NOMATCH = 2,
163 IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH), 176 IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
164 IPSET_FLAG_CADT_MAX = 15, /* Upper half */ 177 IPSET_FLAG_BIT_WITH_COUNTERS = 3,
178 IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
179 IPSET_FLAG_CADT_MAX = 15,
165}; 180};
166 181
167/* Commands with settype-specific attributes */ 182/* Commands with settype-specific attributes */
@@ -190,6 +205,7 @@ enum ip_set_dim {
190 * If changed, new revision of iptables match/target is required. 205 * If changed, new revision of iptables match/target is required.
191 */ 206 */
192 IPSET_DIM_MAX = 6, 207 IPSET_DIM_MAX = 6,
208 /* Backward compatibility: set match revision 2 */
193 IPSET_BIT_RETURN_NOMATCH = 7, 209 IPSET_BIT_RETURN_NOMATCH = 7,
194}; 210};
195 211
@@ -202,6 +218,18 @@ enum ip_set_kopt {
202 IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH), 218 IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
203}; 219};
204 220
221enum {
222 IPSET_COUNTER_NONE = 0,
223 IPSET_COUNTER_EQ,
224 IPSET_COUNTER_NE,
225 IPSET_COUNTER_LT,
226 IPSET_COUNTER_GT,
227};
228
229struct ip_set_counter_match {
230 __u8 op;
231 __u64 value;
232};
205 233
206/* Interface to iptables/ip6tables */ 234/* Interface to iptables/ip6tables */
207 235
diff --git a/include/uapi/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
index 70ec8c2bc11a..a2308ae5a73d 100644
--- a/include/uapi/linux/netfilter/nfnetlink_queue.h
+++ b/include/uapi/linux/netfilter/nfnetlink_queue.h
@@ -45,6 +45,7 @@ enum nfqnl_attr_type {
45 NFQA_CT, /* nf_conntrack_netlink.h */ 45 NFQA_CT, /* nf_conntrack_netlink.h */
46 NFQA_CT_INFO, /* enum ip_conntrack_info */ 46 NFQA_CT_INFO, /* enum ip_conntrack_info */
47 NFQA_CAP_LEN, /* __u32 length of captured packet */ 47 NFQA_CAP_LEN, /* __u32 length of captured packet */
48 NFQA_SKB_INFO, /* __u32 skb meta information */
48 49
49 __NFQA_MAX 50 __NFQA_MAX
50}; 51};
@@ -96,6 +97,13 @@ enum nfqnl_attr_config {
96/* Flags for NFQA_CFG_FLAGS */ 97/* Flags for NFQA_CFG_FLAGS */
97#define NFQA_CFG_F_FAIL_OPEN (1 << 0) 98#define NFQA_CFG_F_FAIL_OPEN (1 << 0)
98#define NFQA_CFG_F_CONNTRACK (1 << 1) 99#define NFQA_CFG_F_CONNTRACK (1 << 1)
99#define NFQA_CFG_F_MAX (1 << 2) 100#define NFQA_CFG_F_GSO (1 << 2)
101#define NFQA_CFG_F_MAX (1 << 3)
102
103/* flags for NFQA_SKB_INFO */
104/* packet appears to have wrong checksums, but they are ok */
105#define NFQA_SKB_CSUMNOTREADY (1 << 0)
106/* packet is GSO (i.e., exceeds device mtu) */
107#define NFQA_SKB_GSO (1 << 1)
100 108
101#endif /* _NFNETLINK_QUEUE_H */ 109#endif /* _NFNETLINK_QUEUE_H */
diff --git a/include/uapi/linux/netfilter/xt_set.h b/include/uapi/linux/netfilter/xt_set.h
index e3a9978f259f..964d3d42f874 100644
--- a/include/uapi/linux/netfilter/xt_set.h
+++ b/include/uapi/linux/netfilter/xt_set.h
@@ -62,4 +62,13 @@ struct xt_set_info_target_v2 {
62 __u32 timeout; 62 __u32 timeout;
63}; 63};
64 64
65/* Revision 3 match */
66
67struct xt_set_info_match_v3 {
68 struct xt_set_info match_set;
69 struct ip_set_counter_match packets;
70 struct ip_set_counter_match bytes;
71 __u32 flags;
72};
73
65#endif /*_XT_SET_H*/ 74#endif /*_XT_SET_H*/
diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h
new file mode 100644
index 000000000000..25243379b887
--- /dev/null
+++ b/net/netfilter/ipset/ip_set_bitmap_gen.h
@@ -0,0 +1,277 @@
1/* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
7
8#ifndef __IP_SET_BITMAP_IP_GEN_H
9#define __IP_SET_BITMAP_IP_GEN_H
10
11#define CONCAT(a, b) a##b
12#define TOKEN(a,b) CONCAT(a, b)
13
14#define mtype_do_test TOKEN(MTYPE, _do_test)
15#define mtype_gc_test TOKEN(MTYPE, _gc_test)
16#define mtype_is_filled TOKEN(MTYPE, _is_filled)
17#define mtype_do_add TOKEN(MTYPE, _do_add)
18#define mtype_do_del TOKEN(MTYPE, _do_del)
19#define mtype_do_list TOKEN(MTYPE, _do_list)
20#define mtype_do_head TOKEN(MTYPE, _do_head)
21#define mtype_adt_elem TOKEN(MTYPE, _adt_elem)
22#define mtype_add_timeout TOKEN(MTYPE, _add_timeout)
23#define mtype_gc_init TOKEN(MTYPE, _gc_init)
24#define mtype_kadt TOKEN(MTYPE, _kadt)
25#define mtype_uadt TOKEN(MTYPE, _uadt)
26#define mtype_destroy TOKEN(MTYPE, _destroy)
27#define mtype_flush TOKEN(MTYPE, _flush)
28#define mtype_head TOKEN(MTYPE, _head)
29#define mtype_same_set TOKEN(MTYPE, _same_set)
30#define mtype_elem TOKEN(MTYPE, _elem)
31#define mtype_test TOKEN(MTYPE, _test)
32#define mtype_add TOKEN(MTYPE, _add)
33#define mtype_del TOKEN(MTYPE, _del)
34#define mtype_list TOKEN(MTYPE, _list)
35#define mtype_gc TOKEN(MTYPE, _gc)
36#define mtype MTYPE
37
38#define ext_timeout(e, m) \
39 (unsigned long *)((e) + (m)->offset[IPSET_OFFSET_TIMEOUT])
40#define ext_counter(e, m) \
41 (struct ip_set_counter *)((e) + (m)->offset[IPSET_OFFSET_COUNTER])
42#define get_ext(map, id) ((map)->extensions + (map)->dsize * (id))
43
44static void
45mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
46{
47 struct mtype *map = set->data;
48
49 init_timer(&map->gc);
50 map->gc.data = (unsigned long) set;
51 map->gc.function = gc;
52 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
53 add_timer(&map->gc);
54}
55
56static void
57mtype_destroy(struct ip_set *set)
58{
59 struct mtype *map = set->data;
60
61 if (SET_WITH_TIMEOUT(set))
62 del_timer_sync(&map->gc);
63
64 ip_set_free(map->members);
65 if (map->dsize)
66 ip_set_free(map->extensions);
67 kfree(map);
68
69 set->data = NULL;
70}
71
72static void
73mtype_flush(struct ip_set *set)
74{
75 struct mtype *map = set->data;
76
77 memset(map->members, 0, map->memsize);
78}
79
80static int
81mtype_head(struct ip_set *set, struct sk_buff *skb)
82{
83 const struct mtype *map = set->data;
84 struct nlattr *nested;
85
86 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
87 if (!nested)
88 goto nla_put_failure;
89 if (mtype_do_head(skb, map) ||
90 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
91 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
92 htonl(sizeof(*map) +
93 map->memsize +
94 map->dsize * map->elements)) ||
95 (SET_WITH_TIMEOUT(set) &&
96 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
97 (SET_WITH_COUNTER(set) &&
98 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
99 htonl(IPSET_FLAG_WITH_COUNTERS))))
100 goto nla_put_failure;
101 ipset_nest_end(skb, nested);
102
103 return 0;
104nla_put_failure:
105 return -EMSGSIZE;
106}
107
108static int
109mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
110 struct ip_set_ext *mext, u32 flags)
111{
112 struct mtype *map = set->data;
113 const struct mtype_adt_elem *e = value;
114 void *x = get_ext(map, e->id);
115 int ret = mtype_do_test(e, map);
116
117 if (ret <= 0)
118 return ret;
119 if (SET_WITH_TIMEOUT(set) &&
120 ip_set_timeout_expired(ext_timeout(x, map)))
121 return 0;
122 if (SET_WITH_COUNTER(set))
123 ip_set_update_counter(ext_counter(x, map), ext, mext, flags);
124 return 1;
125}
126
127static int
128mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
129 struct ip_set_ext *mext, u32 flags)
130{
131 struct mtype *map = set->data;
132 const struct mtype_adt_elem *e = value;
133 void *x = get_ext(map, e->id);
134 int ret = mtype_do_add(e, map, flags);
135
136 if (ret == IPSET_ADD_FAILED) {
137 if (SET_WITH_TIMEOUT(set) &&
138 ip_set_timeout_expired(ext_timeout(x, map)))
139 ret = 0;
140 else if (!(flags & IPSET_FLAG_EXIST))
141 return -IPSET_ERR_EXIST;
142 }
143
144 if (SET_WITH_TIMEOUT(set))
145#ifdef IP_SET_BITMAP_STORED_TIMEOUT
146 mtype_add_timeout(ext_timeout(x, map), e, ext, map, ret);
147#else
148 ip_set_timeout_set(ext_timeout(x, map), ext->timeout);
149#endif
150
151 if (SET_WITH_COUNTER(set))
152 ip_set_init_counter(ext_counter(x, map), ext);
153 return 0;
154}
155
156static int
157mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
158 struct ip_set_ext *mext, u32 flags)
159{
160 struct mtype *map = set->data;
161 const struct mtype_adt_elem *e = value;
162 const void *x = get_ext(map, e->id);
163
164 if (mtype_do_del(e, map) ||
165 (SET_WITH_TIMEOUT(set) &&
166 ip_set_timeout_expired(ext_timeout(x, map))))
167 return -IPSET_ERR_EXIST;
168
169 return 0;
170}
171
172static int
173mtype_list(const struct ip_set *set,
174 struct sk_buff *skb, struct netlink_callback *cb)
175{
176 struct mtype *map = set->data;
177 struct nlattr *adt, *nested;
178 void *x;
179 u32 id, first = cb->args[2];
180
181 adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
182 if (!adt)
183 return -EMSGSIZE;
184 for (; cb->args[2] < map->elements; cb->args[2]++) {
185 id = cb->args[2];
186 x = get_ext(map, id);
187 if (!test_bit(id, map->members) ||
188 (SET_WITH_TIMEOUT(set) &&
189#ifdef IP_SET_BITMAP_STORED_TIMEOUT
190 mtype_is_filled((const struct mtype_elem *) x) &&
191#endif
192 ip_set_timeout_expired(ext_timeout(x, map))))
193 continue;
194 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
195 if (!nested) {
196 if (id == first) {
197 nla_nest_cancel(skb, adt);
198 return -EMSGSIZE;
199 } else
200 goto nla_put_failure;
201 }
202 if (mtype_do_list(skb, map, id))
203 goto nla_put_failure;
204 if (SET_WITH_TIMEOUT(set)) {
205#ifdef IP_SET_BITMAP_STORED_TIMEOUT
206 if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
207 htonl(ip_set_timeout_stored(map, id,
208 ext_timeout(x, map)))))
209 goto nla_put_failure;
210#else
211 if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
212 htonl(ip_set_timeout_get(
213 ext_timeout(x, map)))))
214 goto nla_put_failure;
215#endif
216 }
217 if (SET_WITH_COUNTER(set) &&
218 ip_set_put_counter(skb, ext_counter(x, map)))
219 goto nla_put_failure;
220 ipset_nest_end(skb, nested);
221 }
222 ipset_nest_end(skb, adt);
223
224 /* Set listing finished */
225 cb->args[2] = 0;
226
227 return 0;
228
229nla_put_failure:
230 nla_nest_cancel(skb, nested);
231 ipset_nest_end(skb, adt);
232 if (unlikely(id == first)) {
233 cb->args[2] = 0;
234 return -EMSGSIZE;
235 }
236 return 0;
237}
238
239static void
240mtype_gc(unsigned long ul_set)
241{
242 struct ip_set *set = (struct ip_set *) ul_set;
243 struct mtype *map = set->data;
244 const void *x;
245 u32 id;
246
247 /* We run parallel with other readers (test element)
248 * but adding/deleting new entries is locked out */
249 read_lock_bh(&set->lock);
250 for (id = 0; id < map->elements; id++)
251 if (mtype_gc_test(id, map)) {
252 x = get_ext(map, id);
253 if (ip_set_timeout_expired(ext_timeout(x, map)))
254 clear_bit(id, map->members);
255 }
256 read_unlock_bh(&set->lock);
257
258 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
259 add_timer(&map->gc);
260}
261
262static const struct ip_set_type_variant mtype = {
263 .kadt = mtype_kadt,
264 .uadt = mtype_uadt,
265 .adt = {
266 [IPSET_ADD] = mtype_add,
267 [IPSET_DEL] = mtype_del,
268 [IPSET_TEST] = mtype_test,
269 },
270 .destroy = mtype_destroy,
271 .flush = mtype_flush,
272 .head = mtype_head,
273 .list = mtype_list,
274 .same_set = mtype_same_set,
275};
276
277#endif /* __IP_SET_BITMAP_IP_GEN_H */
diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c
index 4a92fd47bd4c..f1a8128bef01 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ip.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ip.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
@@ -24,31 +24,37 @@
24#include <linux/netfilter/ipset/pfxlen.h> 24#include <linux/netfilter/ipset/pfxlen.h>
25#include <linux/netfilter/ipset/ip_set.h> 25#include <linux/netfilter/ipset/ip_set.h>
26#include <linux/netfilter/ipset/ip_set_bitmap.h> 26#include <linux/netfilter/ipset/ip_set_bitmap.h>
27#define IP_SET_BITMAP_TIMEOUT
28#include <linux/netfilter/ipset/ip_set_timeout.h>
29 27
30#define REVISION_MIN 0 28#define REVISION_MIN 0
31#define REVISION_MAX 0 29#define REVISION_MAX 1 /* Counter support added */
32 30
33MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
35IP_SET_MODULE_DESC("bitmap:ip", REVISION_MIN, REVISION_MAX); 33IP_SET_MODULE_DESC("bitmap:ip", REVISION_MIN, REVISION_MAX);
36MODULE_ALIAS("ip_set_bitmap:ip"); 34MODULE_ALIAS("ip_set_bitmap:ip");
37 35
36#define MTYPE bitmap_ip
37
38/* Type structure */ 38/* Type structure */
39struct bitmap_ip { 39struct bitmap_ip {
40 void *members; /* the set members */ 40 void *members; /* the set members */
41 void *extensions; /* data extensions */
41 u32 first_ip; /* host byte order, included in range */ 42 u32 first_ip; /* host byte order, included in range */
42 u32 last_ip; /* host byte order, included in range */ 43 u32 last_ip; /* host byte order, included in range */
43 u32 elements; /* number of max elements in the set */ 44 u32 elements; /* number of max elements in the set */
44 u32 hosts; /* number of hosts in a subnet */ 45 u32 hosts; /* number of hosts in a subnet */
45 size_t memsize; /* members size */ 46 size_t memsize; /* members size */
47 size_t dsize; /* extensions struct size */
48 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
46 u8 netmask; /* subnet netmask */ 49 u8 netmask; /* subnet netmask */
47 u32 timeout; /* timeout parameter */ 50 u32 timeout; /* timeout parameter */
48 struct timer_list gc; /* garbage collection */ 51 struct timer_list gc; /* garbage collection */
49}; 52};
50 53
51/* Base variant */ 54/* ADT structure for generic function args */
55struct bitmap_ip_adt_elem {
56 u16 id;
57};
52 58
53static inline u32 59static inline u32
54ip_to_id(const struct bitmap_ip *m, u32 ip) 60ip_to_id(const struct bitmap_ip *m, u32 ip)
@@ -56,188 +62,67 @@ ip_to_id(const struct bitmap_ip *m, u32 ip)
56 return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts; 62 return ((ip & ip_set_hostmask(m->netmask)) - m->first_ip)/m->hosts;
57} 63}
58 64
59static int 65/* Common functions */
60bitmap_ip_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
61{
62 const struct bitmap_ip *map = set->data;
63 u16 id = *(u16 *)value;
64
65 return !!test_bit(id, map->members);
66}
67 66
68static int 67static inline int
69bitmap_ip_add(struct ip_set *set, void *value, u32 timeout, u32 flags) 68bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
70{ 69{
71 struct bitmap_ip *map = set->data; 70 return !!test_bit(e->id, map->members);
72 u16 id = *(u16 *)value;
73
74 if (test_and_set_bit(id, map->members))
75 return -IPSET_ERR_EXIST;
76
77 return 0;
78} 71}
79 72
80static int 73static inline int
81bitmap_ip_del(struct ip_set *set, void *value, u32 timeout, u32 flags) 74bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map)
82{ 75{
83 struct bitmap_ip *map = set->data; 76 return !!test_bit(id, map->members);
84 u16 id = *(u16 *)value;
85
86 if (!test_and_clear_bit(id, map->members))
87 return -IPSET_ERR_EXIST;
88
89 return 0;
90}
91
92static int
93bitmap_ip_list(const struct ip_set *set,
94 struct sk_buff *skb, struct netlink_callback *cb)
95{
96 const struct bitmap_ip *map = set->data;
97 struct nlattr *atd, *nested;
98 u32 id, first = cb->args[2];
99
100 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
101 if (!atd)
102 return -EMSGSIZE;
103 for (; cb->args[2] < map->elements; cb->args[2]++) {
104 id = cb->args[2];
105 if (!test_bit(id, map->members))
106 continue;
107 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
108 if (!nested) {
109 if (id == first) {
110 nla_nest_cancel(skb, atd);
111 return -EMSGSIZE;
112 } else
113 goto nla_put_failure;
114 }
115 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
116 htonl(map->first_ip + id * map->hosts)))
117 goto nla_put_failure;
118 ipset_nest_end(skb, nested);
119 }
120 ipset_nest_end(skb, atd);
121 /* Set listing finished */
122 cb->args[2] = 0;
123 return 0;
124
125nla_put_failure:
126 nla_nest_cancel(skb, nested);
127 ipset_nest_end(skb, atd);
128 if (unlikely(id == first)) {
129 cb->args[2] = 0;
130 return -EMSGSIZE;
131 }
132 return 0;
133} 77}
134 78
135/* Timeout variant */ 79static inline int
136 80bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map,
137static int 81 u32 flags)
138bitmap_ip_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
139{ 82{
140 const struct bitmap_ip *map = set->data; 83 return !!test_and_set_bit(e->id, map->members);
141 const unsigned long *members = map->members;
142 u16 id = *(u16 *)value;
143
144 return ip_set_timeout_test(members[id]);
145} 84}
146 85
147static int 86static inline int
148bitmap_ip_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) 87bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
149{ 88{
150 struct bitmap_ip *map = set->data; 89 return !test_and_clear_bit(e->id, map->members);
151 unsigned long *members = map->members;
152 u16 id = *(u16 *)value;
153
154 if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST))
155 return -IPSET_ERR_EXIST;
156
157 members[id] = ip_set_timeout_set(timeout);
158
159 return 0;
160} 90}
161 91
162static int 92static inline int
163bitmap_ip_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) 93bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id)
164{ 94{
165 struct bitmap_ip *map = set->data; 95 return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
166 unsigned long *members = map->members; 96 htonl(map->first_ip + id * map->hosts));
167 u16 id = *(u16 *)value;
168 int ret = -IPSET_ERR_EXIST;
169
170 if (ip_set_timeout_test(members[id]))
171 ret = 0;
172
173 members[id] = IPSET_ELEM_UNSET;
174 return ret;
175} 97}
176 98
177static int 99static inline int
178bitmap_ip_tlist(const struct ip_set *set, 100bitmap_ip_do_head(struct sk_buff *skb, const struct bitmap_ip *map)
179 struct sk_buff *skb, struct netlink_callback *cb)
180{ 101{
181 const struct bitmap_ip *map = set->data; 102 return nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
182 struct nlattr *adt, *nested; 103 nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
183 u32 id, first = cb->args[2]; 104 (map->netmask != 32 &&
184 const unsigned long *members = map->members; 105 nla_put_u8(skb, IPSET_ATTR_NETMASK, map->netmask));
185
186 adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
187 if (!adt)
188 return -EMSGSIZE;
189 for (; cb->args[2] < map->elements; cb->args[2]++) {
190 id = cb->args[2];
191 if (!ip_set_timeout_test(members[id]))
192 continue;
193 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
194 if (!nested) {
195 if (id == first) {
196 nla_nest_cancel(skb, adt);
197 return -EMSGSIZE;
198 } else
199 goto nla_put_failure;
200 }
201 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
202 htonl(map->first_ip + id * map->hosts)) ||
203 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
204 htonl(ip_set_timeout_get(members[id]))))
205 goto nla_put_failure;
206 ipset_nest_end(skb, nested);
207 }
208 ipset_nest_end(skb, adt);
209
210 /* Set listing finished */
211 cb->args[2] = 0;
212
213 return 0;
214
215nla_put_failure:
216 nla_nest_cancel(skb, nested);
217 ipset_nest_end(skb, adt);
218 if (unlikely(id == first)) {
219 cb->args[2] = 0;
220 return -EMSGSIZE;
221 }
222 return 0;
223} 106}
224 107
225static int 108static int
226bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb, 109bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
227 const struct xt_action_param *par, 110 const struct xt_action_param *par,
228 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 111 enum ipset_adt adt, struct ip_set_adt_opt *opt)
229{ 112{
230 struct bitmap_ip *map = set->data; 113 struct bitmap_ip *map = set->data;
231 ipset_adtfn adtfn = set->variant->adt[adt]; 114 ipset_adtfn adtfn = set->variant->adt[adt];
115 struct bitmap_ip_adt_elem e = { };
116 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
232 u32 ip; 117 u32 ip;
233 118
234 ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); 119 ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
235 if (ip < map->first_ip || ip > map->last_ip) 120 if (ip < map->first_ip || ip > map->last_ip)
236 return -IPSET_ERR_BITMAP_RANGE; 121 return -IPSET_ERR_BITMAP_RANGE;
237 122
238 ip = ip_to_id(map, ip); 123 e.id = ip_to_id(map, ip);
239 124
240 return adtfn(set, &ip, opt_timeout(opt, map), opt->cmdflags); 125 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
241} 126}
242 127
243static int 128static int
@@ -246,33 +131,31 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
246{ 131{
247 struct bitmap_ip *map = set->data; 132 struct bitmap_ip *map = set->data;
248 ipset_adtfn adtfn = set->variant->adt[adt]; 133 ipset_adtfn adtfn = set->variant->adt[adt];
249 u32 timeout = map->timeout; 134 u32 ip, ip_to;
250 u32 ip, ip_to, id; 135 struct bitmap_ip_adt_elem e = { };
136 struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
251 int ret = 0; 137 int ret = 0;
252 138
253 if (unlikely(!tb[IPSET_ATTR_IP] || 139 if (unlikely(!tb[IPSET_ATTR_IP] ||
254 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 140 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
141 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
142 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
255 return -IPSET_ERR_PROTOCOL; 143 return -IPSET_ERR_PROTOCOL;
256 144
257 if (tb[IPSET_ATTR_LINENO]) 145 if (tb[IPSET_ATTR_LINENO])
258 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 146 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
259 147
260 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 148 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
149 ip_set_get_extensions(set, tb, &ext);
261 if (ret) 150 if (ret)
262 return ret; 151 return ret;
263 152
264 if (ip < map->first_ip || ip > map->last_ip) 153 if (ip < map->first_ip || ip > map->last_ip)
265 return -IPSET_ERR_BITMAP_RANGE; 154 return -IPSET_ERR_BITMAP_RANGE;
266 155
267 if (tb[IPSET_ATTR_TIMEOUT]) {
268 if (!with_timeout(map->timeout))
269 return -IPSET_ERR_TIMEOUT;
270 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
271 }
272
273 if (adt == IPSET_TEST) { 156 if (adt == IPSET_TEST) {
274 id = ip_to_id(map, ip); 157 e.id = ip_to_id(map, ip);
275 return adtfn(set, &id, timeout, flags); 158 return adtfn(set, &e, &ext, &ext, flags);
276 } 159 }
277 160
278 if (tb[IPSET_ATTR_IP_TO]) { 161 if (tb[IPSET_ATTR_IP_TO]) {
@@ -297,8 +180,8 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
297 return -IPSET_ERR_BITMAP_RANGE; 180 return -IPSET_ERR_BITMAP_RANGE;
298 181
299 for (; !before(ip_to, ip); ip += map->hosts) { 182 for (; !before(ip_to, ip); ip += map->hosts) {
300 id = ip_to_id(map, ip); 183 e.id = ip_to_id(map, ip);
301 ret = adtfn(set, &id, timeout, flags); 184 ret = adtfn(set, &e, &ext, &ext, flags);
302 185
303 if (ret && !ip_set_eexist(ret, flags)) 186 if (ret && !ip_set_eexist(ret, flags))
304 return ret; 187 return ret;
@@ -308,54 +191,6 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
308 return ret; 191 return ret;
309} 192}
310 193
311static void
312bitmap_ip_destroy(struct ip_set *set)
313{
314 struct bitmap_ip *map = set->data;
315
316 if (with_timeout(map->timeout))
317 del_timer_sync(&map->gc);
318
319 ip_set_free(map->members);
320 kfree(map);
321
322 set->data = NULL;
323}
324
325static void
326bitmap_ip_flush(struct ip_set *set)
327{
328 struct bitmap_ip *map = set->data;
329
330 memset(map->members, 0, map->memsize);
331}
332
333static int
334bitmap_ip_head(struct ip_set *set, struct sk_buff *skb)
335{
336 const struct bitmap_ip *map = set->data;
337 struct nlattr *nested;
338
339 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
340 if (!nested)
341 goto nla_put_failure;
342 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
343 nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
344 (map->netmask != 32 &&
345 nla_put_u8(skb, IPSET_ATTR_NETMASK, map->netmask)) ||
346 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
347 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
348 htonl(sizeof(*map) + map->memsize)) ||
349 (with_timeout(map->timeout) &&
350 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
351 goto nla_put_failure;
352 ipset_nest_end(skb, nested);
353
354 return 0;
355nla_put_failure:
356 return -EMSGSIZE;
357}
358
359static bool 194static bool
360bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b) 195bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
361{ 196{
@@ -365,70 +200,35 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
365 return x->first_ip == y->first_ip && 200 return x->first_ip == y->first_ip &&
366 x->last_ip == y->last_ip && 201 x->last_ip == y->last_ip &&
367 x->netmask == y->netmask && 202 x->netmask == y->netmask &&
368 x->timeout == y->timeout; 203 x->timeout == y->timeout &&
204 a->extensions == b->extensions;
369} 205}
370 206
371static const struct ip_set_type_variant bitmap_ip = { 207/* Plain variant */
372 .kadt = bitmap_ip_kadt, 208
373 .uadt = bitmap_ip_uadt, 209struct bitmap_ip_elem {
374 .adt = {
375 [IPSET_ADD] = bitmap_ip_add,
376 [IPSET_DEL] = bitmap_ip_del,
377 [IPSET_TEST] = bitmap_ip_test,
378 },
379 .destroy = bitmap_ip_destroy,
380 .flush = bitmap_ip_flush,
381 .head = bitmap_ip_head,
382 .list = bitmap_ip_list,
383 .same_set = bitmap_ip_same_set,
384}; 210};
385 211
386static const struct ip_set_type_variant bitmap_tip = { 212/* Timeout variant */
387 .kadt = bitmap_ip_kadt, 213
388 .uadt = bitmap_ip_uadt, 214struct bitmap_ipt_elem {
389 .adt = { 215 unsigned long timeout;
390 [IPSET_ADD] = bitmap_ip_tadd,
391 [IPSET_DEL] = bitmap_ip_tdel,
392 [IPSET_TEST] = bitmap_ip_ttest,
393 },
394 .destroy = bitmap_ip_destroy,
395 .flush = bitmap_ip_flush,
396 .head = bitmap_ip_head,
397 .list = bitmap_ip_tlist,
398 .same_set = bitmap_ip_same_set,
399}; 216};
400 217
401static void 218/* Plain variant with counter */
402bitmap_ip_gc(unsigned long ul_set)
403{
404 struct ip_set *set = (struct ip_set *) ul_set;
405 struct bitmap_ip *map = set->data;
406 unsigned long *table = map->members;
407 u32 id;
408
409 /* We run parallel with other readers (test element)
410 * but adding/deleting new entries is locked out */
411 read_lock_bh(&set->lock);
412 for (id = 0; id < map->elements; id++)
413 if (ip_set_timeout_expired(table[id]))
414 table[id] = IPSET_ELEM_UNSET;
415 read_unlock_bh(&set->lock);
416
417 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
418 add_timer(&map->gc);
419}
420 219
421static void 220struct bitmap_ipc_elem {
422bitmap_ip_gc_init(struct ip_set *set) 221 struct ip_set_counter counter;
423{ 222};
424 struct bitmap_ip *map = set->data;
425 223
426 init_timer(&map->gc); 224/* Timeout variant with counter */
427 map->gc.data = (unsigned long) set; 225
428 map->gc.function = bitmap_ip_gc; 226struct bitmap_ipct_elem {
429 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 227 unsigned long timeout;
430 add_timer(&map->gc); 228 struct ip_set_counter counter;
431} 229};
230
231#include "ip_set_bitmap_gen.h"
432 232
433/* Create bitmap:ip type of sets */ 233/* Create bitmap:ip type of sets */
434 234
@@ -440,6 +240,13 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
440 map->members = ip_set_alloc(map->memsize); 240 map->members = ip_set_alloc(map->memsize);
441 if (!map->members) 241 if (!map->members)
442 return false; 242 return false;
243 if (map->dsize) {
244 map->extensions = ip_set_alloc(map->dsize * elements);
245 if (!map->extensions) {
246 kfree(map->members);
247 return false;
248 }
249 }
443 map->first_ip = first_ip; 250 map->first_ip = first_ip;
444 map->last_ip = last_ip; 251 map->last_ip = last_ip;
445 map->elements = elements; 252 map->elements = elements;
@@ -457,13 +264,14 @@ static int
457bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) 264bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
458{ 265{
459 struct bitmap_ip *map; 266 struct bitmap_ip *map;
460 u32 first_ip, last_ip, hosts; 267 u32 first_ip, last_ip, hosts, cadt_flags = 0;
461 u64 elements; 268 u64 elements;
462 u8 netmask = 32; 269 u8 netmask = 32;
463 int ret; 270 int ret;
464 271
465 if (unlikely(!tb[IPSET_ATTR_IP] || 272 if (unlikely(!tb[IPSET_ATTR_IP] ||
466 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 273 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
274 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
467 return -IPSET_ERR_PROTOCOL; 275 return -IPSET_ERR_PROTOCOL;
468 276
469 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); 277 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
@@ -526,8 +334,45 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
526 if (!map) 334 if (!map)
527 return -ENOMEM; 335 return -ENOMEM;
528 336
529 if (tb[IPSET_ATTR_TIMEOUT]) { 337 map->memsize = bitmap_bytes(0, elements - 1);
530 map->memsize = elements * sizeof(unsigned long); 338 set->variant = &bitmap_ip;
339 if (tb[IPSET_ATTR_CADT_FLAGS])
340 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
341 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
342 set->extensions |= IPSET_EXT_COUNTER;
343 if (tb[IPSET_ATTR_TIMEOUT]) {
344 map->dsize = sizeof(struct bitmap_ipct_elem);
345 map->offset[IPSET_OFFSET_TIMEOUT] =
346 offsetof(struct bitmap_ipct_elem, timeout);
347 map->offset[IPSET_OFFSET_COUNTER] =
348 offsetof(struct bitmap_ipct_elem, counter);
349
350 if (!init_map_ip(set, map, first_ip, last_ip,
351 elements, hosts, netmask)) {
352 kfree(map);
353 return -ENOMEM;
354 }
355
356 map->timeout = ip_set_timeout_uget(
357 tb[IPSET_ATTR_TIMEOUT]);
358 set->extensions |= IPSET_EXT_TIMEOUT;
359
360 bitmap_ip_gc_init(set, bitmap_ip_gc);
361 } else {
362 map->dsize = sizeof(struct bitmap_ipc_elem);
363 map->offset[IPSET_OFFSET_COUNTER] =
364 offsetof(struct bitmap_ipc_elem, counter);
365
366 if (!init_map_ip(set, map, first_ip, last_ip,
367 elements, hosts, netmask)) {
368 kfree(map);
369 return -ENOMEM;
370 }
371 }
372 } else if (tb[IPSET_ATTR_TIMEOUT]) {
373 map->dsize = sizeof(struct bitmap_ipt_elem);
374 map->offset[IPSET_OFFSET_TIMEOUT] =
375 offsetof(struct bitmap_ipt_elem, timeout);
531 376
532 if (!init_map_ip(set, map, first_ip, last_ip, 377 if (!init_map_ip(set, map, first_ip, last_ip,
533 elements, hosts, netmask)) { 378 elements, hosts, netmask)) {
@@ -536,19 +381,16 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
536 } 381 }
537 382
538 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 383 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
539 set->variant = &bitmap_tip; 384 set->extensions |= IPSET_EXT_TIMEOUT;
540 385
541 bitmap_ip_gc_init(set); 386 bitmap_ip_gc_init(set, bitmap_ip_gc);
542 } else { 387 } else {
543 map->memsize = bitmap_bytes(0, elements - 1); 388 map->dsize = 0;
544
545 if (!init_map_ip(set, map, first_ip, last_ip, 389 if (!init_map_ip(set, map, first_ip, last_ip,
546 elements, hosts, netmask)) { 390 elements, hosts, netmask)) {
547 kfree(map); 391 kfree(map);
548 return -ENOMEM; 392 return -ENOMEM;
549 } 393 }
550
551 set->variant = &bitmap_ip;
552 } 394 }
553 return 0; 395 return 0;
554} 396}
@@ -568,6 +410,7 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
568 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 410 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
569 [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, 411 [IPSET_ATTR_NETMASK] = { .type = NLA_U8 },
570 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 412 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
413 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
571 }, 414 },
572 .adt_policy = { 415 .adt_policy = {
573 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 416 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -575,6 +418,8 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
575 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 418 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
576 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 419 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
577 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 420 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
421 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
422 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
578 }, 423 },
579 .me = THIS_MODULE, 424 .me = THIS_MODULE,
580}; 425};
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c
index d7df6ac2c6f1..3b30e0bef890 100644
--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c
+++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.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
@@ -23,344 +23,208 @@
23 23
24#include <linux/netfilter/ipset/pfxlen.h> 24#include <linux/netfilter/ipset/pfxlen.h>
25#include <linux/netfilter/ipset/ip_set.h> 25#include <linux/netfilter/ipset/ip_set.h>
26#include <linux/netfilter/ipset/ip_set_timeout.h>
27#include <linux/netfilter/ipset/ip_set_bitmap.h> 26#include <linux/netfilter/ipset/ip_set_bitmap.h>
28 27
29#define REVISION_MIN 0 28#define REVISION_MIN 0
30#define REVISION_MAX 0 29#define REVISION_MAX 1 /* Counter support added */
31 30
32MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
34IP_SET_MODULE_DESC("bitmap:ip,mac", REVISION_MIN, REVISION_MAX); 33IP_SET_MODULE_DESC("bitmap:ip,mac", REVISION_MIN, REVISION_MAX);
35MODULE_ALIAS("ip_set_bitmap:ip,mac"); 34MODULE_ALIAS("ip_set_bitmap:ip,mac");
36 35
36#define MTYPE bitmap_ipmac
37#define IP_SET_BITMAP_STORED_TIMEOUT
38
37enum { 39enum {
38 MAC_EMPTY, /* element is not set */
39 MAC_FILLED, /* element is set with MAC */
40 MAC_UNSET, /* element is set, without MAC */ 40 MAC_UNSET, /* element is set, without MAC */
41 MAC_FILLED, /* element is set with MAC */
41}; 42};
42 43
43/* Type structure */ 44/* Type structure */
44struct bitmap_ipmac { 45struct bitmap_ipmac {
45 void *members; /* the set members */ 46 void *members; /* the set members */
47 void *extensions; /* MAC + data extensions */
46 u32 first_ip; /* host byte order, included in range */ 48 u32 first_ip; /* host byte order, included in range */
47 u32 last_ip; /* host byte order, included in range */ 49 u32 last_ip; /* host byte order, included in range */
50 u32 elements; /* number of max elements in the set */
48 u32 timeout; /* timeout value */ 51 u32 timeout; /* timeout value */
49 struct timer_list gc; /* garbage collector */ 52 struct timer_list gc; /* garbage collector */
53 size_t memsize; /* members size */
50 size_t dsize; /* size of element */ 54 size_t dsize; /* size of element */
55 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
51}; 56};
52 57
53/* ADT structure for generic function args */ 58/* ADT structure for generic function args */
54struct ipmac { 59struct bitmap_ipmac_adt_elem {
55 u32 id; /* id in array */ 60 u16 id;
56 unsigned char *ether; /* ethernet address */ 61 unsigned char *ether;
57}; 62};
58 63
59/* Member element without and with timeout */ 64struct bitmap_ipmac_elem {
60
61struct ipmac_elem {
62 unsigned char ether[ETH_ALEN]; 65 unsigned char ether[ETH_ALEN];
63 unsigned char match; 66 unsigned char filled;
64} __attribute__ ((aligned)); 67} __attribute__ ((aligned));
65 68
66struct ipmac_telem { 69static inline u32
67 unsigned char ether[ETH_ALEN]; 70ip_to_id(const struct bitmap_ipmac *m, u32 ip)
68 unsigned char match;
69 unsigned long timeout;
70} __attribute__ ((aligned));
71
72static inline void *
73bitmap_ipmac_elem(const struct bitmap_ipmac *map, u32 id)
74{ 71{
75 return (void *)((char *)map->members + id * map->dsize); 72 return ip - m->first_ip;
76} 73}
77 74
78static inline bool 75static inline struct bitmap_ipmac_elem *
79bitmap_timeout(const struct bitmap_ipmac *map, u32 id) 76get_elem(void *extensions, u16 id, size_t dsize)
80{ 77{
81 const struct ipmac_telem *elem = bitmap_ipmac_elem(map, id); 78 return (struct bitmap_ipmac_elem *)(extensions + id * dsize);
82
83 return ip_set_timeout_test(elem->timeout);
84} 79}
85 80
86static inline bool 81/* Common functions */
87bitmap_expired(const struct bitmap_ipmac *map, u32 id)
88{
89 const struct ipmac_telem *elem = bitmap_ipmac_elem(map, id);
90
91 return ip_set_timeout_expired(elem->timeout);
92}
93 82
94static inline int 83static inline int
95bitmap_ipmac_exist(const struct ipmac_telem *elem) 84bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
96{ 85 const struct bitmap_ipmac *map)
97 return elem->match == MAC_UNSET ||
98 (elem->match == MAC_FILLED &&
99 !ip_set_timeout_expired(elem->timeout));
100}
101
102/* Base variant */
103
104static int
105bitmap_ipmac_test(struct ip_set *set, void *value, u32 timeout, u32 flags)
106{
107 const struct bitmap_ipmac *map = set->data;
108 const struct ipmac *data = value;
109 const struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id);
110
111 switch (elem->match) {
112 case MAC_UNSET:
113 /* Trigger kernel to fill out the ethernet address */
114 return -EAGAIN;
115 case MAC_FILLED:
116 return data->ether == NULL ||
117 ether_addr_equal(data->ether, elem->ether);
118 }
119 return 0;
120}
121
122static int
123bitmap_ipmac_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
124{
125 struct bitmap_ipmac *map = set->data;
126 const struct ipmac *data = value;
127 struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id);
128
129 switch (elem->match) {
130 case MAC_UNSET:
131 if (!data->ether)
132 /* Already added without ethernet address */
133 return -IPSET_ERR_EXIST;
134 /* Fill the MAC address */
135 memcpy(elem->ether, data->ether, ETH_ALEN);
136 elem->match = MAC_FILLED;
137 break;
138 case MAC_FILLED:
139 return -IPSET_ERR_EXIST;
140 case MAC_EMPTY:
141 if (data->ether) {
142 memcpy(elem->ether, data->ether, ETH_ALEN);
143 elem->match = MAC_FILLED;
144 } else
145 elem->match = MAC_UNSET;
146 }
147
148 return 0;
149}
150
151static int
152bitmap_ipmac_del(struct ip_set *set, void *value, u32 timeout, u32 flags)
153{ 86{
154 struct bitmap_ipmac *map = set->data; 87 const struct bitmap_ipmac_elem *elem;
155 const struct ipmac *data = value;
156 struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id);
157
158 if (elem->match == MAC_EMPTY)
159 return -IPSET_ERR_EXIST;
160 88
161 elem->match = MAC_EMPTY; 89 if (!test_bit(e->id, map->members))
162 90 return 0;
163 return 0; 91 elem = get_elem(map->extensions, e->id, map->dsize);
92 if (elem->filled == MAC_FILLED)
93 return e->ether == NULL ||
94 ether_addr_equal(e->ether, elem->ether);
95 /* Trigger kernel to fill out the ethernet address */
96 return -EAGAIN;
164} 97}
165 98
166static int 99static inline int
167bitmap_ipmac_list(const struct ip_set *set, 100bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map)
168 struct sk_buff *skb, struct netlink_callback *cb)
169{ 101{
170 const struct bitmap_ipmac *map = set->data; 102 const struct bitmap_ipmac_elem *elem;
171 const struct ipmac_elem *elem;
172 struct nlattr *atd, *nested;
173 u32 id, first = cb->args[2];
174 u32 last = map->last_ip - map->first_ip;
175
176 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
177 if (!atd)
178 return -EMSGSIZE;
179 for (; cb->args[2] <= last; cb->args[2]++) {
180 id = cb->args[2];
181 elem = bitmap_ipmac_elem(map, id);
182 if (elem->match == MAC_EMPTY)
183 continue;
184 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
185 if (!nested) {
186 if (id == first) {
187 nla_nest_cancel(skb, atd);
188 return -EMSGSIZE;
189 } else
190 goto nla_put_failure;
191 }
192 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
193 htonl(map->first_ip + id)) ||
194 (elem->match == MAC_FILLED &&
195 nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN,
196 elem->ether)))
197 goto nla_put_failure;
198 ipset_nest_end(skb, nested);
199 }
200 ipset_nest_end(skb, atd);
201 /* Set listing finished */
202 cb->args[2] = 0;
203
204 return 0;
205 103
206nla_put_failure: 104 if (!test_bit(id, map->members))
207 nla_nest_cancel(skb, nested); 105 return 0;
208 ipset_nest_end(skb, atd); 106 elem = get_elem(map->extensions, id, map->dsize);
209 if (unlikely(id == first)) { 107 /* Timer not started for the incomplete elements */
210 cb->args[2] = 0; 108 return elem->filled == MAC_FILLED;
211 return -EMSGSIZE;
212 }
213 return 0;
214} 109}
215 110
216/* Timeout variant */ 111static inline int
217 112bitmap_ipmac_is_filled(const struct bitmap_ipmac_elem *elem)
218static int
219bitmap_ipmac_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
220{ 113{
221 const struct bitmap_ipmac *map = set->data; 114 return elem->filled == MAC_FILLED;
222 const struct ipmac *data = value;
223 const struct ipmac_elem *elem = bitmap_ipmac_elem(map, data->id);
224
225 switch (elem->match) {
226 case MAC_UNSET:
227 /* Trigger kernel to fill out the ethernet address */
228 return -EAGAIN;
229 case MAC_FILLED:
230 return (data->ether == NULL ||
231 ether_addr_equal(data->ether, elem->ether)) &&
232 !bitmap_expired(map, data->id);
233 }
234 return 0;
235} 115}
236 116
237static int 117static inline int
238bitmap_ipmac_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) 118bitmap_ipmac_add_timeout(unsigned long *timeout,
119 const struct bitmap_ipmac_adt_elem *e,
120 const struct ip_set_ext *ext,
121 struct bitmap_ipmac *map, int mode)
239{ 122{
240 struct bitmap_ipmac *map = set->data; 123 u32 t = ext->timeout;
241 const struct ipmac *data = value;
242 struct ipmac_telem *elem = bitmap_ipmac_elem(map, data->id);
243 bool flag_exist = flags & IPSET_FLAG_EXIST;
244 124
245 switch (elem->match) { 125 if (mode == IPSET_ADD_START_STORED_TIMEOUT) {
246 case MAC_UNSET: 126 if (t == map->timeout)
247 if (!(data->ether || flag_exist))
248 /* Already added without ethernet address */
249 return -IPSET_ERR_EXIST;
250 /* Fill the MAC address and activate the timer */
251 memcpy(elem->ether, data->ether, ETH_ALEN);
252 elem->match = MAC_FILLED;
253 if (timeout == map->timeout)
254 /* Timeout was not specified, get stored one */ 127 /* Timeout was not specified, get stored one */
255 timeout = elem->timeout; 128 t = *timeout;
256 elem->timeout = ip_set_timeout_set(timeout); 129 ip_set_timeout_set(timeout, t);
257 break; 130 } else {
258 case MAC_FILLED:
259 if (!(bitmap_expired(map, data->id) || flag_exist))
260 return -IPSET_ERR_EXIST;
261 /* Fall through */
262 case MAC_EMPTY:
263 if (data->ether) {
264 memcpy(elem->ether, data->ether, ETH_ALEN);
265 elem->match = MAC_FILLED;
266 } else
267 elem->match = MAC_UNSET;
268 /* If MAC is unset yet, we store plain timeout value 131 /* If MAC is unset yet, we store plain timeout value
269 * because the timer is not activated yet 132 * because the timer is not activated yet
270 * and we can reuse it later when MAC is filled out, 133 * and we can reuse it later when MAC is filled out,
271 * possibly by the kernel */ 134 * possibly by the kernel */
272 elem->timeout = data->ether ? ip_set_timeout_set(timeout) 135 if (e->ether)
273 : timeout; 136 ip_set_timeout_set(timeout, t);
274 break; 137 else
138 *timeout = t;
275 } 139 }
276
277 return 0; 140 return 0;
278} 141}
279 142
280static int 143static inline int
281bitmap_ipmac_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) 144bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
145 struct bitmap_ipmac *map, u32 flags)
282{ 146{
283 struct bitmap_ipmac *map = set->data; 147 struct bitmap_ipmac_elem *elem;
284 const struct ipmac *data = value; 148
285 struct ipmac_telem *elem = bitmap_ipmac_elem(map, data->id); 149 elem = get_elem(map->extensions, e->id, map->dsize);
150 if (test_and_set_bit(e->id, map->members)) {
151 if (elem->filled == MAC_FILLED) {
152 if (e->ether && (flags & IPSET_FLAG_EXIST))
153 memcpy(elem->ether, e->ether, ETH_ALEN);
154 return IPSET_ADD_FAILED;
155 } else if (!e->ether)
156 /* Already added without ethernet address */
157 return IPSET_ADD_FAILED;
158 /* Fill the MAC address and trigger the timer activation */
159 memcpy(elem->ether, e->ether, ETH_ALEN);
160 elem->filled = MAC_FILLED;
161 return IPSET_ADD_START_STORED_TIMEOUT;
162 } else if (e->ether) {
163 /* We can store MAC too */
164 memcpy(elem->ether, e->ether, ETH_ALEN);
165 elem->filled = MAC_FILLED;
166 return 0;
167 } else {
168 elem->filled = MAC_UNSET;
169 /* MAC is not stored yet, don't start timer */
170 return IPSET_ADD_STORE_PLAIN_TIMEOUT;
171 }
172}
286 173
287 if (elem->match == MAC_EMPTY || bitmap_expired(map, data->id)) 174static inline int
288 return -IPSET_ERR_EXIST; 175bitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e,
176 struct bitmap_ipmac *map)
177{
178 return !test_and_clear_bit(e->id, map->members);
179}
289 180
290 elem->match = MAC_EMPTY; 181static inline unsigned long
182ip_set_timeout_stored(struct bitmap_ipmac *map, u32 id, unsigned long *timeout)
183{
184 const struct bitmap_ipmac_elem *elem =
185 get_elem(map->extensions, id, map->dsize);
291 186
292 return 0; 187 return elem->filled == MAC_FILLED ? ip_set_timeout_get(timeout) :
188 *timeout;
293} 189}
294 190
295static int 191static inline int
296bitmap_ipmac_tlist(const struct ip_set *set, 192bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map,
297 struct sk_buff *skb, struct netlink_callback *cb) 193 u32 id)
298{ 194{
299 const struct bitmap_ipmac *map = set->data; 195 const struct bitmap_ipmac_elem *elem =
300 const struct ipmac_telem *elem; 196 get_elem(map->extensions, id, map->dsize);
301 struct nlattr *atd, *nested;
302 u32 id, first = cb->args[2];
303 u32 timeout, last = map->last_ip - map->first_ip;
304
305 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
306 if (!atd)
307 return -EMSGSIZE;
308 for (; cb->args[2] <= last; cb->args[2]++) {
309 id = cb->args[2];
310 elem = bitmap_ipmac_elem(map, id);
311 if (!bitmap_ipmac_exist(elem))
312 continue;
313 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
314 if (!nested) {
315 if (id == first) {
316 nla_nest_cancel(skb, atd);
317 return -EMSGSIZE;
318 } else
319 goto nla_put_failure;
320 }
321 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP,
322 htonl(map->first_ip + id)) ||
323 (elem->match == MAC_FILLED &&
324 nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN,
325 elem->ether)))
326 goto nla_put_failure;
327 timeout = elem->match == MAC_UNSET ? elem->timeout
328 : ip_set_timeout_get(elem->timeout);
329 if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(timeout)))
330 goto nla_put_failure;
331 ipset_nest_end(skb, nested);
332 }
333 ipset_nest_end(skb, atd);
334 /* Set listing finished */
335 cb->args[2] = 0;
336 197
337 return 0; 198 return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
199 htonl(map->first_ip + id)) ||
200 (elem->filled == MAC_FILLED &&
201 nla_put(skb, IPSET_ATTR_ETHER, ETH_ALEN, elem->ether));
202}
338 203
339nla_put_failure: 204static inline int
340 nla_nest_cancel(skb, nested); 205bitmap_ipmac_do_head(struct sk_buff *skb, const struct bitmap_ipmac *map)
341 ipset_nest_end(skb, atd); 206{
342 if (unlikely(id == first)) { 207 return nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
343 cb->args[2] = 0; 208 nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
344 return -EMSGSIZE;
345 }
346 return 0;
347} 209}
348 210
349static int 211static int
350bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, 212bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
351 const struct xt_action_param *par, 213 const struct xt_action_param *par,
352 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 214 enum ipset_adt adt, struct ip_set_adt_opt *opt)
353{ 215{
354 struct bitmap_ipmac *map = set->data; 216 struct bitmap_ipmac *map = set->data;
355 ipset_adtfn adtfn = set->variant->adt[adt]; 217 ipset_adtfn adtfn = set->variant->adt[adt];
356 struct ipmac data; 218 struct bitmap_ipmac_adt_elem e = {};
219 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
220 u32 ip;
357 221
358 /* MAC can be src only */ 222 /* MAC can be src only */
359 if (!(opt->flags & IPSET_DIM_TWO_SRC)) 223 if (!(opt->flags & IPSET_DIM_TWO_SRC))
360 return 0; 224 return 0;
361 225
362 data.id = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); 226 ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
363 if (data.id < map->first_ip || data.id > map->last_ip) 227 if (ip < map->first_ip || ip > map->last_ip)
364 return -IPSET_ERR_BITMAP_RANGE; 228 return -IPSET_ERR_BITMAP_RANGE;
365 229
366 /* Backward compatibility: we don't check the second flag */ 230 /* Backward compatibility: we don't check the second flag */
@@ -368,10 +232,10 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
368 (skb_mac_header(skb) + ETH_HLEN) > skb->data) 232 (skb_mac_header(skb) + ETH_HLEN) > skb->data)
369 return -EINVAL; 233 return -EINVAL;
370 234
371 data.id -= map->first_ip; 235 e.id = ip_to_id(map, ip);
372 data.ether = eth_hdr(skb)->h_source; 236 e.ether = eth_hdr(skb)->h_source;
373 237
374 return adtfn(set, &data, opt_timeout(opt, map), opt->cmdflags); 238 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
375} 239}
376 240
377static int 241static int
@@ -380,91 +244,39 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
380{ 244{
381 const struct bitmap_ipmac *map = set->data; 245 const struct bitmap_ipmac *map = set->data;
382 ipset_adtfn adtfn = set->variant->adt[adt]; 246 ipset_adtfn adtfn = set->variant->adt[adt];
383 struct ipmac data; 247 struct bitmap_ipmac_adt_elem e = {};
384 u32 timeout = map->timeout; 248 struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
249 u32 ip;
385 int ret = 0; 250 int ret = 0;
386 251
387 if (unlikely(!tb[IPSET_ATTR_IP] || 252 if (unlikely(!tb[IPSET_ATTR_IP] ||
388 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 253 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
254 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
255 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
389 return -IPSET_ERR_PROTOCOL; 256 return -IPSET_ERR_PROTOCOL;
390 257
391 if (tb[IPSET_ATTR_LINENO]) 258 if (tb[IPSET_ATTR_LINENO])
392 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 259 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
393 260
394 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &data.id); 261 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
262 ip_set_get_extensions(set, tb, &ext);
395 if (ret) 263 if (ret)
396 return ret; 264 return ret;
397 265
398 if (data.id < map->first_ip || data.id > map->last_ip) 266 if (ip < map->first_ip || ip > map->last_ip)
399 return -IPSET_ERR_BITMAP_RANGE; 267 return -IPSET_ERR_BITMAP_RANGE;
400 268
269 e.id = ip_to_id(map, ip);
401 if (tb[IPSET_ATTR_ETHER]) 270 if (tb[IPSET_ATTR_ETHER])
402 data.ether = nla_data(tb[IPSET_ATTR_ETHER]); 271 e.ether = nla_data(tb[IPSET_ATTR_ETHER]);
403 else 272 else
404 data.ether = NULL; 273 e.ether = NULL;
405
406 if (tb[IPSET_ATTR_TIMEOUT]) {
407 if (!with_timeout(map->timeout))
408 return -IPSET_ERR_TIMEOUT;
409 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
410 }
411
412 data.id -= map->first_ip;
413 274
414 ret = adtfn(set, &data, timeout, flags); 275 ret = adtfn(set, &e, &ext, &ext, flags);
415 276
416 return ip_set_eexist(ret, flags) ? 0 : ret; 277 return ip_set_eexist(ret, flags) ? 0 : ret;
417} 278}
418 279
419static void
420bitmap_ipmac_destroy(struct ip_set *set)
421{
422 struct bitmap_ipmac *map = set->data;
423
424 if (with_timeout(map->timeout))
425 del_timer_sync(&map->gc);
426
427 ip_set_free(map->members);
428 kfree(map);
429
430 set->data = NULL;
431}
432
433static void
434bitmap_ipmac_flush(struct ip_set *set)
435{
436 struct bitmap_ipmac *map = set->data;
437
438 memset(map->members, 0,
439 (map->last_ip - map->first_ip + 1) * map->dsize);
440}
441
442static int
443bitmap_ipmac_head(struct ip_set *set, struct sk_buff *skb)
444{
445 const struct bitmap_ipmac *map = set->data;
446 struct nlattr *nested;
447
448 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
449 if (!nested)
450 goto nla_put_failure;
451 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, htonl(map->first_ip)) ||
452 nla_put_ipaddr4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip)) ||
453 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
454 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
455 htonl(sizeof(*map) +
456 ((map->last_ip - map->first_ip + 1) *
457 map->dsize))) ||
458 (with_timeout(map->timeout) &&
459 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
460 goto nla_put_failure;
461 ipset_nest_end(skb, nested);
462
463 return 0;
464nla_put_failure:
465 return -EMSGSIZE;
466}
467
468static bool 280static bool
469bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b) 281bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
470{ 282{
@@ -473,85 +285,64 @@ bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
473 285
474 return x->first_ip == y->first_ip && 286 return x->first_ip == y->first_ip &&
475 x->last_ip == y->last_ip && 287 x->last_ip == y->last_ip &&
476 x->timeout == y->timeout; 288 x->timeout == y->timeout &&
289 a->extensions == b->extensions;
477} 290}
478 291
479static const struct ip_set_type_variant bitmap_ipmac = { 292/* Plain variant */
480 .kadt = bitmap_ipmac_kadt,
481 .uadt = bitmap_ipmac_uadt,
482 .adt = {
483 [IPSET_ADD] = bitmap_ipmac_add,
484 [IPSET_DEL] = bitmap_ipmac_del,
485 [IPSET_TEST] = bitmap_ipmac_test,
486 },
487 .destroy = bitmap_ipmac_destroy,
488 .flush = bitmap_ipmac_flush,
489 .head = bitmap_ipmac_head,
490 .list = bitmap_ipmac_list,
491 .same_set = bitmap_ipmac_same_set,
492};
493 293
494static const struct ip_set_type_variant bitmap_tipmac = { 294/* Timeout variant */
495 .kadt = bitmap_ipmac_kadt, 295
496 .uadt = bitmap_ipmac_uadt, 296struct bitmap_ipmact_elem {
497 .adt = { 297 struct {
498 [IPSET_ADD] = bitmap_ipmac_tadd, 298 unsigned char ether[ETH_ALEN];
499 [IPSET_DEL] = bitmap_ipmac_tdel, 299 unsigned char filled;
500 [IPSET_TEST] = bitmap_ipmac_ttest, 300 } __attribute__ ((aligned));
501 }, 301 unsigned long timeout;
502 .destroy = bitmap_ipmac_destroy,
503 .flush = bitmap_ipmac_flush,
504 .head = bitmap_ipmac_head,
505 .list = bitmap_ipmac_tlist,
506 .same_set = bitmap_ipmac_same_set,
507}; 302};
508 303
509static void 304/* Plain variant with counter */
510bitmap_ipmac_gc(unsigned long ul_set)
511{
512 struct ip_set *set = (struct ip_set *) ul_set;
513 struct bitmap_ipmac *map = set->data;
514 struct ipmac_telem *elem;
515 u32 id, last = map->last_ip - map->first_ip;
516
517 /* We run parallel with other readers (test element)
518 * but adding/deleting new entries is locked out */
519 read_lock_bh(&set->lock);
520 for (id = 0; id <= last; id++) {
521 elem = bitmap_ipmac_elem(map, id);
522 if (elem->match == MAC_FILLED &&
523 ip_set_timeout_expired(elem->timeout))
524 elem->match = MAC_EMPTY;
525 }
526 read_unlock_bh(&set->lock);
527 305
528 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 306struct bitmap_ipmacc_elem {
529 add_timer(&map->gc); 307 struct {
530} 308 unsigned char ether[ETH_ALEN];
309 unsigned char filled;
310 } __attribute__ ((aligned));
311 struct ip_set_counter counter;
312};
531 313
532static void 314/* Timeout variant with counter */
533bitmap_ipmac_gc_init(struct ip_set *set)
534{
535 struct bitmap_ipmac *map = set->data;
536 315
537 init_timer(&map->gc); 316struct bitmap_ipmacct_elem {
538 map->gc.data = (unsigned long) set; 317 struct {
539 map->gc.function = bitmap_ipmac_gc; 318 unsigned char ether[ETH_ALEN];
540 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 319 unsigned char filled;
541 add_timer(&map->gc); 320 } __attribute__ ((aligned));
542} 321 unsigned long timeout;
322 struct ip_set_counter counter;
323};
324
325#include "ip_set_bitmap_gen.h"
543 326
544/* Create bitmap:ip,mac type of sets */ 327/* Create bitmap:ip,mac type of sets */
545 328
546static bool 329static bool
547init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, 330init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
548 u32 first_ip, u32 last_ip) 331 u32 first_ip, u32 last_ip, u32 elements)
549{ 332{
550 map->members = ip_set_alloc((last_ip - first_ip + 1) * map->dsize); 333 map->members = ip_set_alloc((last_ip - first_ip + 1) * map->dsize);
551 if (!map->members) 334 if (!map->members)
552 return false; 335 return false;
336 if (map->dsize) {
337 map->extensions = ip_set_alloc(map->dsize * elements);
338 if (!map->extensions) {
339 kfree(map->members);
340 return false;
341 }
342 }
553 map->first_ip = first_ip; 343 map->first_ip = first_ip;
554 map->last_ip = last_ip; 344 map->last_ip = last_ip;
345 map->elements = elements;
555 map->timeout = IPSET_NO_TIMEOUT; 346 map->timeout = IPSET_NO_TIMEOUT;
556 347
557 set->data = map; 348 set->data = map;
@@ -564,13 +355,14 @@ static int
564bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], 355bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
565 u32 flags) 356 u32 flags)
566{ 357{
567 u32 first_ip, last_ip; 358 u32 first_ip, last_ip, cadt_flags = 0;
568 u64 elements; 359 u64 elements;
569 struct bitmap_ipmac *map; 360 struct bitmap_ipmac *map;
570 int ret; 361 int ret;
571 362
572 if (unlikely(!tb[IPSET_ATTR_IP] || 363 if (unlikely(!tb[IPSET_ATTR_IP] ||
573 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 364 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
365 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
574 return -IPSET_ERR_PROTOCOL; 366 return -IPSET_ERR_PROTOCOL;
575 367
576 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip); 368 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &first_ip);
@@ -605,28 +397,59 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
605 if (!map) 397 if (!map)
606 return -ENOMEM; 398 return -ENOMEM;
607 399
608 if (tb[IPSET_ATTR_TIMEOUT]) { 400 map->memsize = bitmap_bytes(0, elements - 1);
609 map->dsize = sizeof(struct ipmac_telem); 401 set->variant = &bitmap_ipmac;
402 if (tb[IPSET_ATTR_CADT_FLAGS])
403 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
404 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
405 set->extensions |= IPSET_EXT_COUNTER;
406 if (tb[IPSET_ATTR_TIMEOUT]) {
407 map->dsize = sizeof(struct bitmap_ipmacct_elem);
408 map->offset[IPSET_OFFSET_TIMEOUT] =
409 offsetof(struct bitmap_ipmacct_elem, timeout);
410 map->offset[IPSET_OFFSET_COUNTER] =
411 offsetof(struct bitmap_ipmacct_elem, counter);
412
413 if (!init_map_ipmac(set, map, first_ip, last_ip,
414 elements)) {
415 kfree(map);
416 return -ENOMEM;
417 }
418 map->timeout = ip_set_timeout_uget(
419 tb[IPSET_ATTR_TIMEOUT]);
420 set->extensions |= IPSET_EXT_TIMEOUT;
421 bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
422 } else {
423 map->dsize = sizeof(struct bitmap_ipmacc_elem);
424 map->offset[IPSET_OFFSET_COUNTER] =
425 offsetof(struct bitmap_ipmacc_elem, counter);
426
427 if (!init_map_ipmac(set, map, first_ip, last_ip,
428 elements)) {
429 kfree(map);
430 return -ENOMEM;
431 }
432 }
433 } else if (tb[IPSET_ATTR_TIMEOUT]) {
434 map->dsize = sizeof(struct bitmap_ipmact_elem);
435 map->offset[IPSET_OFFSET_TIMEOUT] =
436 offsetof(struct bitmap_ipmact_elem, timeout);
610 437
611 if (!init_map_ipmac(set, map, first_ip, last_ip)) { 438 if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
612 kfree(map); 439 kfree(map);
613 return -ENOMEM; 440 return -ENOMEM;
614 } 441 }
615
616 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 442 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
617 443 set->extensions |= IPSET_EXT_TIMEOUT;
618 set->variant = &bitmap_tipmac; 444 bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
619
620 bitmap_ipmac_gc_init(set);
621 } else { 445 } else {
622 map->dsize = sizeof(struct ipmac_elem); 446 map->dsize = sizeof(struct bitmap_ipmac_elem);
623 447
624 if (!init_map_ipmac(set, map, first_ip, last_ip)) { 448 if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
625 kfree(map); 449 kfree(map);
626 return -ENOMEM; 450 return -ENOMEM;
627 } 451 }
628 set->variant = &bitmap_ipmac; 452 set->variant = &bitmap_ipmac;
629
630 } 453 }
631 return 0; 454 return 0;
632} 455}
@@ -645,6 +468,7 @@ static struct ip_set_type bitmap_ipmac_type = {
645 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED }, 468 [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
646 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 469 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
647 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 470 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
471 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
648 }, 472 },
649 .adt_policy = { 473 .adt_policy = {
650 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 474 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -652,6 +476,8 @@ static struct ip_set_type bitmap_ipmac_type = {
652 .len = ETH_ALEN }, 476 .len = ETH_ALEN },
653 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 477 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
654 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 478 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
479 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
480 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
655 }, 481 },
656 .me = THIS_MODULE, 482 .me = THIS_MODULE,
657}; 483};
diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c
index e6b2db76f4c3..8207d1fda528 100644
--- a/net/netfilter/ipset/ip_set_bitmap_port.c
+++ b/net/netfilter/ipset/ip_set_bitmap_port.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -19,205 +19,94 @@
19#include <linux/netfilter/ipset/ip_set.h> 19#include <linux/netfilter/ipset/ip_set.h>
20#include <linux/netfilter/ipset/ip_set_bitmap.h> 20#include <linux/netfilter/ipset/ip_set_bitmap.h>
21#include <linux/netfilter/ipset/ip_set_getport.h> 21#include <linux/netfilter/ipset/ip_set_getport.h>
22#define IP_SET_BITMAP_TIMEOUT
23#include <linux/netfilter/ipset/ip_set_timeout.h>
24 22
25#define REVISION_MIN 0 23#define REVISION_MIN 0
26#define REVISION_MAX 0 24#define REVISION_MAX 1 /* Counter support added */
27 25
28MODULE_LICENSE("GPL"); 26MODULE_LICENSE("GPL");
29MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 27MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
30IP_SET_MODULE_DESC("bitmap:port", REVISION_MIN, REVISION_MAX); 28IP_SET_MODULE_DESC("bitmap:port", REVISION_MIN, REVISION_MAX);
31MODULE_ALIAS("ip_set_bitmap:port"); 29MODULE_ALIAS("ip_set_bitmap:port");
32 30
31#define MTYPE bitmap_port
32
33/* Type structure */ 33/* Type structure */
34struct bitmap_port { 34struct bitmap_port {
35 void *members; /* the set members */ 35 void *members; /* the set members */
36 void *extensions; /* data extensions */
36 u16 first_port; /* host byte order, included in range */ 37 u16 first_port; /* host byte order, included in range */
37 u16 last_port; /* host byte order, included in range */ 38 u16 last_port; /* host byte order, included in range */
39 u32 elements; /* number of max elements in the set */
38 size_t memsize; /* members size */ 40 size_t memsize; /* members size */
41 size_t dsize; /* extensions struct size */
42 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
39 u32 timeout; /* timeout parameter */ 43 u32 timeout; /* timeout parameter */
40 struct timer_list gc; /* garbage collection */ 44 struct timer_list gc; /* garbage collection */
41}; 45};
42 46
43/* Base variant */ 47/* ADT structure for generic function args */
48struct bitmap_port_adt_elem {
49 u16 id;
50};
44 51
45static int 52static inline u16
46bitmap_port_test(struct ip_set *set, void *value, u32 timeout, u32 flags) 53port_to_id(const struct bitmap_port *m, u16 port)
47{ 54{
48 const struct bitmap_port *map = set->data; 55 return port - m->first_port;
49 u16 id = *(u16 *)value;
50
51 return !!test_bit(id, map->members);
52} 56}
53 57
54static int 58/* Common functions */
55bitmap_port_add(struct ip_set *set, void *value, u32 timeout, u32 flags)
56{
57 struct bitmap_port *map = set->data;
58 u16 id = *(u16 *)value;
59
60 if (test_and_set_bit(id, map->members))
61 return -IPSET_ERR_EXIST;
62
63 return 0;
64}
65 59
66static int 60static inline int
67bitmap_port_del(struct ip_set *set, void *value, u32 timeout, u32 flags) 61bitmap_port_do_test(const struct bitmap_port_adt_elem *e,
62 const struct bitmap_port *map)
68{ 63{
69 struct bitmap_port *map = set->data; 64 return !!test_bit(e->id, map->members);
70 u16 id = *(u16 *)value;
71
72 if (!test_and_clear_bit(id, map->members))
73 return -IPSET_ERR_EXIST;
74
75 return 0;
76} 65}
77 66
78static int 67static inline int
79bitmap_port_list(const struct ip_set *set, 68bitmap_port_gc_test(u16 id, const struct bitmap_port *map)
80 struct sk_buff *skb, struct netlink_callback *cb)
81{ 69{
82 const struct bitmap_port *map = set->data; 70 return !!test_bit(id, map->members);
83 struct nlattr *atd, *nested;
84 u16 id, first = cb->args[2];
85 u16 last = map->last_port - map->first_port;
86
87 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
88 if (!atd)
89 return -EMSGSIZE;
90 for (; cb->args[2] <= last; cb->args[2]++) {
91 id = cb->args[2];
92 if (!test_bit(id, map->members))
93 continue;
94 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
95 if (!nested) {
96 if (id == first) {
97 nla_nest_cancel(skb, atd);
98 return -EMSGSIZE;
99 } else
100 goto nla_put_failure;
101 }
102 if (nla_put_net16(skb, IPSET_ATTR_PORT,
103 htons(map->first_port + id)))
104 goto nla_put_failure;
105 ipset_nest_end(skb, nested);
106 }
107 ipset_nest_end(skb, atd);
108 /* Set listing finished */
109 cb->args[2] = 0;
110
111 return 0;
112
113nla_put_failure:
114 nla_nest_cancel(skb, nested);
115 ipset_nest_end(skb, atd);
116 if (unlikely(id == first)) {
117 cb->args[2] = 0;
118 return -EMSGSIZE;
119 }
120 return 0;
121} 71}
122 72
123/* Timeout variant */ 73static inline int
124 74bitmap_port_do_add(const struct bitmap_port_adt_elem *e,
125static int 75 struct bitmap_port *map, u32 flags)
126bitmap_port_ttest(struct ip_set *set, void *value, u32 timeout, u32 flags)
127{ 76{
128 const struct bitmap_port *map = set->data; 77 return !!test_and_set_bit(e->id, map->members);
129 const unsigned long *members = map->members;
130 u16 id = *(u16 *)value;
131
132 return ip_set_timeout_test(members[id]);
133} 78}
134 79
135static int 80static inline int
136bitmap_port_tadd(struct ip_set *set, void *value, u32 timeout, u32 flags) 81bitmap_port_do_del(const struct bitmap_port_adt_elem *e,
82 struct bitmap_port *map)
137{ 83{
138 struct bitmap_port *map = set->data; 84 return !test_and_clear_bit(e->id, map->members);
139 unsigned long *members = map->members;
140 u16 id = *(u16 *)value;
141
142 if (ip_set_timeout_test(members[id]) && !(flags & IPSET_FLAG_EXIST))
143 return -IPSET_ERR_EXIST;
144
145 members[id] = ip_set_timeout_set(timeout);
146
147 return 0;
148} 85}
149 86
150static int 87static inline int
151bitmap_port_tdel(struct ip_set *set, void *value, u32 timeout, u32 flags) 88bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id)
152{ 89{
153 struct bitmap_port *map = set->data; 90 return nla_put_net16(skb, IPSET_ATTR_PORT,
154 unsigned long *members = map->members; 91 htons(map->first_port + id));
155 u16 id = *(u16 *)value;
156 int ret = -IPSET_ERR_EXIST;
157
158 if (ip_set_timeout_test(members[id]))
159 ret = 0;
160
161 members[id] = IPSET_ELEM_UNSET;
162 return ret;
163} 92}
164 93
165static int 94static inline int
166bitmap_port_tlist(const struct ip_set *set, 95bitmap_port_do_head(struct sk_buff *skb, const struct bitmap_port *map)
167 struct sk_buff *skb, struct netlink_callback *cb)
168{ 96{
169 const struct bitmap_port *map = set->data; 97 return nla_put_net16(skb, IPSET_ATTR_PORT, htons(map->first_port)) ||
170 struct nlattr *adt, *nested; 98 nla_put_net16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
171 u16 id, first = cb->args[2];
172 u16 last = map->last_port - map->first_port;
173 const unsigned long *members = map->members;
174
175 adt = ipset_nest_start(skb, IPSET_ATTR_ADT);
176 if (!adt)
177 return -EMSGSIZE;
178 for (; cb->args[2] <= last; cb->args[2]++) {
179 id = cb->args[2];
180 if (!ip_set_timeout_test(members[id]))
181 continue;
182 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
183 if (!nested) {
184 if (id == first) {
185 nla_nest_cancel(skb, adt);
186 return -EMSGSIZE;
187 } else
188 goto nla_put_failure;
189 }
190 if (nla_put_net16(skb, IPSET_ATTR_PORT,
191 htons(map->first_port + id)) ||
192 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
193 htonl(ip_set_timeout_get(members[id]))))
194 goto nla_put_failure;
195 ipset_nest_end(skb, nested);
196 }
197 ipset_nest_end(skb, adt);
198
199 /* Set listing finished */
200 cb->args[2] = 0;
201
202 return 0;
203
204nla_put_failure:
205 nla_nest_cancel(skb, nested);
206 ipset_nest_end(skb, adt);
207 if (unlikely(id == first)) {
208 cb->args[2] = 0;
209 return -EMSGSIZE;
210 }
211 return 0;
212} 99}
213 100
214static int 101static int
215bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb, 102bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
216 const struct xt_action_param *par, 103 const struct xt_action_param *par,
217 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 104 enum ipset_adt adt, struct ip_set_adt_opt *opt)
218{ 105{
219 struct bitmap_port *map = set->data; 106 struct bitmap_port *map = set->data;
220 ipset_adtfn adtfn = set->variant->adt[adt]; 107 ipset_adtfn adtfn = set->variant->adt[adt];
108 struct bitmap_port_adt_elem e = {};
109 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
221 __be16 __port; 110 __be16 __port;
222 u16 port = 0; 111 u16 port = 0;
223 112
@@ -230,9 +119,9 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
230 if (port < map->first_port || port > map->last_port) 119 if (port < map->first_port || port > map->last_port)
231 return -IPSET_ERR_BITMAP_RANGE; 120 return -IPSET_ERR_BITMAP_RANGE;
232 121
233 port -= map->first_port; 122 e.id = port_to_id(map, port);
234 123
235 return adtfn(set, &port, opt_timeout(opt, map), opt->cmdflags); 124 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
236} 125}
237 126
238static int 127static int
@@ -241,14 +130,17 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
241{ 130{
242 struct bitmap_port *map = set->data; 131 struct bitmap_port *map = set->data;
243 ipset_adtfn adtfn = set->variant->adt[adt]; 132 ipset_adtfn adtfn = set->variant->adt[adt];
244 u32 timeout = map->timeout; 133 struct bitmap_port_adt_elem e = {};
134 struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
245 u32 port; /* wraparound */ 135 u32 port; /* wraparound */
246 u16 id, port_to; 136 u16 port_to;
247 int ret = 0; 137 int ret = 0;
248 138
249 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 139 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
250 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 140 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
251 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 141 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
142 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
143 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
252 return -IPSET_ERR_PROTOCOL; 144 return -IPSET_ERR_PROTOCOL;
253 145
254 if (tb[IPSET_ATTR_LINENO]) 146 if (tb[IPSET_ATTR_LINENO])
@@ -257,16 +149,13 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
257 port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); 149 port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
258 if (port < map->first_port || port > map->last_port) 150 if (port < map->first_port || port > map->last_port)
259 return -IPSET_ERR_BITMAP_RANGE; 151 return -IPSET_ERR_BITMAP_RANGE;
260 152 ret = ip_set_get_extensions(set, tb, &ext);
261 if (tb[IPSET_ATTR_TIMEOUT]) { 153 if (ret)
262 if (!with_timeout(map->timeout)) 154 return ret;
263 return -IPSET_ERR_TIMEOUT;
264 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
265 }
266 155
267 if (adt == IPSET_TEST) { 156 if (adt == IPSET_TEST) {
268 id = port - map->first_port; 157 e.id = port_to_id(map, port);
269 return adtfn(set, &id, timeout, flags); 158 return adtfn(set, &e, &ext, &ext, flags);
270 } 159 }
271 160
272 if (tb[IPSET_ATTR_PORT_TO]) { 161 if (tb[IPSET_ATTR_PORT_TO]) {
@@ -283,8 +172,8 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
283 return -IPSET_ERR_BITMAP_RANGE; 172 return -IPSET_ERR_BITMAP_RANGE;
284 173
285 for (; port <= port_to; port++) { 174 for (; port <= port_to; port++) {
286 id = port - map->first_port; 175 e.id = port_to_id(map, port);
287 ret = adtfn(set, &id, timeout, flags); 176 ret = adtfn(set, &e, &ext, &ext, flags);
288 177
289 if (ret && !ip_set_eexist(ret, flags)) 178 if (ret && !ip_set_eexist(ret, flags))
290 return ret; 179 return ret;
@@ -294,52 +183,6 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
294 return ret; 183 return ret;
295} 184}
296 185
297static void
298bitmap_port_destroy(struct ip_set *set)
299{
300 struct bitmap_port *map = set->data;
301
302 if (with_timeout(map->timeout))
303 del_timer_sync(&map->gc);
304
305 ip_set_free(map->members);
306 kfree(map);
307
308 set->data = NULL;
309}
310
311static void
312bitmap_port_flush(struct ip_set *set)
313{
314 struct bitmap_port *map = set->data;
315
316 memset(map->members, 0, map->memsize);
317}
318
319static int
320bitmap_port_head(struct ip_set *set, struct sk_buff *skb)
321{
322 const struct bitmap_port *map = set->data;
323 struct nlattr *nested;
324
325 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
326 if (!nested)
327 goto nla_put_failure;
328 if (nla_put_net16(skb, IPSET_ATTR_PORT, htons(map->first_port)) ||
329 nla_put_net16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port)) ||
330 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
331 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
332 htonl(sizeof(*map) + map->memsize)) ||
333 (with_timeout(map->timeout) &&
334 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))))
335 goto nla_put_failure;
336 ipset_nest_end(skb, nested);
337
338 return 0;
339nla_put_failure:
340 return -EMSGSIZE;
341}
342
343static bool 186static bool
344bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b) 187bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
345{ 188{
@@ -348,71 +191,35 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
348 191
349 return x->first_port == y->first_port && 192 return x->first_port == y->first_port &&
350 x->last_port == y->last_port && 193 x->last_port == y->last_port &&
351 x->timeout == y->timeout; 194 x->timeout == y->timeout &&
195 a->extensions == b->extensions;
352} 196}
353 197
354static const struct ip_set_type_variant bitmap_port = { 198/* Plain variant */
355 .kadt = bitmap_port_kadt, 199
356 .uadt = bitmap_port_uadt, 200struct bitmap_port_elem {
357 .adt = {
358 [IPSET_ADD] = bitmap_port_add,
359 [IPSET_DEL] = bitmap_port_del,
360 [IPSET_TEST] = bitmap_port_test,
361 },
362 .destroy = bitmap_port_destroy,
363 .flush = bitmap_port_flush,
364 .head = bitmap_port_head,
365 .list = bitmap_port_list,
366 .same_set = bitmap_port_same_set,
367}; 201};
368 202
369static const struct ip_set_type_variant bitmap_tport = { 203/* Timeout variant */
370 .kadt = bitmap_port_kadt, 204
371 .uadt = bitmap_port_uadt, 205struct bitmap_portt_elem {
372 .adt = { 206 unsigned long timeout;
373 [IPSET_ADD] = bitmap_port_tadd,
374 [IPSET_DEL] = bitmap_port_tdel,
375 [IPSET_TEST] = bitmap_port_ttest,
376 },
377 .destroy = bitmap_port_destroy,
378 .flush = bitmap_port_flush,
379 .head = bitmap_port_head,
380 .list = bitmap_port_tlist,
381 .same_set = bitmap_port_same_set,
382}; 207};
383 208
384static void 209/* Plain variant with counter */
385bitmap_port_gc(unsigned long ul_set)
386{
387 struct ip_set *set = (struct ip_set *) ul_set;
388 struct bitmap_port *map = set->data;
389 unsigned long *table = map->members;
390 u32 id; /* wraparound */
391 u16 last = map->last_port - map->first_port;
392
393 /* We run parallel with other readers (test element)
394 * but adding/deleting new entries is locked out */
395 read_lock_bh(&set->lock);
396 for (id = 0; id <= last; id++)
397 if (ip_set_timeout_expired(table[id]))
398 table[id] = IPSET_ELEM_UNSET;
399 read_unlock_bh(&set->lock);
400
401 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
402 add_timer(&map->gc);
403}
404 210
405static void 211struct bitmap_portc_elem {
406bitmap_port_gc_init(struct ip_set *set) 212 struct ip_set_counter counter;
407{ 213};
408 struct bitmap_port *map = set->data;
409 214
410 init_timer(&map->gc); 215/* Timeout variant with counter */
411 map->gc.data = (unsigned long) set; 216
412 map->gc.function = bitmap_port_gc; 217struct bitmap_portct_elem {
413 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 218 unsigned long timeout;
414 add_timer(&map->gc); 219 struct ip_set_counter counter;
415} 220};
221
222#include "ip_set_bitmap_gen.h"
416 223
417/* Create bitmap:ip type of sets */ 224/* Create bitmap:ip type of sets */
418 225
@@ -423,6 +230,13 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
423 map->members = ip_set_alloc(map->memsize); 230 map->members = ip_set_alloc(map->memsize);
424 if (!map->members) 231 if (!map->members)
425 return false; 232 return false;
233 if (map->dsize) {
234 map->extensions = ip_set_alloc(map->dsize * map->elements);
235 if (!map->extensions) {
236 kfree(map->members);
237 return false;
238 }
239 }
426 map->first_port = first_port; 240 map->first_port = first_port;
427 map->last_port = last_port; 241 map->last_port = last_port;
428 map->timeout = IPSET_NO_TIMEOUT; 242 map->timeout = IPSET_NO_TIMEOUT;
@@ -434,15 +248,16 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
434} 248}
435 249
436static int 250static int
437bitmap_port_create(struct ip_set *set, struct nlattr *tb[], 251bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
438 u32 flags)
439{ 252{
440 struct bitmap_port *map; 253 struct bitmap_port *map;
441 u16 first_port, last_port; 254 u16 first_port, last_port;
255 u32 cadt_flags = 0;
442 256
443 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 257 if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
444 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || 258 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
445 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 259 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
260 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
446 return -IPSET_ERR_PROTOCOL; 261 return -IPSET_ERR_PROTOCOL;
447 262
448 first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]); 263 first_port = ip_set_get_h16(tb[IPSET_ATTR_PORT]);
@@ -458,28 +273,56 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[],
458 if (!map) 273 if (!map)
459 return -ENOMEM; 274 return -ENOMEM;
460 275
461 if (tb[IPSET_ATTR_TIMEOUT]) { 276 map->elements = last_port - first_port + 1;
462 map->memsize = (last_port - first_port + 1) 277 map->memsize = map->elements * sizeof(unsigned long);
463 * sizeof(unsigned long); 278 set->variant = &bitmap_port;
464 279 if (tb[IPSET_ATTR_CADT_FLAGS])
280 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
281 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
282 set->extensions |= IPSET_EXT_COUNTER;
283 if (tb[IPSET_ATTR_TIMEOUT]) {
284 map->dsize = sizeof(struct bitmap_portct_elem);
285 map->offset[IPSET_OFFSET_TIMEOUT] =
286 offsetof(struct bitmap_portct_elem, timeout);
287 map->offset[IPSET_OFFSET_COUNTER] =
288 offsetof(struct bitmap_portct_elem, counter);
289 if (!init_map_port(set, map, first_port, last_port)) {
290 kfree(map);
291 return -ENOMEM;
292 }
293
294 map->timeout =
295 ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
296 set->extensions |= IPSET_EXT_TIMEOUT;
297 bitmap_port_gc_init(set, bitmap_port_gc);
298 } else {
299 map->dsize = sizeof(struct bitmap_portc_elem);
300 map->offset[IPSET_OFFSET_COUNTER] =
301 offsetof(struct bitmap_portc_elem, counter);
302 if (!init_map_port(set, map, first_port, last_port)) {
303 kfree(map);
304 return -ENOMEM;
305 }
306 }
307 } else if (tb[IPSET_ATTR_TIMEOUT]) {
308 map->dsize = sizeof(struct bitmap_portt_elem);
309 map->offset[IPSET_OFFSET_TIMEOUT] =
310 offsetof(struct bitmap_portt_elem, timeout);
465 if (!init_map_port(set, map, first_port, last_port)) { 311 if (!init_map_port(set, map, first_port, last_port)) {
466 kfree(map); 312 kfree(map);
467 return -ENOMEM; 313 return -ENOMEM;
468 } 314 }
469 315
470 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); 316 map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
471 set->variant = &bitmap_tport; 317 set->extensions |= IPSET_EXT_TIMEOUT;
472 318 bitmap_port_gc_init(set, bitmap_port_gc);
473 bitmap_port_gc_init(set);
474 } else { 319 } else {
475 map->memsize = bitmap_bytes(0, last_port - first_port); 320 map->dsize = 0;
476 pr_debug("memsize: %zu\n", map->memsize);
477 if (!init_map_port(set, map, first_port, last_port)) { 321 if (!init_map_port(set, map, first_port, last_port)) {
478 kfree(map); 322 kfree(map);
479 return -ENOMEM; 323 return -ENOMEM;
480 } 324 }
481 325
482 set->variant = &bitmap_port;
483 } 326 }
484 return 0; 327 return 0;
485} 328}
@@ -497,12 +340,15 @@ static struct ip_set_type bitmap_port_type = {
497 [IPSET_ATTR_PORT] = { .type = NLA_U16 }, 340 [IPSET_ATTR_PORT] = { .type = NLA_U16 },
498 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, 341 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
499 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 342 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
343 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
500 }, 344 },
501 .adt_policy = { 345 .adt_policy = {
502 [IPSET_ATTR_PORT] = { .type = NLA_U16 }, 346 [IPSET_ATTR_PORT] = { .type = NLA_U16 },
503 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 }, 347 [IPSET_ATTR_PORT_TO] = { .type = NLA_U16 },
504 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 348 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
505 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 349 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
350 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
351 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
506 }, 352 },
507 .me = THIS_MODULE, 353 .me = THIS_MODULE,
508}; 354};
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 86f5e26f39d3..f77139007983 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,29 @@ 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 if (tb[IPSET_ATTR_BYTES] || tb[IPSET_ATTR_PACKETS]) {
328 if (!(set->extensions & IPSET_EXT_COUNTER))
329 return -IPSET_ERR_COUNTER;
330 if (tb[IPSET_ATTR_BYTES])
331 ext->bytes = be64_to_cpu(nla_get_be64(
332 tb[IPSET_ATTR_BYTES]));
333 if (tb[IPSET_ATTR_PACKETS])
334 ext->packets = be64_to_cpu(nla_get_be64(
335 tb[IPSET_ATTR_PACKETS]));
336 }
337 return 0;
338}
339EXPORT_SYMBOL_GPL(ip_set_get_extensions);
340
318/* 341/*
319 * Creating/destroying/renaming/swapping affect the existence and 342 * Creating/destroying/renaming/swapping affect the existence and
320 * the properties of a set. All of these can be executed from userspace 343 * the properties of a set. All of these can be executed from userspace
@@ -365,8 +388,7 @@ ip_set_rcu_get(ip_set_id_t index)
365 388
366int 389int
367ip_set_test(ip_set_id_t index, const struct sk_buff *skb, 390ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
368 const struct xt_action_param *par, 391 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
369 const struct ip_set_adt_opt *opt)
370{ 392{
371 struct ip_set *set = ip_set_rcu_get(index); 393 struct ip_set *set = ip_set_rcu_get(index);
372 int ret = 0; 394 int ret = 0;
@@ -391,7 +413,7 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
391 ret = 1; 413 ret = 1;
392 } else { 414 } else {
393 /* --return-nomatch: invert matched element */ 415 /* --return-nomatch: invert matched element */
394 if ((opt->flags & IPSET_RETURN_NOMATCH) && 416 if ((opt->cmdflags & IPSET_FLAG_RETURN_NOMATCH) &&
395 (set->type->features & IPSET_TYPE_NOMATCH) && 417 (set->type->features & IPSET_TYPE_NOMATCH) &&
396 (ret > 0 || ret == -ENOTEMPTY)) 418 (ret > 0 || ret == -ENOTEMPTY))
397 ret = -ret; 419 ret = -ret;
@@ -404,8 +426,7 @@ EXPORT_SYMBOL_GPL(ip_set_test);
404 426
405int 427int
406ip_set_add(ip_set_id_t index, const struct sk_buff *skb, 428ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
407 const struct xt_action_param *par, 429 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
408 const struct ip_set_adt_opt *opt)
409{ 430{
410 struct ip_set *set = ip_set_rcu_get(index); 431 struct ip_set *set = ip_set_rcu_get(index);
411 int ret; 432 int ret;
@@ -427,8 +448,7 @@ EXPORT_SYMBOL_GPL(ip_set_add);
427 448
428int 449int
429ip_set_del(ip_set_id_t index, const struct sk_buff *skb, 450ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
430 const struct xt_action_param *par, 451 const struct xt_action_param *par, struct ip_set_adt_opt *opt)
431 const struct ip_set_adt_opt *opt)
432{ 452{
433 struct ip_set *set = ip_set_rcu_get(index); 453 struct ip_set *set = ip_set_rcu_get(index);
434 int ret = 0; 454 int ret = 0;
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
new file mode 100644
index 000000000000..57beb1762b2d
--- /dev/null
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -0,0 +1,1100 @@
1/* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
7
8#ifndef _IP_SET_HASH_GEN_H
9#define _IP_SET_HASH_GEN_H
10
11#include <linux/rcupdate.h>
12#include <linux/jhash.h>
13#include <linux/netfilter/ipset/ip_set_timeout.h>
14#ifndef rcu_dereference_bh
15#define rcu_dereference_bh(p) rcu_dereference(p)
16#endif
17
18#define CONCAT(a, b) a##b
19#define TOKEN(a, b) CONCAT(a, b)
20
21/* Hashing which uses arrays to resolve clashing. The hash table is resized
22 * (doubled) when searching becomes too long.
23 * Internally jhash is used with the assumption that the size of the
24 * stored data is a multiple of sizeof(u32). If storage supports timeout,
25 * the timeout field must be the last one in the data structure - that field
26 * is ignored when computing the hash key.
27 *
28 * Readers and resizing
29 *
30 * Resizing can be triggered by userspace command only, and those
31 * are serialized by the nfnl mutex. During resizing the set is
32 * read-locked, so the only possible concurrent operations are
33 * the kernel side readers. Those must be protected by proper RCU locking.
34 */
35
36/* Number of elements to store in an initial array block */
37#define AHASH_INIT_SIZE 4
38/* Max number of elements to store in an array block */
39#define AHASH_MAX_SIZE (3*AHASH_INIT_SIZE)
40
41/* Max number of elements can be tuned */
42#ifdef IP_SET_HASH_WITH_MULTI
43#define AHASH_MAX(h) ((h)->ahash_max)
44
45static inline u8
46tune_ahash_max(u8 curr, u32 multi)
47{
48 u32 n;
49
50 if (multi < curr)
51 return curr;
52
53 n = curr + AHASH_INIT_SIZE;
54 /* Currently, at listing one hash bucket must fit into a message.
55 * Therefore we have a hard limit here.
56 */
57 return n > curr && n <= 64 ? n : curr;
58}
59#define TUNE_AHASH_MAX(h, multi) \
60 ((h)->ahash_max = tune_ahash_max((h)->ahash_max, multi))
61#else
62#define AHASH_MAX(h) AHASH_MAX_SIZE
63#define TUNE_AHASH_MAX(h, multi)
64#endif
65
66/* A hash bucket */
67struct hbucket {
68 void *value; /* the array of the values */
69 u8 size; /* size of the array */
70 u8 pos; /* position of the first free entry */
71};
72
73/* The hash table: the table size stored here in order to make resizing easy */
74struct htable {
75 u8 htable_bits; /* size of hash table == 2^htable_bits */
76 struct hbucket bucket[0]; /* hashtable buckets */
77};
78
79#define hbucket(h, i) (&((h)->bucket[i]))
80
81/* Book-keeping of the prefixes added to the set */
82struct net_prefixes {
83 u8 cidr; /* the different cidr values in the set */
84 u32 nets; /* number of elements per cidr */
85};
86
87/* Compute the hash table size */
88static size_t
89htable_size(u8 hbits)
90{
91 size_t hsize;
92
93 /* We must fit both into u32 in jhash and size_t */
94 if (hbits > 31)
95 return 0;
96 hsize = jhash_size(hbits);
97 if ((((size_t)-1) - sizeof(struct htable))/sizeof(struct hbucket)
98 < hsize)
99 return 0;
100
101 return hsize * sizeof(struct hbucket) + sizeof(struct htable);
102}
103
104/* Compute htable_bits from the user input parameter hashsize */
105static u8
106htable_bits(u32 hashsize)
107{
108 /* Assume that hashsize == 2^htable_bits */
109 u8 bits = fls(hashsize - 1);
110 if (jhash_size(bits) != hashsize)
111 /* Round up to the first 2^n value */
112 bits = fls(hashsize);
113
114 return bits;
115}
116
117/* Destroy the hashtable part of the set */
118static void
119ahash_destroy(struct htable *t)
120{
121 struct hbucket *n;
122 u32 i;
123
124 for (i = 0; i < jhash_size(t->htable_bits); i++) {
125 n = hbucket(t, i);
126 if (n->size)
127 /* FIXME: use slab cache */
128 kfree(n->value);
129 }
130
131 ip_set_free(t);
132}
133
134static int
135hbucket_elem_add(struct hbucket *n, u8 ahash_max, size_t dsize)
136{
137 if (n->pos >= n->size) {
138 void *tmp;
139
140 if (n->size >= ahash_max)
141 /* Trigger rehashing */
142 return -EAGAIN;
143
144 tmp = kzalloc((n->size + AHASH_INIT_SIZE) * dsize,
145 GFP_ATOMIC);
146 if (!tmp)
147 return -ENOMEM;
148 if (n->size) {
149 memcpy(tmp, n->value, n->size * dsize);
150 kfree(n->value);
151 }
152 n->value = tmp;
153 n->size += AHASH_INIT_SIZE;
154 }
155 return 0;
156}
157
158#ifdef IP_SET_HASH_WITH_NETS
159#ifdef IP_SET_HASH_WITH_NETS_PACKED
160/* When cidr is packed with nomatch, cidr - 1 is stored in the entry */
161#define CIDR(cidr) (cidr + 1)
162#else
163#define CIDR(cidr) (cidr)
164#endif
165
166#define SET_HOST_MASK(family) (family == AF_INET ? 32 : 128)
167
168#ifdef IP_SET_HASH_WITH_MULTI
169#define NETS_LENGTH(family) (SET_HOST_MASK(family) + 1)
170#else
171#define NETS_LENGTH(family) SET_HOST_MASK(family)
172#endif
173
174#else
175#define NETS_LENGTH(family) 0
176#endif /* IP_SET_HASH_WITH_NETS */
177
178#define ext_timeout(e, h) \
179(unsigned long *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_TIMEOUT])
180#define ext_counter(e, h) \
181(struct ip_set_counter *)(((void *)(e)) + (h)->offset[IPSET_OFFSET_COUNTER])
182
183#endif /* _IP_SET_HASH_GEN_H */
184
185/* Family dependent templates */
186
187#undef ahash_data
188#undef mtype_data_equal
189#undef mtype_do_data_match
190#undef mtype_data_set_flags
191#undef mtype_data_reset_flags
192#undef mtype_data_netmask
193#undef mtype_data_list
194#undef mtype_data_next
195#undef mtype_elem
196
197#undef mtype_add_cidr
198#undef mtype_del_cidr
199#undef mtype_ahash_memsize
200#undef mtype_flush
201#undef mtype_destroy
202#undef mtype_gc_init
203#undef mtype_same_set
204#undef mtype_kadt
205#undef mtype_uadt
206#undef mtype
207
208#undef mtype_add
209#undef mtype_del
210#undef mtype_test_cidrs
211#undef mtype_test
212#undef mtype_expire
213#undef mtype_resize
214#undef mtype_head
215#undef mtype_list
216#undef mtype_gc
217#undef mtype_gc_init
218#undef mtype_variant
219#undef mtype_data_match
220
221#undef HKEY
222
223#define mtype_data_equal TOKEN(MTYPE, _data_equal)
224#ifdef IP_SET_HASH_WITH_NETS
225#define mtype_do_data_match TOKEN(MTYPE, _do_data_match)
226#else
227#define mtype_do_data_match(d) 1
228#endif
229#define mtype_data_set_flags TOKEN(MTYPE, _data_set_flags)
230#define mtype_data_reset_flags TOKEN(MTYPE, _data_reset_flags)
231#define mtype_data_netmask TOKEN(MTYPE, _data_netmask)
232#define mtype_data_list TOKEN(MTYPE, _data_list)
233#define mtype_data_next TOKEN(MTYPE, _data_next)
234#define mtype_elem TOKEN(MTYPE, _elem)
235#define mtype_add_cidr TOKEN(MTYPE, _add_cidr)
236#define mtype_del_cidr TOKEN(MTYPE, _del_cidr)
237#define mtype_ahash_memsize TOKEN(MTYPE, _ahash_memsize)
238#define mtype_flush TOKEN(MTYPE, _flush)
239#define mtype_destroy TOKEN(MTYPE, _destroy)
240#define mtype_gc_init TOKEN(MTYPE, _gc_init)
241#define mtype_same_set TOKEN(MTYPE, _same_set)
242#define mtype_kadt TOKEN(MTYPE, _kadt)
243#define mtype_uadt TOKEN(MTYPE, _uadt)
244#define mtype MTYPE
245
246#define mtype_elem TOKEN(MTYPE, _elem)
247#define mtype_add TOKEN(MTYPE, _add)
248#define mtype_del TOKEN(MTYPE, _del)
249#define mtype_test_cidrs TOKEN(MTYPE, _test_cidrs)
250#define mtype_test TOKEN(MTYPE, _test)
251#define mtype_expire TOKEN(MTYPE, _expire)
252#define mtype_resize TOKEN(MTYPE, _resize)
253#define mtype_head TOKEN(MTYPE, _head)
254#define mtype_list TOKEN(MTYPE, _list)
255#define mtype_gc TOKEN(MTYPE, _gc)
256#define mtype_variant TOKEN(MTYPE, _variant)
257#define mtype_data_match TOKEN(MTYPE, _data_match)
258
259#ifndef HKEY_DATALEN
260#define HKEY_DATALEN sizeof(struct mtype_elem)
261#endif
262
263#define HKEY(data, initval, htable_bits) \
264(jhash2((u32 *)(data), HKEY_DATALEN/sizeof(u32), initval) \
265 & jhash_mask(htable_bits))
266
267#ifndef htype
268#define htype HTYPE
269
270/* The generic hash structure */
271struct htype {
272 struct htable *table; /* the hash table */
273 u32 maxelem; /* max elements in the hash */
274 u32 elements; /* current element (vs timeout) */
275 u32 initval; /* random jhash init value */
276 u32 timeout; /* timeout value, if enabled */
277 size_t dsize; /* data struct size */
278 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
279 struct timer_list gc; /* garbage collection when timeout enabled */
280 struct mtype_elem next; /* temporary storage for uadd */
281#ifdef IP_SET_HASH_WITH_MULTI
282 u8 ahash_max; /* max elements in an array block */
283#endif
284#ifdef IP_SET_HASH_WITH_NETMASK
285 u8 netmask; /* netmask value for subnets to store */
286#endif
287#ifdef IP_SET_HASH_WITH_RBTREE
288 struct rb_root rbtree;
289#endif
290#ifdef IP_SET_HASH_WITH_NETS
291 struct net_prefixes nets[0]; /* book-keeping of prefixes */
292#endif
293};
294#endif
295
296#ifdef IP_SET_HASH_WITH_NETS
297/* Network cidr size book keeping when the hash stores different
298 * sized networks */
299static void
300mtype_add_cidr(struct htype *h, u8 cidr, u8 nets_length)
301{
302 int i, j;
303
304 /* Add in increasing prefix order, so larger cidr first */
305 for (i = 0, j = -1; i < nets_length && h->nets[i].nets; i++) {
306 if (j != -1)
307 continue;
308 else if (h->nets[i].cidr < cidr)
309 j = i;
310 else if (h->nets[i].cidr == cidr) {
311 h->nets[i].nets++;
312 return;
313 }
314 }
315 if (j != -1) {
316 for (; i > j; i--) {
317 h->nets[i].cidr = h->nets[i - 1].cidr;
318 h->nets[i].nets = h->nets[i - 1].nets;
319 }
320 }
321 h->nets[i].cidr = cidr;
322 h->nets[i].nets = 1;
323}
324
325static void
326mtype_del_cidr(struct htype *h, u8 cidr, u8 nets_length)
327{
328 u8 i, j;
329
330 for (i = 0; i < nets_length - 1 && h->nets[i].cidr != cidr; i++)
331 ;
332 h->nets[i].nets--;
333
334 if (h->nets[i].nets != 0)
335 return;
336
337 for (j = i; j < nets_length - 1 && h->nets[j].nets; j++) {
338 h->nets[j].cidr = h->nets[j + 1].cidr;
339 h->nets[j].nets = h->nets[j + 1].nets;
340 }
341}
342#endif
343
344/* Calculate the actual memory size of the set data */
345static size_t
346mtype_ahash_memsize(const struct htype *h, u8 nets_length)
347{
348 u32 i;
349 struct htable *t = h->table;
350 size_t memsize = sizeof(*h)
351 + sizeof(*t)
352#ifdef IP_SET_HASH_WITH_NETS
353 + sizeof(struct net_prefixes) * nets_length
354#endif
355 + jhash_size(t->htable_bits) * sizeof(struct hbucket);
356
357 for (i = 0; i < jhash_size(t->htable_bits); i++)
358 memsize += t->bucket[i].size * h->dsize;
359
360 return memsize;
361}
362
363/* Flush a hash type of set: destroy all elements */
364static void
365mtype_flush(struct ip_set *set)
366{
367 struct htype *h = set->data;
368 struct htable *t = h->table;
369 struct hbucket *n;
370 u32 i;
371
372 for (i = 0; i < jhash_size(t->htable_bits); i++) {
373 n = hbucket(t, i);
374 if (n->size) {
375 n->size = n->pos = 0;
376 /* FIXME: use slab cache */
377 kfree(n->value);
378 }
379 }
380#ifdef IP_SET_HASH_WITH_NETS
381 memset(h->nets, 0, sizeof(struct net_prefixes)
382 * NETS_LENGTH(set->family));
383#endif
384 h->elements = 0;
385}
386
387/* Destroy a hash type of set */
388static void
389mtype_destroy(struct ip_set *set)
390{
391 struct htype *h = set->data;
392
393 if (set->extensions & IPSET_EXT_TIMEOUT)
394 del_timer_sync(&h->gc);
395
396 ahash_destroy(h->table);
397#ifdef IP_SET_HASH_WITH_RBTREE
398 rbtree_destroy(&h->rbtree);
399#endif
400 kfree(h);
401
402 set->data = NULL;
403}
404
405static void
406mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
407{
408 struct htype *h = set->data;
409
410 init_timer(&h->gc);
411 h->gc.data = (unsigned long) set;
412 h->gc.function = gc;
413 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
414 add_timer(&h->gc);
415 pr_debug("gc initialized, run in every %u\n",
416 IPSET_GC_PERIOD(h->timeout));
417}
418
419static bool
420mtype_same_set(const struct ip_set *a, const struct ip_set *b)
421{
422 const struct htype *x = a->data;
423 const struct htype *y = b->data;
424
425 /* Resizing changes htable_bits, so we ignore it */
426 return x->maxelem == y->maxelem &&
427 x->timeout == y->timeout &&
428#ifdef IP_SET_HASH_WITH_NETMASK
429 x->netmask == y->netmask &&
430#endif
431 a->extensions == b->extensions;
432}
433
434/* Get the ith element from the array block n */
435#define ahash_data(n, i, dsize) \
436 ((struct mtype_elem *)((n)->value + ((i) * (dsize))))
437
438/* Delete expired elements from the hashtable */
439static void
440mtype_expire(struct htype *h, u8 nets_length, size_t dsize)
441{
442 struct htable *t = h->table;
443 struct hbucket *n;
444 struct mtype_elem *data;
445 u32 i;
446 int j;
447
448 for (i = 0; i < jhash_size(t->htable_bits); i++) {
449 n = hbucket(t, i);
450 for (j = 0; j < n->pos; j++) {
451 data = ahash_data(n, j, dsize);
452 if (ip_set_timeout_expired(ext_timeout(data, h))) {
453 pr_debug("expired %u/%u\n", i, j);
454#ifdef IP_SET_HASH_WITH_NETS
455 mtype_del_cidr(h, CIDR(data->cidr),
456 nets_length);
457#endif
458 if (j != n->pos - 1)
459 /* Not last one */
460 memcpy(data,
461 ahash_data(n, n->pos - 1, dsize),
462 dsize);
463 n->pos--;
464 h->elements--;
465 }
466 }
467 if (n->pos + AHASH_INIT_SIZE < n->size) {
468 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
469 * dsize,
470 GFP_ATOMIC);
471 if (!tmp)
472 /* Still try to delete expired elements */
473 continue;
474 n->size -= AHASH_INIT_SIZE;
475 memcpy(tmp, n->value, n->size * dsize);
476 kfree(n->value);
477 n->value = tmp;
478 }
479 }
480}
481
482static void
483mtype_gc(unsigned long ul_set)
484{
485 struct ip_set *set = (struct ip_set *) ul_set;
486 struct htype *h = set->data;
487
488 pr_debug("called\n");
489 write_lock_bh(&set->lock);
490 mtype_expire(h, NETS_LENGTH(set->family), h->dsize);
491 write_unlock_bh(&set->lock);
492
493 h->gc.expires = jiffies + IPSET_GC_PERIOD(h->timeout) * HZ;
494 add_timer(&h->gc);
495}
496
497/* Resize a hash: create a new hash table with doubling the hashsize
498 * and inserting the elements to it. Repeat until we succeed or
499 * fail due to memory pressures. */
500static int
501mtype_resize(struct ip_set *set, bool retried)
502{
503 struct htype *h = set->data;
504 struct htable *t, *orig = h->table;
505 u8 htable_bits = orig->htable_bits;
506#ifdef IP_SET_HASH_WITH_NETS
507 u8 flags;
508#endif
509 struct mtype_elem *data;
510 struct mtype_elem *d;
511 struct hbucket *n, *m;
512 u32 i, j;
513 int ret;
514
515 /* Try to cleanup once */
516 if (SET_WITH_TIMEOUT(set) && !retried) {
517 i = h->elements;
518 write_lock_bh(&set->lock);
519 mtype_expire(set->data, NETS_LENGTH(set->family),
520 h->dsize);
521 write_unlock_bh(&set->lock);
522 if (h->elements < i)
523 return 0;
524 }
525
526retry:
527 ret = 0;
528 htable_bits++;
529 pr_debug("attempt to resize set %s from %u to %u, t %p\n",
530 set->name, orig->htable_bits, htable_bits, orig);
531 if (!htable_bits) {
532 /* In case we have plenty of memory :-) */
533 pr_warning("Cannot increase the hashsize of set %s further\n",
534 set->name);
535 return -IPSET_ERR_HASH_FULL;
536 }
537 t = ip_set_alloc(sizeof(*t)
538 + jhash_size(htable_bits) * sizeof(struct hbucket));
539 if (!t)
540 return -ENOMEM;
541 t->htable_bits = htable_bits;
542
543 read_lock_bh(&set->lock);
544 for (i = 0; i < jhash_size(orig->htable_bits); i++) {
545 n = hbucket(orig, i);
546 for (j = 0; j < n->pos; j++) {
547 data = ahash_data(n, j, h->dsize);
548#ifdef IP_SET_HASH_WITH_NETS
549 flags = 0;
550 mtype_data_reset_flags(data, &flags);
551#endif
552 m = hbucket(t, HKEY(data, h->initval, htable_bits));
553 ret = hbucket_elem_add(m, AHASH_MAX(h), h->dsize);
554 if (ret < 0) {
555#ifdef IP_SET_HASH_WITH_NETS
556 mtype_data_reset_flags(data, &flags);
557#endif
558 read_unlock_bh(&set->lock);
559 ahash_destroy(t);
560 if (ret == -EAGAIN)
561 goto retry;
562 return ret;
563 }
564 d = ahash_data(m, m->pos++, h->dsize);
565 memcpy(d, data, h->dsize);
566#ifdef IP_SET_HASH_WITH_NETS
567 mtype_data_reset_flags(d, &flags);
568#endif
569 }
570 }
571
572 rcu_assign_pointer(h->table, t);
573 read_unlock_bh(&set->lock);
574
575 /* Give time to other readers of the set */
576 synchronize_rcu_bh();
577
578 pr_debug("set %s resized from %u (%p) to %u (%p)\n", set->name,
579 orig->htable_bits, orig, t->htable_bits, t);
580 ahash_destroy(orig);
581
582 return 0;
583}
584
585/* Add an element to a hash and update the internal counters when succeeded,
586 * otherwise report the proper error code. */
587static int
588mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
589 struct ip_set_ext *mext, u32 flags)
590{
591 struct htype *h = set->data;
592 struct htable *t;
593 const struct mtype_elem *d = value;
594 struct mtype_elem *data;
595 struct hbucket *n;
596 int i, ret = 0;
597 int j = AHASH_MAX(h) + 1;
598 bool flag_exist = flags & IPSET_FLAG_EXIST;
599 u32 key, multi = 0;
600
601 if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
602 /* FIXME: when set is full, we slow down here */
603 mtype_expire(h, NETS_LENGTH(set->family), h->dsize);
604
605 if (h->elements >= h->maxelem) {
606 if (net_ratelimit())
607 pr_warning("Set %s is full, maxelem %u reached\n",
608 set->name, h->maxelem);
609 return -IPSET_ERR_HASH_FULL;
610 }
611
612 rcu_read_lock_bh();
613 t = rcu_dereference_bh(h->table);
614 key = HKEY(value, h->initval, t->htable_bits);
615 n = hbucket(t, key);
616 for (i = 0; i < n->pos; i++) {
617 data = ahash_data(n, i, h->dsize);
618 if (mtype_data_equal(data, d, &multi)) {
619 if (flag_exist ||
620 (SET_WITH_TIMEOUT(set) &&
621 ip_set_timeout_expired(ext_timeout(data, h)))) {
622 /* Just the extensions could be overwritten */
623 j = i;
624 goto reuse_slot;
625 } else {
626 ret = -IPSET_ERR_EXIST;
627 goto out;
628 }
629 }
630 /* Reuse first timed out entry */
631 if (SET_WITH_TIMEOUT(set) &&
632 ip_set_timeout_expired(ext_timeout(data, h)) &&
633 j != AHASH_MAX(h) + 1)
634 j = i;
635 }
636reuse_slot:
637 if (j != AHASH_MAX(h) + 1) {
638 /* Fill out reused slot */
639 data = ahash_data(n, j, h->dsize);
640#ifdef IP_SET_HASH_WITH_NETS
641 mtype_del_cidr(h, CIDR(data->cidr), NETS_LENGTH(set->family));
642 mtype_add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
643#endif
644 } else {
645 /* Use/create a new slot */
646 TUNE_AHASH_MAX(h, multi);
647 ret = hbucket_elem_add(n, AHASH_MAX(h), h->dsize);
648 if (ret != 0) {
649 if (ret == -EAGAIN)
650 mtype_data_next(&h->next, d);
651 goto out;
652 }
653 data = ahash_data(n, n->pos++, h->dsize);
654#ifdef IP_SET_HASH_WITH_NETS
655 mtype_add_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
656#endif
657 h->elements++;
658 }
659 memcpy(data, d, sizeof(struct mtype_elem));
660#ifdef IP_SET_HASH_WITH_NETS
661 mtype_data_set_flags(data, flags);
662#endif
663 if (SET_WITH_TIMEOUT(set))
664 ip_set_timeout_set(ext_timeout(data, h), ext->timeout);
665 if (SET_WITH_COUNTER(set))
666 ip_set_init_counter(ext_counter(data, h), ext);
667
668out:
669 rcu_read_unlock_bh();
670 return ret;
671}
672
673/* Delete an element from the hash: swap it with the last element
674 * and free up space if possible.
675 */
676static int
677mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
678 struct ip_set_ext *mext, u32 flags)
679{
680 struct htype *h = set->data;
681 struct htable *t = h->table;
682 const struct mtype_elem *d = value;
683 struct mtype_elem *data;
684 struct hbucket *n;
685 int i;
686 u32 key, multi = 0;
687
688 key = HKEY(value, h->initval, t->htable_bits);
689 n = hbucket(t, key);
690 for (i = 0; i < n->pos; i++) {
691 data = ahash_data(n, i, h->dsize);
692 if (!mtype_data_equal(data, d, &multi))
693 continue;
694 if (SET_WITH_TIMEOUT(set) &&
695 ip_set_timeout_expired(ext_timeout(data, h)))
696 return -IPSET_ERR_EXIST;
697 if (i != n->pos - 1)
698 /* Not last one */
699 memcpy(data, ahash_data(n, n->pos - 1, h->dsize),
700 h->dsize);
701
702 n->pos--;
703 h->elements--;
704#ifdef IP_SET_HASH_WITH_NETS
705 mtype_del_cidr(h, CIDR(d->cidr), NETS_LENGTH(set->family));
706#endif
707 if (n->pos + AHASH_INIT_SIZE < n->size) {
708 void *tmp = kzalloc((n->size - AHASH_INIT_SIZE)
709 * h->dsize,
710 GFP_ATOMIC);
711 if (!tmp)
712 return 0;
713 n->size -= AHASH_INIT_SIZE;
714 memcpy(tmp, n->value, n->size * h->dsize);
715 kfree(n->value);
716 n->value = tmp;
717 }
718 return 0;
719 }
720
721 return -IPSET_ERR_EXIST;
722}
723
724static inline int
725mtype_data_match(struct mtype_elem *data, const struct ip_set_ext *ext,
726 struct ip_set_ext *mext, struct ip_set *set, u32 flags)
727{
728 if (SET_WITH_COUNTER(set))
729 ip_set_update_counter(ext_counter(data,
730 (struct htype *)(set->data)),
731 ext, mext, flags);
732 return mtype_do_data_match(data);
733}
734
735#ifdef IP_SET_HASH_WITH_NETS
736/* Special test function which takes into account the different network
737 * sizes added to the set */
738static int
739mtype_test_cidrs(struct ip_set *set, struct mtype_elem *d,
740 const struct ip_set_ext *ext,
741 struct ip_set_ext *mext, u32 flags)
742{
743 struct htype *h = set->data;
744 struct htable *t = h->table;
745 struct hbucket *n;
746 struct mtype_elem *data;
747 int i, j = 0;
748 u32 key, multi = 0;
749 u8 nets_length = NETS_LENGTH(set->family);
750
751 pr_debug("test by nets\n");
752 for (; j < nets_length && h->nets[j].nets && !multi; j++) {
753 mtype_data_netmask(d, h->nets[j].cidr);
754 key = HKEY(d, h->initval, t->htable_bits);
755 n = hbucket(t, key);
756 for (i = 0; i < n->pos; i++) {
757 data = ahash_data(n, i, h->dsize);
758 if (!mtype_data_equal(data, d, &multi))
759 continue;
760 if (SET_WITH_TIMEOUT(set)) {
761 if (!ip_set_timeout_expired(
762 ext_timeout(data, h)))
763 return mtype_data_match(data, ext,
764 mext, set,
765 flags);
766#ifdef IP_SET_HASH_WITH_MULTI
767 multi = 0;
768#endif
769 } else
770 return mtype_data_match(data, ext,
771 mext, set, flags);
772 }
773 }
774 return 0;
775}
776#endif
777
778/* Test whether the element is added to the set */
779static int
780mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
781 struct ip_set_ext *mext, u32 flags)
782{
783 struct htype *h = set->data;
784 struct htable *t = h->table;
785 struct mtype_elem *d = value;
786 struct hbucket *n;
787 struct mtype_elem *data;
788 int i;
789 u32 key, multi = 0;
790
791#ifdef IP_SET_HASH_WITH_NETS
792 /* If we test an IP address and not a network address,
793 * try all possible network sizes */
794 if (CIDR(d->cidr) == SET_HOST_MASK(set->family))
795 return mtype_test_cidrs(set, d, ext, mext, flags);
796#endif
797
798 key = HKEY(d, h->initval, t->htable_bits);
799 n = hbucket(t, key);
800 for (i = 0; i < n->pos; i++) {
801 data = ahash_data(n, i, h->dsize);
802 if (mtype_data_equal(data, d, &multi) &&
803 !(SET_WITH_TIMEOUT(set) &&
804 ip_set_timeout_expired(ext_timeout(data, h))))
805 return mtype_data_match(data, ext, mext, set, flags);
806 }
807 return 0;
808}
809
810/* Reply a HEADER request: fill out the header part of the set */
811static int
812mtype_head(struct ip_set *set, struct sk_buff *skb)
813{
814 const struct htype *h = set->data;
815 struct nlattr *nested;
816 size_t memsize;
817
818 read_lock_bh(&set->lock);
819 memsize = mtype_ahash_memsize(h, NETS_LENGTH(set->family));
820 read_unlock_bh(&set->lock);
821
822 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
823 if (!nested)
824 goto nla_put_failure;
825 if (nla_put_net32(skb, IPSET_ATTR_HASHSIZE,
826 htonl(jhash_size(h->table->htable_bits))) ||
827 nla_put_net32(skb, IPSET_ATTR_MAXELEM, htonl(h->maxelem)))
828 goto nla_put_failure;
829#ifdef IP_SET_HASH_WITH_NETMASK
830 if (h->netmask != HOST_MASK &&
831 nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask))
832 goto nla_put_failure;
833#endif
834 if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
835 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)) ||
836 ((set->extensions & IPSET_EXT_TIMEOUT) &&
837 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout))) ||
838 ((set->extensions & IPSET_EXT_COUNTER) &&
839 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
840 htonl(IPSET_FLAG_WITH_COUNTERS))))
841 goto nla_put_failure;
842 ipset_nest_end(skb, nested);
843
844 return 0;
845nla_put_failure:
846 return -EMSGSIZE;
847}
848
849/* Reply a LIST/SAVE request: dump the elements of the specified set */
850static int
851mtype_list(const struct ip_set *set,
852 struct sk_buff *skb, struct netlink_callback *cb)
853{
854 const struct htype *h = set->data;
855 const struct htable *t = h->table;
856 struct nlattr *atd, *nested;
857 const struct hbucket *n;
858 const struct mtype_elem *e;
859 u32 first = cb->args[2];
860 /* We assume that one hash bucket fills into one page */
861 void *incomplete;
862 int i;
863
864 atd = ipset_nest_start(skb, IPSET_ATTR_ADT);
865 if (!atd)
866 return -EMSGSIZE;
867 pr_debug("list hash set %s\n", set->name);
868 for (; cb->args[2] < jhash_size(t->htable_bits); cb->args[2]++) {
869 incomplete = skb_tail_pointer(skb);
870 n = hbucket(t, cb->args[2]);
871 pr_debug("cb->args[2]: %lu, t %p n %p\n", cb->args[2], t, n);
872 for (i = 0; i < n->pos; i++) {
873 e = ahash_data(n, i, h->dsize);
874 if (SET_WITH_TIMEOUT(set) &&
875 ip_set_timeout_expired(ext_timeout(e, h)))
876 continue;
877 pr_debug("list hash %lu hbucket %p i %u, data %p\n",
878 cb->args[2], n, i, e);
879 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
880 if (!nested) {
881 if (cb->args[2] == first) {
882 nla_nest_cancel(skb, atd);
883 return -EMSGSIZE;
884 } else
885 goto nla_put_failure;
886 }
887 if (mtype_data_list(skb, e))
888 goto nla_put_failure;
889 if (SET_WITH_TIMEOUT(set) &&
890 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
891 htonl(ip_set_timeout_get(
892 ext_timeout(e, h)))))
893 goto nla_put_failure;
894 if (SET_WITH_COUNTER(set) &&
895 ip_set_put_counter(skb, ext_counter(e, h)))
896 goto nla_put_failure;
897 ipset_nest_end(skb, nested);
898 }
899 }
900 ipset_nest_end(skb, atd);
901 /* Set listing finished */
902 cb->args[2] = 0;
903
904 return 0;
905
906nla_put_failure:
907 nlmsg_trim(skb, incomplete);
908 ipset_nest_end(skb, atd);
909 if (unlikely(first == cb->args[2])) {
910 pr_warning("Can't list set %s: one bucket does not fit into "
911 "a message. Please report it!\n", set->name);
912 cb->args[2] = 0;
913 return -EMSGSIZE;
914 }
915 return 0;
916}
917
918static int
919TOKEN(MTYPE, _kadt)(struct ip_set *set, const struct sk_buff *skb,
920 const struct xt_action_param *par,
921 enum ipset_adt adt, struct ip_set_adt_opt *opt);
922
923static int
924TOKEN(MTYPE, _uadt)(struct ip_set *set, struct nlattr *tb[],
925 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried);
926
927static const struct ip_set_type_variant mtype_variant = {
928 .kadt = mtype_kadt,
929 .uadt = mtype_uadt,
930 .adt = {
931 [IPSET_ADD] = mtype_add,
932 [IPSET_DEL] = mtype_del,
933 [IPSET_TEST] = mtype_test,
934 },
935 .destroy = mtype_destroy,
936 .flush = mtype_flush,
937 .head = mtype_head,
938 .list = mtype_list,
939 .resize = mtype_resize,
940 .same_set = mtype_same_set,
941};
942
943#ifdef IP_SET_EMIT_CREATE
944static int
945TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
946{
947 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
948 u32 cadt_flags = 0;
949 u8 hbits;
950#ifdef IP_SET_HASH_WITH_NETMASK
951 u8 netmask;
952#endif
953 size_t hsize;
954 struct HTYPE *h;
955
956 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
957 return -IPSET_ERR_INVALID_FAMILY;
958#ifdef IP_SET_HASH_WITH_NETMASK
959 netmask = set->family == NFPROTO_IPV4 ? 32 : 128;
960 pr_debug("Create set %s with family %s\n",
961 set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6");
962#endif
963
964 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
965 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
966 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
967 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
968 return -IPSET_ERR_PROTOCOL;
969
970 if (tb[IPSET_ATTR_HASHSIZE]) {
971 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
972 if (hashsize < IPSET_MIMINAL_HASHSIZE)
973 hashsize = IPSET_MIMINAL_HASHSIZE;
974 }
975
976 if (tb[IPSET_ATTR_MAXELEM])
977 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
978
979#ifdef IP_SET_HASH_WITH_NETMASK
980 if (tb[IPSET_ATTR_NETMASK]) {
981 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
982
983 if ((set->family == NFPROTO_IPV4 && netmask > 32) ||
984 (set->family == NFPROTO_IPV6 && netmask > 128) ||
985 netmask == 0)
986 return -IPSET_ERR_INVALID_NETMASK;
987 }
988#endif
989
990 hsize = sizeof(*h);
991#ifdef IP_SET_HASH_WITH_NETS
992 hsize += sizeof(struct net_prefixes) *
993 (set->family == NFPROTO_IPV4 ? 32 : 128);
994#endif
995 h = kzalloc(hsize, GFP_KERNEL);
996 if (!h)
997 return -ENOMEM;
998
999 h->maxelem = maxelem;
1000#ifdef IP_SET_HASH_WITH_NETMASK
1001 h->netmask = netmask;
1002#endif
1003 get_random_bytes(&h->initval, sizeof(h->initval));
1004 h->timeout = IPSET_NO_TIMEOUT;
1005
1006 hbits = htable_bits(hashsize);
1007 hsize = htable_size(hbits);
1008 if (hsize == 0) {
1009 kfree(h);
1010 return -ENOMEM;
1011 }
1012 h->table = ip_set_alloc(hsize);
1013 if (!h->table) {
1014 kfree(h);
1015 return -ENOMEM;
1016 }
1017 h->table->htable_bits = hbits;
1018
1019 set->data = h;
1020 if (set->family == NFPROTO_IPV4)
1021 set->variant = &TOKEN(HTYPE, 4_variant);
1022 else
1023 set->variant = &TOKEN(HTYPE, 6_variant);
1024
1025 if (tb[IPSET_ATTR_CADT_FLAGS])
1026 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
1027 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
1028 set->extensions |= IPSET_EXT_COUNTER;
1029 if (tb[IPSET_ATTR_TIMEOUT]) {
1030 h->timeout =
1031 ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1032 set->extensions |= IPSET_EXT_TIMEOUT;
1033 if (set->family == NFPROTO_IPV4) {
1034 h->dsize =
1035 sizeof(struct TOKEN(HTYPE, 4ct_elem));
1036 h->offset[IPSET_OFFSET_TIMEOUT] =
1037 offsetof(struct TOKEN(HTYPE, 4ct_elem),
1038 timeout);
1039 h->offset[IPSET_OFFSET_COUNTER] =
1040 offsetof(struct TOKEN(HTYPE, 4ct_elem),
1041 counter);
1042 TOKEN(HTYPE, 4_gc_init)(set,
1043 TOKEN(HTYPE, 4_gc));
1044 } else {
1045 h->dsize =
1046 sizeof(struct TOKEN(HTYPE, 6ct_elem));
1047 h->offset[IPSET_OFFSET_TIMEOUT] =
1048 offsetof(struct TOKEN(HTYPE, 6ct_elem),
1049 timeout);
1050 h->offset[IPSET_OFFSET_COUNTER] =
1051 offsetof(struct TOKEN(HTYPE, 6ct_elem),
1052 counter);
1053 TOKEN(HTYPE, 6_gc_init)(set,
1054 TOKEN(HTYPE, 6_gc));
1055 }
1056 } else {
1057 if (set->family == NFPROTO_IPV4) {
1058 h->dsize =
1059 sizeof(struct TOKEN(HTYPE, 4c_elem));
1060 h->offset[IPSET_OFFSET_COUNTER] =
1061 offsetof(struct TOKEN(HTYPE, 4c_elem),
1062 counter);
1063 } else {
1064 h->dsize =
1065 sizeof(struct TOKEN(HTYPE, 6c_elem));
1066 h->offset[IPSET_OFFSET_COUNTER] =
1067 offsetof(struct TOKEN(HTYPE, 6c_elem),
1068 counter);
1069 }
1070 }
1071 } else if (tb[IPSET_ATTR_TIMEOUT]) {
1072 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
1073 set->extensions |= IPSET_EXT_TIMEOUT;
1074 if (set->family == NFPROTO_IPV4) {
1075 h->dsize = sizeof(struct TOKEN(HTYPE, 4t_elem));
1076 h->offset[IPSET_OFFSET_TIMEOUT] =
1077 offsetof(struct TOKEN(HTYPE, 4t_elem),
1078 timeout);
1079 TOKEN(HTYPE, 4_gc_init)(set, TOKEN(HTYPE, 4_gc));
1080 } else {
1081 h->dsize = sizeof(struct TOKEN(HTYPE, 6t_elem));
1082 h->offset[IPSET_OFFSET_TIMEOUT] =
1083 offsetof(struct TOKEN(HTYPE, 6t_elem),
1084 timeout);
1085 TOKEN(HTYPE, 6_gc_init)(set, TOKEN(HTYPE, 6_gc));
1086 }
1087 } else {
1088 if (set->family == NFPROTO_IPV4)
1089 h->dsize = sizeof(struct TOKEN(HTYPE, 4_elem));
1090 else
1091 h->dsize = sizeof(struct TOKEN(HTYPE, 6_elem));
1092 }
1093
1094 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
1095 set->name, jhash_size(h->table->htable_bits),
1096 h->table->htable_bits, h->maxelem, set->data, h->table);
1097
1098 return 0;
1099}
1100#endif /* IP_SET_EMIT_CREATE */
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index b7d4cb475ae6..c74e6e14cd93 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -21,11 +21,10 @@
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h> 22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_timeout.h>
25#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
26 25
27#define REVISION_MIN 0 26#define REVISION_MIN 0
28#define REVISION_MAX 0 27#define REVISION_MAX 1 /* Counters support */
29 28
30MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 30MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -33,58 +32,47 @@ IP_SET_MODULE_DESC("hash:ip", REVISION_MIN, REVISION_MAX);
33MODULE_ALIAS("ip_set_hash:ip"); 32MODULE_ALIAS("ip_set_hash:ip");
34 33
35/* Type specific function prefix */ 34/* Type specific function prefix */
36#define TYPE hash_ip 35#define HTYPE hash_ip
37 36#define IP_SET_HASH_WITH_NETMASK
38static bool
39hash_ip_same_set(const struct ip_set *a, const struct ip_set *b);
40
41#define hash_ip4_same_set hash_ip_same_set
42#define hash_ip6_same_set hash_ip_same_set
43 37
44/* The type variant functions: IPv4 */ 38/* IPv4 variants */
45 39
46/* Member elements without timeout */ 40/* Member elements */
47struct hash_ip4_elem { 41struct hash_ip4_elem {
42 /* Zero valued IP addresses cannot be stored */
48 __be32 ip; 43 __be32 ip;
49}; 44};
50 45
51/* Member elements with timeout support */ 46struct hash_ip4t_elem {
52struct hash_ip4_telem {
53 __be32 ip; 47 __be32 ip;
54 unsigned long timeout; 48 unsigned long timeout;
55}; 49};
56 50
57static inline bool 51struct hash_ip4c_elem {
58hash_ip4_data_equal(const struct hash_ip4_elem *ip1, 52 __be32 ip;
59 const struct hash_ip4_elem *ip2, 53 struct ip_set_counter counter;
60 u32 *multi) 54};
61{
62 return ip1->ip == ip2->ip;
63}
64 55
65static inline bool 56struct hash_ip4ct_elem {
66hash_ip4_data_isnull(const struct hash_ip4_elem *elem) 57 __be32 ip;
67{ 58 struct ip_set_counter counter;
68 return elem->ip == 0; 59 unsigned long timeout;
69} 60};
70 61
71static inline void 62/* Common functions */
72hash_ip4_data_copy(struct hash_ip4_elem *dst, const struct hash_ip4_elem *src)
73{
74 dst->ip = src->ip;
75}
76 63
77/* Zero valued IP addresses cannot be stored */ 64static inline bool
78static inline void 65hash_ip4_data_equal(const struct hash_ip4_elem *e1,
79hash_ip4_data_zero_out(struct hash_ip4_elem *elem) 66 const struct hash_ip4_elem *e2,
67 u32 *multi)
80{ 68{
81 elem->ip = 0; 69 return e1->ip == e2->ip;
82} 70}
83 71
84static inline bool 72static inline bool
85hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *data) 73hash_ip4_data_list(struct sk_buff *skb, const struct hash_ip4_elem *e)
86{ 74{
87 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip)) 75 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, e->ip))
88 goto nla_put_failure; 76 goto nla_put_failure;
89 return 0; 77 return 0;
90 78
@@ -92,41 +80,26 @@ nla_put_failure:
92 return 1; 80 return 1;
93} 81}
94 82
95static bool 83static inline void
96hash_ip4_data_tlist(struct sk_buff *skb, const struct hash_ip4_elem *data) 84hash_ip4_data_next(struct hash_ip4_elem *next, const struct hash_ip4_elem *e)
97{ 85{
98 const struct hash_ip4_telem *tdata = 86 next->ip = e->ip;
99 (const struct hash_ip4_telem *)data;
100
101 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
102 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
103 htonl(ip_set_timeout_get(tdata->timeout))))
104 goto nla_put_failure;
105
106 return 0;
107
108nla_put_failure:
109 return 1;
110} 87}
111 88
112#define IP_SET_HASH_WITH_NETMASK 89#define MTYPE hash_ip4
113#define PF 4 90#define PF 4
114#define HOST_MASK 32 91#define HOST_MASK 32
115#include <linux/netfilter/ipset/ip_set_ahash.h> 92#include "ip_set_hash_gen.h"
116
117static inline void
118hash_ip4_data_next(struct ip_set_hash *h, const struct hash_ip4_elem *d)
119{
120 h->next.ip = d->ip;
121}
122 93
123static int 94static int
124hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb, 95hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
125 const struct xt_action_param *par, 96 const struct xt_action_param *par,
126 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 97 enum ipset_adt adt, struct ip_set_adt_opt *opt)
127{ 98{
128 const struct ip_set_hash *h = set->data; 99 const struct hash_ip *h = set->data;
129 ipset_adtfn adtfn = set->variant->adt[adt]; 100 ipset_adtfn adtfn = set->variant->adt[adt];
101 struct hash_ip4_elem e = {};
102 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
130 __be32 ip; 103 __be32 ip;
131 104
132 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip); 105 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip);
@@ -134,43 +107,42 @@ hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
134 if (ip == 0) 107 if (ip == 0)
135 return -EINVAL; 108 return -EINVAL;
136 109
137 return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags); 110 e.ip = ip;
111 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
138} 112}
139 113
140static int 114static int
141hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], 115hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
142 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 116 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
143{ 117{
144 const struct ip_set_hash *h = set->data; 118 const struct hash_ip *h = set->data;
145 ipset_adtfn adtfn = set->variant->adt[adt]; 119 ipset_adtfn adtfn = set->variant->adt[adt];
146 u32 ip, ip_to, hosts, timeout = h->timeout; 120 struct hash_ip4_elem e = {};
147 __be32 nip; 121 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
122 u32 ip, ip_to, hosts;
148 int ret = 0; 123 int ret = 0;
149 124
150 if (unlikely(!tb[IPSET_ATTR_IP] || 125 if (unlikely(!tb[IPSET_ATTR_IP] ||
151 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 126 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
127 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
128 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
152 return -IPSET_ERR_PROTOCOL; 129 return -IPSET_ERR_PROTOCOL;
153 130
154 if (tb[IPSET_ATTR_LINENO]) 131 if (tb[IPSET_ATTR_LINENO])
155 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 132 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
156 133
157 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 134 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
135 ip_set_get_extensions(set, tb, &ext);
158 if (ret) 136 if (ret)
159 return ret; 137 return ret;
160 138
161 ip &= ip_set_hostmask(h->netmask); 139 ip &= ip_set_hostmask(h->netmask);
162 140
163 if (tb[IPSET_ATTR_TIMEOUT]) {
164 if (!with_timeout(h->timeout))
165 return -IPSET_ERR_TIMEOUT;
166 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
167 }
168
169 if (adt == IPSET_TEST) { 141 if (adt == IPSET_TEST) {
170 nip = htonl(ip); 142 e.ip = htonl(ip);
171 if (nip == 0) 143 if (e.ip == 0)
172 return -IPSET_ERR_HASH_ELEM; 144 return -IPSET_ERR_HASH_ELEM;
173 return adtfn(set, &nip, timeout, flags); 145 return adtfn(set, &e, &ext, &ext, flags);
174 } 146 }
175 147
176 ip_to = ip; 148 ip_to = ip;
@@ -193,10 +165,10 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
193 if (retried) 165 if (retried)
194 ip = ntohl(h->next.ip); 166 ip = ntohl(h->next.ip);
195 for (; !before(ip_to, ip); ip += hosts) { 167 for (; !before(ip_to, ip); ip += hosts) {
196 nip = htonl(ip); 168 e.ip = htonl(ip);
197 if (nip == 0) 169 if (e.ip == 0)
198 return -IPSET_ERR_HASH_ELEM; 170 return -IPSET_ERR_HASH_ELEM;
199 ret = adtfn(set, &nip, timeout, flags); 171 ret = adtfn(set, &e, &ext, &ext, flags);
200 172
201 if (ret && !ip_set_eexist(ret, flags)) 173 if (ret && !ip_set_eexist(ret, flags))
202 return ret; 174 return ret;
@@ -206,29 +178,31 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
206 return ret; 178 return ret;
207} 179}
208 180
209static bool 181/* IPv6 variants */
210hash_ip_same_set(const struct ip_set *a, const struct ip_set *b)
211{
212 const struct ip_set_hash *x = a->data;
213 const struct ip_set_hash *y = b->data;
214 182
215 /* Resizing changes htable_bits, so we ignore it */ 183/* Member elements */
216 return x->maxelem == y->maxelem && 184struct hash_ip6_elem {
217 x->timeout == y->timeout && 185 union nf_inet_addr ip;
218 x->netmask == y->netmask; 186};
219}
220 187
221/* The type variant functions: IPv6 */ 188struct hash_ip6t_elem {
189 union nf_inet_addr ip;
190 unsigned long timeout;
191};
222 192
223struct hash_ip6_elem { 193struct hash_ip6c_elem {
224 union nf_inet_addr ip; 194 union nf_inet_addr ip;
195 struct ip_set_counter counter;
225}; 196};
226 197
227struct hash_ip6_telem { 198struct hash_ip6ct_elem {
228 union nf_inet_addr ip; 199 union nf_inet_addr ip;
200 struct ip_set_counter counter;
229 unsigned long timeout; 201 unsigned long timeout;
230}; 202};
231 203
204/* Common functions */
205
232static inline bool 206static inline bool
233hash_ip6_data_equal(const struct hash_ip6_elem *ip1, 207hash_ip6_data_equal(const struct hash_ip6_elem *ip1,
234 const struct hash_ip6_elem *ip2, 208 const struct hash_ip6_elem *ip2,
@@ -237,37 +211,16 @@ hash_ip6_data_equal(const struct hash_ip6_elem *ip1,
237 return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6); 211 return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6);
238} 212}
239 213
240static inline bool
241hash_ip6_data_isnull(const struct hash_ip6_elem *elem)
242{
243 return ipv6_addr_any(&elem->ip.in6);
244}
245
246static inline void 214static inline void
247hash_ip6_data_copy(struct hash_ip6_elem *dst, const struct hash_ip6_elem *src) 215hash_ip6_netmask(union nf_inet_addr *ip, u8 prefix)
248{ 216{
249 dst->ip.in6 = src->ip.in6; 217 ip6_netmask(ip, prefix);
250}
251
252static inline void
253hash_ip6_data_zero_out(struct hash_ip6_elem *elem)
254{
255 ipv6_addr_set(&elem->ip.in6, 0, 0, 0, 0);
256}
257
258static inline void
259ip6_netmask(union nf_inet_addr *ip, u8 prefix)
260{
261 ip->ip6[0] &= ip_set_netmask6(prefix)[0];
262 ip->ip6[1] &= ip_set_netmask6(prefix)[1];
263 ip->ip6[2] &= ip_set_netmask6(prefix)[2];
264 ip->ip6[3] &= ip_set_netmask6(prefix)[3];
265} 218}
266 219
267static bool 220static bool
268hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *data) 221hash_ip6_data_list(struct sk_buff *skb, const struct hash_ip6_elem *e)
269{ 222{
270 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6)) 223 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6))
271 goto nla_put_failure; 224 goto nla_put_failure;
272 return 0; 225 return 0;
273 226
@@ -275,69 +228,55 @@ nla_put_failure:
275 return 1; 228 return 1;
276} 229}
277 230
278static bool 231static inline void
279hash_ip6_data_tlist(struct sk_buff *skb, const struct hash_ip6_elem *data) 232hash_ip6_data_next(struct hash_ip4_elem *next, const struct hash_ip6_elem *e)
280{ 233{
281 const struct hash_ip6_telem *e =
282 (const struct hash_ip6_telem *)data;
283
284 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
285 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
286 htonl(ip_set_timeout_get(e->timeout))))
287 goto nla_put_failure;
288 return 0;
289
290nla_put_failure:
291 return 1;
292} 234}
293 235
236#undef MTYPE
294#undef PF 237#undef PF
295#undef HOST_MASK 238#undef HOST_MASK
239#undef HKEY_DATALEN
296 240
241#define MTYPE hash_ip6
297#define PF 6 242#define PF 6
298#define HOST_MASK 128 243#define HOST_MASK 128
299#include <linux/netfilter/ipset/ip_set_ahash.h>
300 244
301static inline void 245#define IP_SET_EMIT_CREATE
302hash_ip6_data_next(struct ip_set_hash *h, const struct hash_ip6_elem *d) 246#include "ip_set_hash_gen.h"
303{
304}
305 247
306static int 248static int
307hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb, 249hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb,
308 const struct xt_action_param *par, 250 const struct xt_action_param *par,
309 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 251 enum ipset_adt adt, struct ip_set_adt_opt *opt)
310{ 252{
311 const struct ip_set_hash *h = set->data; 253 const struct hash_ip *h = set->data;
312 ipset_adtfn adtfn = set->variant->adt[adt]; 254 ipset_adtfn adtfn = set->variant->adt[adt];
313 union nf_inet_addr ip; 255 struct hash_ip6_elem e = {};
256 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
314 257
315 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip.in6); 258 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
316 ip6_netmask(&ip, h->netmask); 259 hash_ip6_netmask(&e.ip, h->netmask);
317 if (ipv6_addr_any(&ip.in6)) 260 if (ipv6_addr_any(&e.ip.in6))
318 return -EINVAL; 261 return -EINVAL;
319 262
320 return adtfn(set, &ip, opt_timeout(opt, h), opt->cmdflags); 263 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
321} 264}
322 265
323static const struct nla_policy hash_ip6_adt_policy[IPSET_ATTR_ADT_MAX + 1] = {
324 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
325 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
326 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
327};
328
329static int 266static int
330hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[], 267hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
331 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 268 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
332{ 269{
333 const struct ip_set_hash *h = set->data; 270 const struct hash_ip *h = set->data;
334 ipset_adtfn adtfn = set->variant->adt[adt]; 271 ipset_adtfn adtfn = set->variant->adt[adt];
335 union nf_inet_addr ip; 272 struct hash_ip6_elem e = {};
336 u32 timeout = h->timeout; 273 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
337 int ret; 274 int ret;
338 275
339 if (unlikely(!tb[IPSET_ATTR_IP] || 276 if (unlikely(!tb[IPSET_ATTR_IP] ||
340 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 277 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
278 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
279 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
341 tb[IPSET_ATTR_IP_TO] || 280 tb[IPSET_ATTR_IP_TO] ||
342 tb[IPSET_ATTR_CIDR])) 281 tb[IPSET_ATTR_CIDR]))
343 return -IPSET_ERR_PROTOCOL; 282 return -IPSET_ERR_PROTOCOL;
@@ -345,110 +284,20 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
345 if (tb[IPSET_ATTR_LINENO]) 284 if (tb[IPSET_ATTR_LINENO])
346 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 285 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
347 286
348 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &ip); 287 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
288 ip_set_get_extensions(set, tb, &ext);
349 if (ret) 289 if (ret)
350 return ret; 290 return ret;
351 291
352 ip6_netmask(&ip, h->netmask); 292 hash_ip6_netmask(&e.ip, h->netmask);
353 if (ipv6_addr_any(&ip.in6)) 293 if (ipv6_addr_any(&e.ip.in6))
354 return -IPSET_ERR_HASH_ELEM; 294 return -IPSET_ERR_HASH_ELEM;
355 295
356 if (tb[IPSET_ATTR_TIMEOUT]) { 296 ret = adtfn(set, &e, &ext, &ext, flags);
357 if (!with_timeout(h->timeout))
358 return -IPSET_ERR_TIMEOUT;
359 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
360 }
361
362 ret = adtfn(set, &ip, timeout, flags);
363 297
364 return ip_set_eexist(ret, flags) ? 0 : ret; 298 return ip_set_eexist(ret, flags) ? 0 : ret;
365} 299}
366 300
367/* Create hash:ip type of sets */
368
369static int
370hash_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
371{
372 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
373 u8 netmask, hbits;
374 size_t hsize;
375 struct ip_set_hash *h;
376
377 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
378 return -IPSET_ERR_INVALID_FAMILY;
379 netmask = set->family == NFPROTO_IPV4 ? 32 : 128;
380 pr_debug("Create set %s with family %s\n",
381 set->name, set->family == NFPROTO_IPV4 ? "inet" : "inet6");
382
383 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
384 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
385 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
386 return -IPSET_ERR_PROTOCOL;
387
388 if (tb[IPSET_ATTR_HASHSIZE]) {
389 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
390 if (hashsize < IPSET_MIMINAL_HASHSIZE)
391 hashsize = IPSET_MIMINAL_HASHSIZE;
392 }
393
394 if (tb[IPSET_ATTR_MAXELEM])
395 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
396
397 if (tb[IPSET_ATTR_NETMASK]) {
398 netmask = nla_get_u8(tb[IPSET_ATTR_NETMASK]);
399
400 if ((set->family == NFPROTO_IPV4 && netmask > 32) ||
401 (set->family == NFPROTO_IPV6 && netmask > 128) ||
402 netmask == 0)
403 return -IPSET_ERR_INVALID_NETMASK;
404 }
405
406 h = kzalloc(sizeof(*h), GFP_KERNEL);
407 if (!h)
408 return -ENOMEM;
409
410 h->maxelem = maxelem;
411 h->netmask = netmask;
412 get_random_bytes(&h->initval, sizeof(h->initval));
413 h->timeout = IPSET_NO_TIMEOUT;
414
415 hbits = htable_bits(hashsize);
416 hsize = htable_size(hbits);
417 if (hsize == 0) {
418 kfree(h);
419 return -ENOMEM;
420 }
421 h->table = ip_set_alloc(hsize);
422 if (!h->table) {
423 kfree(h);
424 return -ENOMEM;
425 }
426 h->table->htable_bits = hbits;
427
428 set->data = h;
429
430 if (tb[IPSET_ATTR_TIMEOUT]) {
431 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
432
433 set->variant = set->family == NFPROTO_IPV4
434 ? &hash_ip4_tvariant : &hash_ip6_tvariant;
435
436 if (set->family == NFPROTO_IPV4)
437 hash_ip4_gc_init(set);
438 else
439 hash_ip6_gc_init(set);
440 } else {
441 set->variant = set->family == NFPROTO_IPV4
442 ? &hash_ip4_variant : &hash_ip6_variant;
443 }
444
445 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
446 set->name, jhash_size(h->table->htable_bits),
447 h->table->htable_bits, h->maxelem, set->data, h->table);
448
449 return 0;
450}
451
452static struct ip_set_type hash_ip_type __read_mostly = { 301static struct ip_set_type hash_ip_type __read_mostly = {
453 .name = "hash:ip", 302 .name = "hash:ip",
454 .protocol = IPSET_PROTOCOL, 303 .protocol = IPSET_PROTOCOL,
@@ -465,6 +314,7 @@ static struct ip_set_type hash_ip_type __read_mostly = {
465 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 314 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
466 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 315 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
467 [IPSET_ATTR_NETMASK] = { .type = NLA_U8 }, 316 [IPSET_ATTR_NETMASK] = { .type = NLA_U8 },
317 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
468 }, 318 },
469 .adt_policy = { 319 .adt_policy = {
470 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 320 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -472,6 +322,8 @@ static struct ip_set_type hash_ip_type __read_mostly = {
472 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 322 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
473 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 323 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
474 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 324 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
325 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
326 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
475 }, 327 },
476 .me = THIS_MODULE, 328 .me = THIS_MODULE,
477}; 329};
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index d8f77bacae86..7a2d2bd98d04 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -21,12 +21,12 @@
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h> 22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_timeout.h>
25#include <linux/netfilter/ipset/ip_set_getport.h> 24#include <linux/netfilter/ipset/ip_set_getport.h>
26#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
27 26
28#define REVISION_MIN 0 27#define REVISION_MIN 0
29#define REVISION_MAX 1 /* SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29#define REVISION_MAX 2 /* Counters support added */
30 30
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -34,33 +34,45 @@ IP_SET_MODULE_DESC("hash:ip,port", REVISION_MIN, REVISION_MAX);
34MODULE_ALIAS("ip_set_hash:ip,port"); 34MODULE_ALIAS("ip_set_hash:ip,port");
35 35
36/* Type specific function prefix */ 36/* Type specific function prefix */
37#define TYPE hash_ipport 37#define HTYPE hash_ipport
38 38
39static bool 39/* IPv4 variants */
40hash_ipport_same_set(const struct ip_set *a, const struct ip_set *b);
41 40
42#define hash_ipport4_same_set hash_ipport_same_set 41/* Member elements */
43#define hash_ipport6_same_set hash_ipport_same_set 42struct hash_ipport4_elem {
43 __be32 ip;
44 __be16 port;
45 u8 proto;
46 u8 padding;
47};
44 48
45/* The type variant functions: IPv4 */ 49struct hash_ipport4t_elem {
50 __be32 ip;
51 __be16 port;
52 u8 proto;
53 u8 padding;
54 unsigned long timeout;
55};
46 56
47/* Member elements without timeout */ 57struct hash_ipport4c_elem {
48struct hash_ipport4_elem {
49 __be32 ip; 58 __be32 ip;
50 __be16 port; 59 __be16 port;
51 u8 proto; 60 u8 proto;
52 u8 padding; 61 u8 padding;
62 struct ip_set_counter counter;
53}; 63};
54 64
55/* Member elements with timeout support */ 65struct hash_ipport4ct_elem {
56struct hash_ipport4_telem {
57 __be32 ip; 66 __be32 ip;
58 __be16 port; 67 __be16 port;
59 u8 proto; 68 u8 proto;
60 u8 padding; 69 u8 padding;
70 struct ip_set_counter counter;
61 unsigned long timeout; 71 unsigned long timeout;
62}; 72};
63 73
74/* Common functions */
75
64static inline bool 76static inline bool
65hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1, 77hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1,
66 const struct hash_ipport4_elem *ip2, 78 const struct hash_ipport4_elem *ip2,
@@ -71,27 +83,6 @@ hash_ipport4_data_equal(const struct hash_ipport4_elem *ip1,
71 ip1->proto == ip2->proto; 83 ip1->proto == ip2->proto;
72} 84}
73 85
74static inline bool
75hash_ipport4_data_isnull(const struct hash_ipport4_elem *elem)
76{
77 return elem->proto == 0;
78}
79
80static inline void
81hash_ipport4_data_copy(struct hash_ipport4_elem *dst,
82 const struct hash_ipport4_elem *src)
83{
84 dst->ip = src->ip;
85 dst->port = src->port;
86 dst->proto = src->proto;
87}
88
89static inline void
90hash_ipport4_data_zero_out(struct hash_ipport4_elem *elem)
91{
92 elem->proto = 0;
93}
94
95static bool 86static bool
96hash_ipport4_data_list(struct sk_buff *skb, 87hash_ipport4_data_list(struct sk_buff *skb,
97 const struct hash_ipport4_elem *data) 88 const struct hash_ipport4_elem *data)
@@ -106,111 +97,91 @@ nla_put_failure:
106 return 1; 97 return 1;
107} 98}
108 99
109static bool
110hash_ipport4_data_tlist(struct sk_buff *skb,
111 const struct hash_ipport4_elem *data)
112{
113 const struct hash_ipport4_telem *tdata =
114 (const struct hash_ipport4_telem *)data;
115
116 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
117 nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
118 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
119 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
120 htonl(ip_set_timeout_get(tdata->timeout))))
121 goto nla_put_failure;
122 return 0;
123
124nla_put_failure:
125 return 1;
126}
127
128#define PF 4
129#define HOST_MASK 32
130#include <linux/netfilter/ipset/ip_set_ahash.h>
131
132static inline void 100static inline void
133hash_ipport4_data_next(struct ip_set_hash *h, 101hash_ipport4_data_next(struct hash_ipport4_elem *next,
134 const struct hash_ipport4_elem *d) 102 const struct hash_ipport4_elem *d)
135{ 103{
136 h->next.ip = d->ip; 104 next->ip = d->ip;
137 h->next.port = d->port; 105 next->port = d->port;
138} 106}
139 107
108#define MTYPE hash_ipport4
109#define PF 4
110#define HOST_MASK 32
111#define HKEY_DATALEN sizeof(struct hash_ipport4_elem)
112#include "ip_set_hash_gen.h"
113
140static int 114static int
141hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb, 115hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
142 const struct xt_action_param *par, 116 const struct xt_action_param *par,
143 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 117 enum ipset_adt adt, struct ip_set_adt_opt *opt)
144{ 118{
145 const struct ip_set_hash *h = set->data; 119 const struct hash_ipport *h = set->data;
146 ipset_adtfn adtfn = set->variant->adt[adt]; 120 ipset_adtfn adtfn = set->variant->adt[adt];
147 struct hash_ipport4_elem data = { }; 121 struct hash_ipport4_elem e = { };
122 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
148 123
149 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 124 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
150 &data.port, &data.proto)) 125 &e.port, &e.proto))
151 return -EINVAL; 126 return -EINVAL;
152 127
153 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); 128 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
154 129 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
155 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
156} 130}
157 131
158static int 132static int
159hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], 133hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
160 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 134 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
161{ 135{
162 const struct ip_set_hash *h = set->data; 136 const struct hash_ipport *h = set->data;
163 ipset_adtfn adtfn = set->variant->adt[adt]; 137 ipset_adtfn adtfn = set->variant->adt[adt];
164 struct hash_ipport4_elem data = { }; 138 struct hash_ipport4_elem e = { };
139 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
165 u32 ip, ip_to, p = 0, port, port_to; 140 u32 ip, ip_to, p = 0, port, port_to;
166 u32 timeout = h->timeout;
167 bool with_ports = false; 141 bool with_ports = false;
168 int ret; 142 int ret;
169 143
170 if (unlikely(!tb[IPSET_ATTR_IP] || 144 if (unlikely(!tb[IPSET_ATTR_IP] ||
171 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 145 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
172 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 146 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
173 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 147 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
148 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
149 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
174 return -IPSET_ERR_PROTOCOL; 150 return -IPSET_ERR_PROTOCOL;
175 151
176 if (tb[IPSET_ATTR_LINENO]) 152 if (tb[IPSET_ATTR_LINENO])
177 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 153 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
178 154
179 ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip); 155 ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &e.ip) ||
156 ip_set_get_extensions(set, tb, &ext);
180 if (ret) 157 if (ret)
181 return ret; 158 return ret;
182 159
183 if (tb[IPSET_ATTR_PORT]) 160 if (tb[IPSET_ATTR_PORT])
184 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 161 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
185 else 162 else
186 return -IPSET_ERR_PROTOCOL; 163 return -IPSET_ERR_PROTOCOL;
187 164
188 if (tb[IPSET_ATTR_PROTO]) { 165 if (tb[IPSET_ATTR_PROTO]) {
189 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 166 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
190 with_ports = ip_set_proto_with_ports(data.proto); 167 with_ports = ip_set_proto_with_ports(e.proto);
191 168
192 if (data.proto == 0) 169 if (e.proto == 0)
193 return -IPSET_ERR_INVALID_PROTO; 170 return -IPSET_ERR_INVALID_PROTO;
194 } else 171 } else
195 return -IPSET_ERR_MISSING_PROTO; 172 return -IPSET_ERR_MISSING_PROTO;
196 173
197 if (!(with_ports || data.proto == IPPROTO_ICMP)) 174 if (!(with_ports || e.proto == IPPROTO_ICMP))
198 data.port = 0; 175 e.port = 0;
199
200 if (tb[IPSET_ATTR_TIMEOUT]) {
201 if (!with_timeout(h->timeout))
202 return -IPSET_ERR_TIMEOUT;
203 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
204 }
205 176
206 if (adt == IPSET_TEST || 177 if (adt == IPSET_TEST ||
207 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 178 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
208 tb[IPSET_ATTR_PORT_TO])) { 179 tb[IPSET_ATTR_PORT_TO])) {
209 ret = adtfn(set, &data, timeout, flags); 180 ret = adtfn(set, &e, &ext, &ext, flags);
210 return ip_set_eexist(ret, flags) ? 0 : ret; 181 return ip_set_eexist(ret, flags) ? 0 : ret;
211 } 182 }
212 183
213 ip_to = ip = ntohl(data.ip); 184 ip_to = ip = ntohl(e.ip);
214 if (tb[IPSET_ATTR_IP_TO]) { 185 if (tb[IPSET_ATTR_IP_TO]) {
215 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); 186 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
216 if (ret) 187 if (ret)
@@ -225,7 +196,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
225 ip_set_mask_from_to(ip, ip_to, cidr); 196 ip_set_mask_from_to(ip, ip_to, cidr);
226 } 197 }
227 198
228 port_to = port = ntohs(data.port); 199 port_to = port = ntohs(e.port);
229 if (with_ports && tb[IPSET_ATTR_PORT_TO]) { 200 if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
230 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 201 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
231 if (port > port_to) 202 if (port > port_to)
@@ -238,9 +209,9 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
238 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) 209 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
239 : port; 210 : port;
240 for (; p <= port_to; p++) { 211 for (; p <= port_to; p++) {
241 data.ip = htonl(ip); 212 e.ip = htonl(ip);
242 data.port = htons(p); 213 e.port = htons(p);
243 ret = adtfn(set, &data, timeout, flags); 214 ret = adtfn(set, &e, &ext, &ext, flags);
244 215
245 if (ret && !ip_set_eexist(ret, flags)) 216 if (ret && !ip_set_eexist(ret, flags))
246 return ret; 217 return ret;
@@ -251,34 +222,42 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
251 return ret; 222 return ret;
252} 223}
253 224
254static bool 225/* IPv6 variants */
255hash_ipport_same_set(const struct ip_set *a, const struct ip_set *b)
256{
257 const struct ip_set_hash *x = a->data;
258 const struct ip_set_hash *y = b->data;
259 226
260 /* Resizing changes htable_bits, so we ignore it */ 227struct hash_ipport6_elem {
261 return x->maxelem == y->maxelem && 228 union nf_inet_addr ip;
262 x->timeout == y->timeout; 229 __be16 port;
263} 230 u8 proto;
231 u8 padding;
232};
264 233
265/* The type variant functions: IPv6 */ 234struct hash_ipport6t_elem {
235 union nf_inet_addr ip;
236 __be16 port;
237 u8 proto;
238 u8 padding;
239 unsigned long timeout;
240};
266 241
267struct hash_ipport6_elem { 242struct hash_ipport6c_elem {
268 union nf_inet_addr ip; 243 union nf_inet_addr ip;
269 __be16 port; 244 __be16 port;
270 u8 proto; 245 u8 proto;
271 u8 padding; 246 u8 padding;
247 struct ip_set_counter counter;
272}; 248};
273 249
274struct hash_ipport6_telem { 250struct hash_ipport6ct_elem {
275 union nf_inet_addr ip; 251 union nf_inet_addr ip;
276 __be16 port; 252 __be16 port;
277 u8 proto; 253 u8 proto;
278 u8 padding; 254 u8 padding;
255 struct ip_set_counter counter;
279 unsigned long timeout; 256 unsigned long timeout;
280}; 257};
281 258
259/* Common functions */
260
282static inline bool 261static inline bool
283hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1, 262hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1,
284 const struct hash_ipport6_elem *ip2, 263 const struct hash_ipport6_elem *ip2,
@@ -289,25 +268,6 @@ hash_ipport6_data_equal(const struct hash_ipport6_elem *ip1,
289 ip1->proto == ip2->proto; 268 ip1->proto == ip2->proto;
290} 269}
291 270
292static inline bool
293hash_ipport6_data_isnull(const struct hash_ipport6_elem *elem)
294{
295 return elem->proto == 0;
296}
297
298static inline void
299hash_ipport6_data_copy(struct hash_ipport6_elem *dst,
300 const struct hash_ipport6_elem *src)
301{
302 memcpy(dst, src, sizeof(*dst));
303}
304
305static inline void
306hash_ipport6_data_zero_out(struct hash_ipport6_elem *elem)
307{
308 elem->proto = 0;
309}
310
311static bool 271static bool
312hash_ipport6_data_list(struct sk_buff *skb, 272hash_ipport6_data_list(struct sk_buff *skb,
313 const struct hash_ipport6_elem *data) 273 const struct hash_ipport6_elem *data)
@@ -322,66 +282,52 @@ nla_put_failure:
322 return 1; 282 return 1;
323} 283}
324 284
325static bool 285static inline void
326hash_ipport6_data_tlist(struct sk_buff *skb, 286hash_ipport6_data_next(struct hash_ipport4_elem *next,
327 const struct hash_ipport6_elem *data) 287 const struct hash_ipport6_elem *d)
328{ 288{
329 const struct hash_ipport6_telem *e = 289 next->port = d->port;
330 (const struct hash_ipport6_telem *)data;
331
332 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
333 nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
334 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
335 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
336 htonl(ip_set_timeout_get(e->timeout))))
337 goto nla_put_failure;
338 return 0;
339
340nla_put_failure:
341 return 1;
342} 290}
343 291
292#undef MTYPE
344#undef PF 293#undef PF
345#undef HOST_MASK 294#undef HOST_MASK
295#undef HKEY_DATALEN
346 296
297#define MTYPE hash_ipport6
347#define PF 6 298#define PF 6
348#define HOST_MASK 128 299#define HOST_MASK 128
349#include <linux/netfilter/ipset/ip_set_ahash.h> 300#define HKEY_DATALEN sizeof(struct hash_ipport6_elem)
350 301#define IP_SET_EMIT_CREATE
351static inline void 302#include "ip_set_hash_gen.h"
352hash_ipport6_data_next(struct ip_set_hash *h,
353 const struct hash_ipport6_elem *d)
354{
355 h->next.port = d->port;
356}
357 303
358static int 304static int
359hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb, 305hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
360 const struct xt_action_param *par, 306 const struct xt_action_param *par,
361 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 307 enum ipset_adt adt, struct ip_set_adt_opt *opt)
362{ 308{
363 const struct ip_set_hash *h = set->data; 309 const struct hash_ipport *h = set->data;
364 ipset_adtfn adtfn = set->variant->adt[adt]; 310 ipset_adtfn adtfn = set->variant->adt[adt];
365 struct hash_ipport6_elem data = { }; 311 struct hash_ipport6_elem e = { };
312 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
366 313
367 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 314 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
368 &data.port, &data.proto)) 315 &e.port, &e.proto))
369 return -EINVAL; 316 return -EINVAL;
370 317
371 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); 318 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
372 319 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
373 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
374} 320}
375 321
376static int 322static int
377hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], 323hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
378 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 324 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
379{ 325{
380 const struct ip_set_hash *h = set->data; 326 const struct hash_ipport *h = set->data;
381 ipset_adtfn adtfn = set->variant->adt[adt]; 327 ipset_adtfn adtfn = set->variant->adt[adt];
382 struct hash_ipport6_elem data = { }; 328 struct hash_ipport6_elem e = { };
329 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
383 u32 port, port_to; 330 u32 port, port_to;
384 u32 timeout = h->timeout;
385 bool with_ports = false; 331 bool with_ports = false;
386 int ret; 332 int ret;
387 333
@@ -389,6 +335,8 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
389 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 335 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
390 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 336 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
391 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 337 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
338 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
339 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
392 tb[IPSET_ATTR_IP_TO] || 340 tb[IPSET_ATTR_IP_TO] ||
393 tb[IPSET_ATTR_CIDR])) 341 tb[IPSET_ATTR_CIDR]))
394 return -IPSET_ERR_PROTOCOL; 342 return -IPSET_ERR_PROTOCOL;
@@ -396,39 +344,34 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
396 if (tb[IPSET_ATTR_LINENO]) 344 if (tb[IPSET_ATTR_LINENO])
397 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 345 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
398 346
399 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); 347 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
348 ip_set_get_extensions(set, tb, &ext);
400 if (ret) 349 if (ret)
401 return ret; 350 return ret;
402 351
403 if (tb[IPSET_ATTR_PORT]) 352 if (tb[IPSET_ATTR_PORT])
404 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 353 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
405 else 354 else
406 return -IPSET_ERR_PROTOCOL; 355 return -IPSET_ERR_PROTOCOL;
407 356
408 if (tb[IPSET_ATTR_PROTO]) { 357 if (tb[IPSET_ATTR_PROTO]) {
409 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 358 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
410 with_ports = ip_set_proto_with_ports(data.proto); 359 with_ports = ip_set_proto_with_ports(e.proto);
411 360
412 if (data.proto == 0) 361 if (e.proto == 0)
413 return -IPSET_ERR_INVALID_PROTO; 362 return -IPSET_ERR_INVALID_PROTO;
414 } else 363 } else
415 return -IPSET_ERR_MISSING_PROTO; 364 return -IPSET_ERR_MISSING_PROTO;
416 365
417 if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 366 if (!(with_ports || e.proto == IPPROTO_ICMPV6))
418 data.port = 0; 367 e.port = 0;
419
420 if (tb[IPSET_ATTR_TIMEOUT]) {
421 if (!with_timeout(h->timeout))
422 return -IPSET_ERR_TIMEOUT;
423 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
424 }
425 368
426 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 369 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
427 ret = adtfn(set, &data, timeout, flags); 370 ret = adtfn(set, &e, &ext, &ext, flags);
428 return ip_set_eexist(ret, flags) ? 0 : ret; 371 return ip_set_eexist(ret, flags) ? 0 : ret;
429 } 372 }
430 373
431 port = ntohs(data.port); 374 port = ntohs(e.port);
432 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 375 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
433 if (port > port_to) 376 if (port > port_to)
434 swap(port, port_to); 377 swap(port, port_to);
@@ -436,8 +379,8 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
436 if (retried) 379 if (retried)
437 port = ntohs(h->next.port); 380 port = ntohs(h->next.port);
438 for (; port <= port_to; port++) { 381 for (; port <= port_to; port++) {
439 data.port = htons(port); 382 e.port = htons(port);
440 ret = adtfn(set, &data, timeout, flags); 383 ret = adtfn(set, &e, &ext, &ext, flags);
441 384
442 if (ret && !ip_set_eexist(ret, flags)) 385 if (ret && !ip_set_eexist(ret, flags))
443 return ret; 386 return ret;
@@ -447,78 +390,6 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
447 return ret; 390 return ret;
448} 391}
449 392
450/* Create hash:ip type of sets */
451
452static int
453hash_ipport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
454{
455 struct ip_set_hash *h;
456 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
457 u8 hbits;
458 size_t hsize;
459
460 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
461 return -IPSET_ERR_INVALID_FAMILY;
462
463 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
464 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
465 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
466 return -IPSET_ERR_PROTOCOL;
467
468 if (tb[IPSET_ATTR_HASHSIZE]) {
469 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
470 if (hashsize < IPSET_MIMINAL_HASHSIZE)
471 hashsize = IPSET_MIMINAL_HASHSIZE;
472 }
473
474 if (tb[IPSET_ATTR_MAXELEM])
475 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
476
477 h = kzalloc(sizeof(*h), GFP_KERNEL);
478 if (!h)
479 return -ENOMEM;
480
481 h->maxelem = maxelem;
482 get_random_bytes(&h->initval, sizeof(h->initval));
483 h->timeout = IPSET_NO_TIMEOUT;
484
485 hbits = htable_bits(hashsize);
486 hsize = htable_size(hbits);
487 if (hsize == 0) {
488 kfree(h);
489 return -ENOMEM;
490 }
491 h->table = ip_set_alloc(hsize);
492 if (!h->table) {
493 kfree(h);
494 return -ENOMEM;
495 }
496 h->table->htable_bits = hbits;
497
498 set->data = h;
499
500 if (tb[IPSET_ATTR_TIMEOUT]) {
501 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
502
503 set->variant = set->family == NFPROTO_IPV4
504 ? &hash_ipport4_tvariant : &hash_ipport6_tvariant;
505
506 if (set->family == NFPROTO_IPV4)
507 hash_ipport4_gc_init(set);
508 else
509 hash_ipport6_gc_init(set);
510 } else {
511 set->variant = set->family == NFPROTO_IPV4
512 ? &hash_ipport4_variant : &hash_ipport6_variant;
513 }
514
515 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
516 set->name, jhash_size(h->table->htable_bits),
517 h->table->htable_bits, h->maxelem, set->data, h->table);
518
519 return 0;
520}
521
522static struct ip_set_type hash_ipport_type __read_mostly = { 393static struct ip_set_type hash_ipport_type __read_mostly = {
523 .name = "hash:ip,port", 394 .name = "hash:ip,port",
524 .protocol = IPSET_PROTOCOL, 395 .protocol = IPSET_PROTOCOL,
@@ -535,6 +406,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
535 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 406 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
536 [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, 407 [IPSET_ATTR_PROTO] = { .type = NLA_U8 },
537 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 408 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
409 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
538 }, 410 },
539 .adt_policy = { 411 .adt_policy = {
540 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 412 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -545,6 +417,8 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
545 [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, 417 [IPSET_ATTR_PROTO] = { .type = NLA_U8 },
546 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 418 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
547 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 419 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
420 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
421 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
548 }, 422 },
549 .me = THIS_MODULE, 423 .me = THIS_MODULE,
550}; 424};
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index 1da1e955f38b..34e8a1acce42 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -21,12 +21,12 @@
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h> 22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_timeout.h>
25#include <linux/netfilter/ipset/ip_set_getport.h> 24#include <linux/netfilter/ipset/ip_set_getport.h>
26#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
27 26
28#define REVISION_MIN 0 27#define REVISION_MIN 0
29#define REVISION_MAX 1 /* SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
29#define REVISION_MAX 2 /* Counters support added */
30 30
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -34,32 +34,44 @@ IP_SET_MODULE_DESC("hash:ip,port,ip", REVISION_MIN, REVISION_MAX);
34MODULE_ALIAS("ip_set_hash:ip,port,ip"); 34MODULE_ALIAS("ip_set_hash:ip,port,ip");
35 35
36/* Type specific function prefix */ 36/* Type specific function prefix */
37#define TYPE hash_ipportip 37#define HTYPE hash_ipportip
38 38
39static bool 39/* IPv4 variants */
40hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b);
41 40
42#define hash_ipportip4_same_set hash_ipportip_same_set 41/* Member elements */
43#define hash_ipportip6_same_set hash_ipportip_same_set 42struct hash_ipportip4_elem {
43 __be32 ip;
44 __be32 ip2;
45 __be16 port;
46 u8 proto;
47 u8 padding;
48};
44 49
45/* The type variant functions: IPv4 */ 50struct hash_ipportip4t_elem {
51 __be32 ip;
52 __be32 ip2;
53 __be16 port;
54 u8 proto;
55 u8 padding;
56 unsigned long timeout;
57};
46 58
47/* Member elements without timeout */ 59struct hash_ipportip4c_elem {
48struct hash_ipportip4_elem {
49 __be32 ip; 60 __be32 ip;
50 __be32 ip2; 61 __be32 ip2;
51 __be16 port; 62 __be16 port;
52 u8 proto; 63 u8 proto;
53 u8 padding; 64 u8 padding;
65 struct ip_set_counter counter;
54}; 66};
55 67
56/* Member elements with timeout support */ 68struct hash_ipportip4ct_elem {
57struct hash_ipportip4_telem {
58 __be32 ip; 69 __be32 ip;
59 __be32 ip2; 70 __be32 ip2;
60 __be16 port; 71 __be16 port;
61 u8 proto; 72 u8 proto;
62 u8 padding; 73 u8 padding;
74 struct ip_set_counter counter;
63 unsigned long timeout; 75 unsigned long timeout;
64}; 76};
65 77
@@ -74,25 +86,6 @@ hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
74 ip1->proto == ip2->proto; 86 ip1->proto == ip2->proto;
75} 87}
76 88
77static inline bool
78hash_ipportip4_data_isnull(const struct hash_ipportip4_elem *elem)
79{
80 return elem->proto == 0;
81}
82
83static inline void
84hash_ipportip4_data_copy(struct hash_ipportip4_elem *dst,
85 const struct hash_ipportip4_elem *src)
86{
87 memcpy(dst, src, sizeof(*dst));
88}
89
90static inline void
91hash_ipportip4_data_zero_out(struct hash_ipportip4_elem *elem)
92{
93 elem->proto = 0;
94}
95
96static bool 89static bool
97hash_ipportip4_data_list(struct sk_buff *skb, 90hash_ipportip4_data_list(struct sk_buff *skb,
98 const struct hash_ipportip4_elem *data) 91 const struct hash_ipportip4_elem *data)
@@ -108,117 +101,96 @@ nla_put_failure:
108 return 1; 101 return 1;
109} 102}
110 103
111static bool 104static inline void
112hash_ipportip4_data_tlist(struct sk_buff *skb, 105hash_ipportip4_data_next(struct hash_ipportip4_elem *next,
113 const struct hash_ipportip4_elem *data) 106 const struct hash_ipportip4_elem *d)
114{ 107{
115 const struct hash_ipportip4_telem *tdata = 108 next->ip = d->ip;
116 (const struct hash_ipportip4_telem *)data; 109 next->port = d->port;
117
118 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
119 nla_put_ipaddr4(skb, IPSET_ATTR_IP2, tdata->ip2) ||
120 nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
121 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
122 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
123 htonl(ip_set_timeout_get(tdata->timeout))))
124 goto nla_put_failure;
125 return 0;
126
127nla_put_failure:
128 return 1;
129} 110}
130 111
112/* Common functions */
113#define MTYPE hash_ipportip4
131#define PF 4 114#define PF 4
132#define HOST_MASK 32 115#define HOST_MASK 32
133#include <linux/netfilter/ipset/ip_set_ahash.h> 116#include "ip_set_hash_gen.h"
134
135static inline void
136hash_ipportip4_data_next(struct ip_set_hash *h,
137 const struct hash_ipportip4_elem *d)
138{
139 h->next.ip = d->ip;
140 h->next.port = d->port;
141}
142 117
143static int 118static int
144hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb, 119hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
145 const struct xt_action_param *par, 120 const struct xt_action_param *par,
146 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 121 enum ipset_adt adt, struct ip_set_adt_opt *opt)
147{ 122{
148 const struct ip_set_hash *h = set->data; 123 const struct hash_ipportip *h = set->data;
149 ipset_adtfn adtfn = set->variant->adt[adt]; 124 ipset_adtfn adtfn = set->variant->adt[adt];
150 struct hash_ipportip4_elem data = { }; 125 struct hash_ipportip4_elem e = { };
126 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
151 127
152 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 128 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
153 &data.port, &data.proto)) 129 &e.port, &e.proto))
154 return -EINVAL; 130 return -EINVAL;
155 131
156 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); 132 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
157 ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2); 133 ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip2);
158 134 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
159 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
160} 135}
161 136
162static int 137static int
163hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], 138hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
164 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 139 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
165{ 140{
166 const struct ip_set_hash *h = set->data; 141 const struct hash_ipportip *h = set->data;
167 ipset_adtfn adtfn = set->variant->adt[adt]; 142 ipset_adtfn adtfn = set->variant->adt[adt];
168 struct hash_ipportip4_elem data = { }; 143 struct hash_ipportip4_elem e = { };
144 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
169 u32 ip, ip_to, p = 0, port, port_to; 145 u32 ip, ip_to, p = 0, port, port_to;
170 u32 timeout = h->timeout;
171 bool with_ports = false; 146 bool with_ports = false;
172 int ret; 147 int ret;
173 148
174 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] || 149 if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
175 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 150 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
176 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 151 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
177 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 152 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
153 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
154 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
178 return -IPSET_ERR_PROTOCOL; 155 return -IPSET_ERR_PROTOCOL;
179 156
180 if (tb[IPSET_ATTR_LINENO]) 157 if (tb[IPSET_ATTR_LINENO])
181 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 158 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
182 159
183 ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &data.ip); 160 ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &e.ip) ||
161 ip_set_get_extensions(set, tb, &ext);
184 if (ret) 162 if (ret)
185 return ret; 163 return ret;
186 164
187 ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &data.ip2); 165 ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP2], &e.ip2);
188 if (ret) 166 if (ret)
189 return ret; 167 return ret;
190 168
191 if (tb[IPSET_ATTR_PORT]) 169 if (tb[IPSET_ATTR_PORT])
192 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 170 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
193 else 171 else
194 return -IPSET_ERR_PROTOCOL; 172 return -IPSET_ERR_PROTOCOL;
195 173
196 if (tb[IPSET_ATTR_PROTO]) { 174 if (tb[IPSET_ATTR_PROTO]) {
197 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 175 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
198 with_ports = ip_set_proto_with_ports(data.proto); 176 with_ports = ip_set_proto_with_ports(e.proto);
199 177
200 if (data.proto == 0) 178 if (e.proto == 0)
201 return -IPSET_ERR_INVALID_PROTO; 179 return -IPSET_ERR_INVALID_PROTO;
202 } else 180 } else
203 return -IPSET_ERR_MISSING_PROTO; 181 return -IPSET_ERR_MISSING_PROTO;
204 182
205 if (!(with_ports || data.proto == IPPROTO_ICMP)) 183 if (!(with_ports || e.proto == IPPROTO_ICMP))
206 data.port = 0; 184 e.port = 0;
207
208 if (tb[IPSET_ATTR_TIMEOUT]) {
209 if (!with_timeout(h->timeout))
210 return -IPSET_ERR_TIMEOUT;
211 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
212 }
213 185
214 if (adt == IPSET_TEST || 186 if (adt == IPSET_TEST ||
215 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] || 187 !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR] ||
216 tb[IPSET_ATTR_PORT_TO])) { 188 tb[IPSET_ATTR_PORT_TO])) {
217 ret = adtfn(set, &data, timeout, flags); 189 ret = adtfn(set, &e, &ext, &ext, flags);
218 return ip_set_eexist(ret, flags) ? 0 : ret; 190 return ip_set_eexist(ret, flags) ? 0 : ret;
219 } 191 }
220 192
221 ip_to = ip = ntohl(data.ip); 193 ip_to = ip = ntohl(e.ip);
222 if (tb[IPSET_ATTR_IP_TO]) { 194 if (tb[IPSET_ATTR_IP_TO]) {
223 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to); 195 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
224 if (ret) 196 if (ret)
@@ -233,7 +205,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
233 ip_set_mask_from_to(ip, ip_to, cidr); 205 ip_set_mask_from_to(ip, ip_to, cidr);
234 } 206 }
235 207
236 port_to = port = ntohs(data.port); 208 port_to = port = ntohs(e.port);
237 if (with_ports && tb[IPSET_ATTR_PORT_TO]) { 209 if (with_ports && tb[IPSET_ATTR_PORT_TO]) {
238 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 210 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
239 if (port > port_to) 211 if (port > port_to)
@@ -246,9 +218,9 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
246 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) 218 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
247 : port; 219 : port;
248 for (; p <= port_to; p++) { 220 for (; p <= port_to; p++) {
249 data.ip = htonl(ip); 221 e.ip = htonl(ip);
250 data.port = htons(p); 222 e.port = htons(p);
251 ret = adtfn(set, &data, timeout, flags); 223 ret = adtfn(set, &e, &ext, &ext, flags);
252 224
253 if (ret && !ip_set_eexist(ret, flags)) 225 if (ret && !ip_set_eexist(ret, flags))
254 return ret; 226 return ret;
@@ -259,36 +231,46 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
259 return ret; 231 return ret;
260} 232}
261 233
262static bool 234/* IPv6 variants */
263hash_ipportip_same_set(const struct ip_set *a, const struct ip_set *b)
264{
265 const struct ip_set_hash *x = a->data;
266 const struct ip_set_hash *y = b->data;
267 235
268 /* Resizing changes htable_bits, so we ignore it */ 236struct hash_ipportip6_elem {
269 return x->maxelem == y->maxelem && 237 union nf_inet_addr ip;
270 x->timeout == y->timeout; 238 union nf_inet_addr ip2;
271} 239 __be16 port;
240 u8 proto;
241 u8 padding;
242};
272 243
273/* The type variant functions: IPv6 */ 244struct hash_ipportip6t_elem {
245 union nf_inet_addr ip;
246 union nf_inet_addr ip2;
247 __be16 port;
248 u8 proto;
249 u8 padding;
250 unsigned long timeout;
251};
274 252
275struct hash_ipportip6_elem { 253struct hash_ipportip6c_elem {
276 union nf_inet_addr ip; 254 union nf_inet_addr ip;
277 union nf_inet_addr ip2; 255 union nf_inet_addr ip2;
278 __be16 port; 256 __be16 port;
279 u8 proto; 257 u8 proto;
280 u8 padding; 258 u8 padding;
259 struct ip_set_counter counter;
281}; 260};
282 261
283struct hash_ipportip6_telem { 262struct hash_ipportip6ct_elem {
284 union nf_inet_addr ip; 263 union nf_inet_addr ip;
285 union nf_inet_addr ip2; 264 union nf_inet_addr ip2;
286 __be16 port; 265 __be16 port;
287 u8 proto; 266 u8 proto;
288 u8 padding; 267 u8 padding;
268 struct ip_set_counter counter;
289 unsigned long timeout; 269 unsigned long timeout;
290}; 270};
291 271
272/* Common functions */
273
292static inline bool 274static inline bool
293hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1, 275hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1,
294 const struct hash_ipportip6_elem *ip2, 276 const struct hash_ipportip6_elem *ip2,
@@ -300,25 +282,6 @@ hash_ipportip6_data_equal(const struct hash_ipportip6_elem *ip1,
300 ip1->proto == ip2->proto; 282 ip1->proto == ip2->proto;
301} 283}
302 284
303static inline bool
304hash_ipportip6_data_isnull(const struct hash_ipportip6_elem *elem)
305{
306 return elem->proto == 0;
307}
308
309static inline void
310hash_ipportip6_data_copy(struct hash_ipportip6_elem *dst,
311 const struct hash_ipportip6_elem *src)
312{
313 memcpy(dst, src, sizeof(*dst));
314}
315
316static inline void
317hash_ipportip6_data_zero_out(struct hash_ipportip6_elem *elem)
318{
319 elem->proto = 0;
320}
321
322static bool 285static bool
323hash_ipportip6_data_list(struct sk_buff *skb, 286hash_ipportip6_data_list(struct sk_buff *skb,
324 const struct hash_ipportip6_elem *data) 287 const struct hash_ipportip6_elem *data)
@@ -334,68 +297,51 @@ nla_put_failure:
334 return 1; 297 return 1;
335} 298}
336 299
337static bool 300static inline void
338hash_ipportip6_data_tlist(struct sk_buff *skb, 301hash_ipportip6_data_next(struct hash_ipportip4_elem *next,
339 const struct hash_ipportip6_elem *data) 302 const struct hash_ipportip6_elem *d)
340{ 303{
341 const struct hash_ipportip6_telem *e = 304 next->port = d->port;
342 (const struct hash_ipportip6_telem *)data;
343
344 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
345 nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
346 nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
347 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
348 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
349 htonl(ip_set_timeout_get(e->timeout))))
350 goto nla_put_failure;
351 return 0;
352
353nla_put_failure:
354 return 1;
355} 305}
356 306
307#undef MTYPE
357#undef PF 308#undef PF
358#undef HOST_MASK 309#undef HOST_MASK
359 310
311#define MTYPE hash_ipportip6
360#define PF 6 312#define PF 6
361#define HOST_MASK 128 313#define HOST_MASK 128
362#include <linux/netfilter/ipset/ip_set_ahash.h> 314#define IP_SET_EMIT_CREATE
363 315#include "ip_set_hash_gen.h"
364static inline void
365hash_ipportip6_data_next(struct ip_set_hash *h,
366 const struct hash_ipportip6_elem *d)
367{
368 h->next.port = d->port;
369}
370 316
371static int 317static int
372hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb, 318hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
373 const struct xt_action_param *par, 319 const struct xt_action_param *par,
374 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 320 enum ipset_adt adt, struct ip_set_adt_opt *opt)
375{ 321{
376 const struct ip_set_hash *h = set->data; 322 const struct hash_ipportip *h = set->data;
377 ipset_adtfn adtfn = set->variant->adt[adt]; 323 ipset_adtfn adtfn = set->variant->adt[adt];
378 struct hash_ipportip6_elem data = { }; 324 struct hash_ipportip6_elem e = { };
325 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
379 326
380 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 327 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
381 &data.port, &data.proto)) 328 &e.port, &e.proto))
382 return -EINVAL; 329 return -EINVAL;
383 330
384 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); 331 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
385 ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2.in6); 332 ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip2.in6);
386 333 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
387 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags);
388} 334}
389 335
390static int 336static int
391hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], 337hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
392 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 338 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
393{ 339{
394 const struct ip_set_hash *h = set->data; 340 const struct hash_ipportip *h = set->data;
395 ipset_adtfn adtfn = set->variant->adt[adt]; 341 ipset_adtfn adtfn = set->variant->adt[adt];
396 struct hash_ipportip6_elem data = { }; 342 struct hash_ipportip6_elem e = { };
343 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
397 u32 port, port_to; 344 u32 port, port_to;
398 u32 timeout = h->timeout;
399 bool with_ports = false; 345 bool with_ports = false;
400 int ret; 346 int ret;
401 347
@@ -403,6 +349,8 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
403 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 349 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
404 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 350 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
405 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 351 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
352 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
353 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
406 tb[IPSET_ATTR_IP_TO] || 354 tb[IPSET_ATTR_IP_TO] ||
407 tb[IPSET_ATTR_CIDR])) 355 tb[IPSET_ATTR_CIDR]))
408 return -IPSET_ERR_PROTOCOL; 356 return -IPSET_ERR_PROTOCOL;
@@ -410,43 +358,38 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
410 if (tb[IPSET_ATTR_LINENO]) 358 if (tb[IPSET_ATTR_LINENO])
411 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 359 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
412 360
413 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); 361 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
362 ip_set_get_extensions(set, tb, &ext);
414 if (ret) 363 if (ret)
415 return ret; 364 return ret;
416 365
417 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2); 366 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &e.ip2);
418 if (ret) 367 if (ret)
419 return ret; 368 return ret;
420 369
421 if (tb[IPSET_ATTR_PORT]) 370 if (tb[IPSET_ATTR_PORT])
422 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 371 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
423 else 372 else
424 return -IPSET_ERR_PROTOCOL; 373 return -IPSET_ERR_PROTOCOL;
425 374
426 if (tb[IPSET_ATTR_PROTO]) { 375 if (tb[IPSET_ATTR_PROTO]) {
427 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 376 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
428 with_ports = ip_set_proto_with_ports(data.proto); 377 with_ports = ip_set_proto_with_ports(e.proto);
429 378
430 if (data.proto == 0) 379 if (e.proto == 0)
431 return -IPSET_ERR_INVALID_PROTO; 380 return -IPSET_ERR_INVALID_PROTO;
432 } else 381 } else
433 return -IPSET_ERR_MISSING_PROTO; 382 return -IPSET_ERR_MISSING_PROTO;
434 383
435 if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 384 if (!(with_ports || e.proto == IPPROTO_ICMPV6))
436 data.port = 0; 385 e.port = 0;
437
438 if (tb[IPSET_ATTR_TIMEOUT]) {
439 if (!with_timeout(h->timeout))
440 return -IPSET_ERR_TIMEOUT;
441 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
442 }
443 386
444 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 387 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
445 ret = adtfn(set, &data, timeout, flags); 388 ret = adtfn(set, &e, &ext, &ext, flags);
446 return ip_set_eexist(ret, flags) ? 0 : ret; 389 return ip_set_eexist(ret, flags) ? 0 : ret;
447 } 390 }
448 391
449 port = ntohs(data.port); 392 port = ntohs(e.port);
450 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 393 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
451 if (port > port_to) 394 if (port > port_to)
452 swap(port, port_to); 395 swap(port, port_to);
@@ -454,8 +397,8 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
454 if (retried) 397 if (retried)
455 port = ntohs(h->next.port); 398 port = ntohs(h->next.port);
456 for (; port <= port_to; port++) { 399 for (; port <= port_to; port++) {
457 data.port = htons(port); 400 e.port = htons(port);
458 ret = adtfn(set, &data, timeout, flags); 401 ret = adtfn(set, &e, &ext, &ext, flags);
459 402
460 if (ret && !ip_set_eexist(ret, flags)) 403 if (ret && !ip_set_eexist(ret, flags))
461 return ret; 404 return ret;
@@ -465,78 +408,6 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
465 return ret; 408 return ret;
466} 409}
467 410
468/* Create hash:ip type of sets */
469
470static int
471hash_ipportip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
472{
473 struct ip_set_hash *h;
474 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
475 u8 hbits;
476 size_t hsize;
477
478 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
479 return -IPSET_ERR_INVALID_FAMILY;
480
481 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
482 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
483 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
484 return -IPSET_ERR_PROTOCOL;
485
486 if (tb[IPSET_ATTR_HASHSIZE]) {
487 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
488 if (hashsize < IPSET_MIMINAL_HASHSIZE)
489 hashsize = IPSET_MIMINAL_HASHSIZE;
490 }
491
492 if (tb[IPSET_ATTR_MAXELEM])
493 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
494
495 h = kzalloc(sizeof(*h), GFP_KERNEL);
496 if (!h)
497 return -ENOMEM;
498
499 h->maxelem = maxelem;
500 get_random_bytes(&h->initval, sizeof(h->initval));
501 h->timeout = IPSET_NO_TIMEOUT;
502
503 hbits = htable_bits(hashsize);
504 hsize = htable_size(hbits);
505 if (hsize == 0) {
506 kfree(h);
507 return -ENOMEM;
508 }
509 h->table = ip_set_alloc(hsize);
510 if (!h->table) {
511 kfree(h);
512 return -ENOMEM;
513 }
514 h->table->htable_bits = hbits;
515
516 set->data = h;
517
518 if (tb[IPSET_ATTR_TIMEOUT]) {
519 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
520
521 set->variant = set->family == NFPROTO_IPV4
522 ? &hash_ipportip4_tvariant : &hash_ipportip6_tvariant;
523
524 if (set->family == NFPROTO_IPV4)
525 hash_ipportip4_gc_init(set);
526 else
527 hash_ipportip6_gc_init(set);
528 } else {
529 set->variant = set->family == NFPROTO_IPV4
530 ? &hash_ipportip4_variant : &hash_ipportip6_variant;
531 }
532
533 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
534 set->name, jhash_size(h->table->htable_bits),
535 h->table->htable_bits, h->maxelem, set->data, h->table);
536
537 return 0;
538}
539
540static struct ip_set_type hash_ipportip_type __read_mostly = { 411static struct ip_set_type hash_ipportip_type __read_mostly = {
541 .name = "hash:ip,port,ip", 412 .name = "hash:ip,port,ip",
542 .protocol = IPSET_PROTOCOL, 413 .protocol = IPSET_PROTOCOL,
@@ -552,6 +423,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
552 [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, 423 [IPSET_ATTR_PROBES] = { .type = NLA_U8 },
553 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 424 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
554 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 425 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
426 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
555 }, 427 },
556 .adt_policy = { 428 .adt_policy = {
557 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 429 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -563,6 +435,8 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
563 [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, 435 [IPSET_ATTR_PROTO] = { .type = NLA_U8 },
564 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 436 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
565 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 437 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
438 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
439 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
566 }, 440 },
567 .me = THIS_MODULE, 441 .me = THIS_MODULE,
568}; 442};
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 10a30b4fc7db..c6a525373be4 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -21,14 +21,14 @@
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h> 22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_timeout.h>
25#include <linux/netfilter/ipset/ip_set_getport.h> 24#include <linux/netfilter/ipset/ip_set_getport.h>
26#include <linux/netfilter/ipset/ip_set_hash.h> 25#include <linux/netfilter/ipset/ip_set_hash.h>
27 26
28#define REVISION_MIN 0 27#define REVISION_MIN 0
29/* 1 SCTP and UDPLITE support added */ 28/* 1 SCTP and UDPLITE support added */
30/* 2 Range as input support for IPv4 added */ 29/* 2 Range as input support for IPv4 added */
31#define REVISION_MAX 3 /* nomatch flag support added */ 30/* 3 nomatch flag support added */
31#define REVISION_MAX 4 /* Counters support added */
32 32
33MODULE_LICENSE("GPL"); 33MODULE_LICENSE("GPL");
34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 34MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -36,23 +36,19 @@ IP_SET_MODULE_DESC("hash:ip,port,net", REVISION_MIN, REVISION_MAX);
36MODULE_ALIAS("ip_set_hash:ip,port,net"); 36MODULE_ALIAS("ip_set_hash:ip,port,net");
37 37
38/* Type specific function prefix */ 38/* Type specific function prefix */
39#define TYPE hash_ipportnet 39#define HTYPE hash_ipportnet
40
41static bool
42hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b);
43
44#define hash_ipportnet4_same_set hash_ipportnet_same_set
45#define hash_ipportnet6_same_set hash_ipportnet_same_set
46
47/* The type variant functions: IPv4 */
48 40
49/* We squeeze the "nomatch" flag into cidr: we don't support cidr == 0 41/* We squeeze the "nomatch" flag into cidr: we don't support cidr == 0
50 * However this way we have to store internally cidr - 1, 42 * However this way we have to store internally cidr - 1,
51 * dancing back and forth. 43 * dancing back and forth.
52 */ 44 */
53#define IP_SET_HASH_WITH_NETS_PACKED 45#define IP_SET_HASH_WITH_NETS_PACKED
46#define IP_SET_HASH_WITH_PROTO
47#define IP_SET_HASH_WITH_NETS
48
49/* IPv4 variants */
54 50
55/* Member elements without timeout */ 51/* Member elements */
56struct hash_ipportnet4_elem { 52struct hash_ipportnet4_elem {
57 __be32 ip; 53 __be32 ip;
58 __be32 ip2; 54 __be32 ip2;
@@ -62,8 +58,7 @@ struct hash_ipportnet4_elem {
62 u8 proto; 58 u8 proto;
63}; 59};
64 60
65/* Member elements with timeout support */ 61struct hash_ipportnet4t_elem {
66struct hash_ipportnet4_telem {
67 __be32 ip; 62 __be32 ip;
68 __be32 ip2; 63 __be32 ip2;
69 __be16 port; 64 __be16 port;
@@ -73,6 +68,29 @@ struct hash_ipportnet4_telem {
73 unsigned long timeout; 68 unsigned long timeout;
74}; 69};
75 70
71struct hash_ipportnet4c_elem {
72 __be32 ip;
73 __be32 ip2;
74 __be16 port;
75 u8 cidr:7;
76 u8 nomatch:1;
77 u8 proto;
78 struct ip_set_counter counter;
79};
80
81struct hash_ipportnet4ct_elem {
82 __be32 ip;
83 __be32 ip2;
84 __be16 port;
85 u8 cidr:7;
86 u8 nomatch:1;
87 u8 proto;
88 struct ip_set_counter counter;
89 unsigned long timeout;
90};
91
92/* Common functions */
93
76static inline bool 94static inline bool
77hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1, 95hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1,
78 const struct hash_ipportnet4_elem *ip2, 96 const struct hash_ipportnet4_elem *ip2,
@@ -85,38 +103,22 @@ hash_ipportnet4_data_equal(const struct hash_ipportnet4_elem *ip1,
85 ip1->proto == ip2->proto; 103 ip1->proto == ip2->proto;
86} 104}
87 105
88static inline bool 106static inline int
89hash_ipportnet4_data_isnull(const struct hash_ipportnet4_elem *elem) 107hash_ipportnet4_do_data_match(const struct hash_ipportnet4_elem *elem)
90{
91 return elem->proto == 0;
92}
93
94static inline void
95hash_ipportnet4_data_copy(struct hash_ipportnet4_elem *dst,
96 const struct hash_ipportnet4_elem *src)
97{ 108{
98 memcpy(dst, src, sizeof(*dst)); 109 return elem->nomatch ? -ENOTEMPTY : 1;
99} 110}
100 111
101static inline void 112static inline void
102hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags) 113hash_ipportnet4_data_set_flags(struct hash_ipportnet4_elem *elem, u32 flags)
103{ 114{
104 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); 115 elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
105} 116}
106 117
107static inline void 118static inline void
108hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *dst, u32 *flags) 119hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *elem, u8 *flags)
109{ 120{
110 if (dst->nomatch) { 121 swap(*flags, elem->nomatch);
111 *flags = IPSET_FLAG_NOMATCH;
112 dst->nomatch = 0;
113 }
114}
115
116static inline int
117hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem)
118{
119 return elem->nomatch ? -ENOTEMPTY : 1;
120} 122}
121 123
122static inline void 124static inline void
@@ -126,12 +128,6 @@ hash_ipportnet4_data_netmask(struct hash_ipportnet4_elem *elem, u8 cidr)
126 elem->cidr = cidr - 1; 128 elem->cidr = cidr - 1;
127} 129}
128 130
129static inline void
130hash_ipportnet4_data_zero_out(struct hash_ipportnet4_elem *elem)
131{
132 elem->proto = 0;
133}
134
135static bool 131static bool
136hash_ipportnet4_data_list(struct sk_buff *skb, 132hash_ipportnet4_data_list(struct sk_buff *skb,
137 const struct hash_ipportnet4_elem *data) 133 const struct hash_ipportnet4_elem *data)
@@ -152,81 +148,56 @@ nla_put_failure:
152 return 1; 148 return 1;
153} 149}
154 150
155static bool 151static inline void
156hash_ipportnet4_data_tlist(struct sk_buff *skb, 152hash_ipportnet4_data_next(struct hash_ipportnet4_elem *next,
157 const struct hash_ipportnet4_elem *data) 153 const struct hash_ipportnet4_elem *d)
158{ 154{
159 const struct hash_ipportnet4_telem *tdata = 155 next->ip = d->ip;
160 (const struct hash_ipportnet4_telem *)data; 156 next->port = d->port;
161 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0; 157 next->ip2 = d->ip2;
162
163 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
164 nla_put_ipaddr4(skb, IPSET_ATTR_IP2, tdata->ip2) ||
165 nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
166 nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
167 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
168 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
169 htonl(ip_set_timeout_get(tdata->timeout))) ||
170 (flags &&
171 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
172 goto nla_put_failure;
173 return 0;
174
175nla_put_failure:
176 return 1;
177} 158}
178 159
179#define IP_SET_HASH_WITH_PROTO 160#define MTYPE hash_ipportnet4
180#define IP_SET_HASH_WITH_NETS
181
182#define PF 4 161#define PF 4
183#define HOST_MASK 32 162#define HOST_MASK 32
184#include <linux/netfilter/ipset/ip_set_ahash.h> 163#include "ip_set_hash_gen.h"
185
186static inline void
187hash_ipportnet4_data_next(struct ip_set_hash *h,
188 const struct hash_ipportnet4_elem *d)
189{
190 h->next.ip = d->ip;
191 h->next.port = d->port;
192 h->next.ip2 = d->ip2;
193}
194 164
195static int 165static int
196hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb, 166hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
197 const struct xt_action_param *par, 167 const struct xt_action_param *par,
198 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 168 enum ipset_adt adt, struct ip_set_adt_opt *opt)
199{ 169{
200 const struct ip_set_hash *h = set->data; 170 const struct hash_ipportnet *h = set->data;
201 ipset_adtfn adtfn = set->variant->adt[adt]; 171 ipset_adtfn adtfn = set->variant->adt[adt];
202 struct hash_ipportnet4_elem data = { 172 struct hash_ipportnet4_elem e = {
203 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 173 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1
204 }; 174 };
175 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
205 176
206 if (adt == IPSET_TEST) 177 if (adt == IPSET_TEST)
207 data.cidr = HOST_MASK - 1; 178 e.cidr = HOST_MASK - 1;
208 179
209 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 180 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
210 &data.port, &data.proto)) 181 &e.port, &e.proto))
211 return -EINVAL; 182 return -EINVAL;
212 183
213 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); 184 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
214 ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2); 185 ip4addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip2);
215 data.ip2 &= ip_set_netmask(data.cidr + 1); 186 e.ip2 &= ip_set_netmask(e.cidr + 1);
216 187
217 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 188 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
218} 189}
219 190
220static int 191static int
221hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], 192hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
222 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 193 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
223{ 194{
224 const struct ip_set_hash *h = set->data; 195 const struct hash_ipportnet *h = set->data;
225 ipset_adtfn adtfn = set->variant->adt[adt]; 196 ipset_adtfn adtfn = set->variant->adt[adt];
226 struct hash_ipportnet4_elem data = { .cidr = HOST_MASK - 1 }; 197 struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
198 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
227 u32 ip, ip_to, p = 0, port, port_to; 199 u32 ip, ip_to, p = 0, port, port_to;
228 u32 ip2_from, ip2_to, ip2_last, ip2; 200 u32 ip2_from, ip2_to, ip2_last, ip2;
229 u32 timeout = h->timeout;
230 bool with_ports = false; 201 bool with_ports = false;
231 u8 cidr; 202 u8 cidr;
232 int ret; 203 int ret;
@@ -235,13 +206,16 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
235 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 206 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
236 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 207 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
237 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 208 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
238 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 209 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
210 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
211 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
239 return -IPSET_ERR_PROTOCOL; 212 return -IPSET_ERR_PROTOCOL;
240 213
241 if (tb[IPSET_ATTR_LINENO]) 214 if (tb[IPSET_ATTR_LINENO])
242 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 215 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
243 216
244 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 217 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
218 ip_set_get_extensions(set, tb, &ext);
245 if (ret) 219 if (ret)
246 return ret; 220 return ret;
247 221
@@ -253,46 +227,41 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
253 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]); 227 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
254 if (!cidr || cidr > HOST_MASK) 228 if (!cidr || cidr > HOST_MASK)
255 return -IPSET_ERR_INVALID_CIDR; 229 return -IPSET_ERR_INVALID_CIDR;
256 data.cidr = cidr - 1; 230 e.cidr = cidr - 1;
257 } 231 }
258 232
259 if (tb[IPSET_ATTR_PORT]) 233 if (tb[IPSET_ATTR_PORT])
260 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 234 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
261 else 235 else
262 return -IPSET_ERR_PROTOCOL; 236 return -IPSET_ERR_PROTOCOL;
263 237
264 if (tb[IPSET_ATTR_PROTO]) { 238 if (tb[IPSET_ATTR_PROTO]) {
265 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 239 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
266 with_ports = ip_set_proto_with_ports(data.proto); 240 with_ports = ip_set_proto_with_ports(e.proto);
267 241
268 if (data.proto == 0) 242 if (e.proto == 0)
269 return -IPSET_ERR_INVALID_PROTO; 243 return -IPSET_ERR_INVALID_PROTO;
270 } else 244 } else
271 return -IPSET_ERR_MISSING_PROTO; 245 return -IPSET_ERR_MISSING_PROTO;
272 246
273 if (!(with_ports || data.proto == IPPROTO_ICMP)) 247 if (!(with_ports || e.proto == IPPROTO_ICMP))
274 data.port = 0; 248 e.port = 0;
275
276 if (tb[IPSET_ATTR_TIMEOUT]) {
277 if (!with_timeout(h->timeout))
278 return -IPSET_ERR_TIMEOUT;
279 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
280 }
281 249
282 if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { 250 if (tb[IPSET_ATTR_CADT_FLAGS]) {
283 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 251 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
284 if (cadt_flags & IPSET_FLAG_NOMATCH) 252 if (cadt_flags & IPSET_FLAG_NOMATCH)
285 flags |= (cadt_flags << 16); 253 flags |= (IPSET_FLAG_NOMATCH << 16);
286 } 254 }
287 255
288 with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; 256 with_ports = with_ports && tb[IPSET_ATTR_PORT_TO];
289 if (adt == IPSET_TEST || 257 if (adt == IPSET_TEST ||
290 !(tb[IPSET_ATTR_CIDR] || tb[IPSET_ATTR_IP_TO] || with_ports || 258 !(tb[IPSET_ATTR_CIDR] || tb[IPSET_ATTR_IP_TO] || with_ports ||
291 tb[IPSET_ATTR_IP2_TO])) { 259 tb[IPSET_ATTR_IP2_TO])) {
292 data.ip = htonl(ip); 260 e.ip = htonl(ip);
293 data.ip2 = htonl(ip2_from & ip_set_hostmask(data.cidr + 1)); 261 e.ip2 = htonl(ip2_from & ip_set_hostmask(e.cidr + 1));
294 ret = adtfn(set, &data, timeout, flags); 262 ret = adtfn(set, &e, &ext, &ext, flags);
295 return ip_set_eexist(ret, flags) ? 0 : ret; 263 return ip_set_enomatch(ret, flags, adt) ? 1 :
264 ip_set_eexist(ret, flags) ? 0 : ret;
296 } 265 }
297 266
298 ip_to = ip; 267 ip_to = ip;
@@ -310,7 +279,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
310 ip_set_mask_from_to(ip, ip_to, cidr); 279 ip_set_mask_from_to(ip, ip_to, cidr);
311 } 280 }
312 281
313 port_to = port = ntohs(data.port); 282 port_to = port = ntohs(e.port);
314 if (tb[IPSET_ATTR_PORT_TO]) { 283 if (tb[IPSET_ATTR_PORT_TO]) {
315 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 284 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
316 if (port > port_to) 285 if (port > port_to)
@@ -326,28 +295,27 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
326 swap(ip2_from, ip2_to); 295 swap(ip2_from, ip2_to);
327 if (ip2_from + UINT_MAX == ip2_to) 296 if (ip2_from + UINT_MAX == ip2_to)
328 return -IPSET_ERR_HASH_RANGE; 297 return -IPSET_ERR_HASH_RANGE;
329 } else { 298 } else
330 ip_set_mask_from_to(ip2_from, ip2_to, data.cidr + 1); 299 ip_set_mask_from_to(ip2_from, ip2_to, e.cidr + 1);
331 }
332 300
333 if (retried) 301 if (retried)
334 ip = ntohl(h->next.ip); 302 ip = ntohl(h->next.ip);
335 for (; !before(ip_to, ip); ip++) { 303 for (; !before(ip_to, ip); ip++) {
336 data.ip = htonl(ip); 304 e.ip = htonl(ip);
337 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) 305 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
338 : port; 306 : port;
339 for (; p <= port_to; p++) { 307 for (; p <= port_to; p++) {
340 data.port = htons(p); 308 e.port = htons(p);
341 ip2 = retried 309 ip2 = retried
342 && ip == ntohl(h->next.ip) 310 && ip == ntohl(h->next.ip)
343 && p == ntohs(h->next.port) 311 && p == ntohs(h->next.port)
344 ? ntohl(h->next.ip2) : ip2_from; 312 ? ntohl(h->next.ip2) : ip2_from;
345 while (!after(ip2, ip2_to)) { 313 while (!after(ip2, ip2_to)) {
346 data.ip2 = htonl(ip2); 314 e.ip2 = htonl(ip2);
347 ip2_last = ip_set_range_to_cidr(ip2, ip2_to, 315 ip2_last = ip_set_range_to_cidr(ip2, ip2_to,
348 &cidr); 316 &cidr);
349 data.cidr = cidr - 1; 317 e.cidr = cidr - 1;
350 ret = adtfn(set, &data, timeout, flags); 318 ret = adtfn(set, &e, &ext, &ext, flags);
351 319
352 if (ret && !ip_set_eexist(ret, flags)) 320 if (ret && !ip_set_eexist(ret, flags))
353 return ret; 321 return ret;
@@ -360,38 +328,50 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
360 return ret; 328 return ret;
361} 329}
362 330
363static bool 331/* IPv6 variants */
364hash_ipportnet_same_set(const struct ip_set *a, const struct ip_set *b)
365{
366 const struct ip_set_hash *x = a->data;
367 const struct ip_set_hash *y = b->data;
368 332
369 /* Resizing changes htable_bits, so we ignore it */ 333struct hash_ipportnet6_elem {
370 return x->maxelem == y->maxelem && 334 union nf_inet_addr ip;
371 x->timeout == y->timeout; 335 union nf_inet_addr ip2;
372} 336 __be16 port;
337 u8 cidr:7;
338 u8 nomatch:1;
339 u8 proto;
340};
373 341
374/* The type variant functions: IPv6 */ 342struct hash_ipportnet6t_elem {
343 union nf_inet_addr ip;
344 union nf_inet_addr ip2;
345 __be16 port;
346 u8 cidr:7;
347 u8 nomatch:1;
348 u8 proto;
349 unsigned long timeout;
350};
375 351
376struct hash_ipportnet6_elem { 352struct hash_ipportnet6c_elem {
377 union nf_inet_addr ip; 353 union nf_inet_addr ip;
378 union nf_inet_addr ip2; 354 union nf_inet_addr ip2;
379 __be16 port; 355 __be16 port;
380 u8 cidr:7; 356 u8 cidr:7;
381 u8 nomatch:1; 357 u8 nomatch:1;
382 u8 proto; 358 u8 proto;
359 struct ip_set_counter counter;
383}; 360};
384 361
385struct hash_ipportnet6_telem { 362struct hash_ipportnet6ct_elem {
386 union nf_inet_addr ip; 363 union nf_inet_addr ip;
387 union nf_inet_addr ip2; 364 union nf_inet_addr ip2;
388 __be16 port; 365 __be16 port;
389 u8 cidr:7; 366 u8 cidr:7;
390 u8 nomatch:1; 367 u8 nomatch:1;
391 u8 proto; 368 u8 proto;
369 struct ip_set_counter counter;
392 unsigned long timeout; 370 unsigned long timeout;
393}; 371};
394 372
373/* Common functions */
374
395static inline bool 375static inline bool
396hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1, 376hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1,
397 const struct hash_ipportnet6_elem *ip2, 377 const struct hash_ipportnet6_elem *ip2,
@@ -404,53 +384,22 @@ hash_ipportnet6_data_equal(const struct hash_ipportnet6_elem *ip1,
404 ip1->proto == ip2->proto; 384 ip1->proto == ip2->proto;
405} 385}
406 386
407static inline bool
408hash_ipportnet6_data_isnull(const struct hash_ipportnet6_elem *elem)
409{
410 return elem->proto == 0;
411}
412
413static inline void
414hash_ipportnet6_data_copy(struct hash_ipportnet6_elem *dst,
415 const struct hash_ipportnet6_elem *src)
416{
417 memcpy(dst, src, sizeof(*dst));
418}
419
420static inline void
421hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags)
422{
423 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
424}
425
426static inline void
427hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *dst, u32 *flags)
428{
429 if (dst->nomatch) {
430 *flags = IPSET_FLAG_NOMATCH;
431 dst->nomatch = 0;
432 }
433}
434
435static inline int 387static inline int
436hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem) 388hash_ipportnet6_do_data_match(const struct hash_ipportnet6_elem *elem)
437{ 389{
438 return elem->nomatch ? -ENOTEMPTY : 1; 390 return elem->nomatch ? -ENOTEMPTY : 1;
439} 391}
440 392
441static inline void 393static inline void
442hash_ipportnet6_data_zero_out(struct hash_ipportnet6_elem *elem) 394hash_ipportnet6_data_set_flags(struct hash_ipportnet6_elem *elem, u32 flags)
443{ 395{
444 elem->proto = 0; 396 elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
445} 397}
446 398
447static inline void 399static inline void
448ip6_netmask(union nf_inet_addr *ip, u8 prefix) 400hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *elem, u8 *flags)
449{ 401{
450 ip->ip6[0] &= ip_set_netmask6(prefix)[0]; 402 swap(*flags, elem->nomatch);
451 ip->ip6[1] &= ip_set_netmask6(prefix)[1];
452 ip->ip6[2] &= ip_set_netmask6(prefix)[2];
453 ip->ip6[3] &= ip_set_netmask6(prefix)[3];
454} 403}
455 404
456static inline void 405static inline void
@@ -480,78 +429,58 @@ nla_put_failure:
480 return 1; 429 return 1;
481} 430}
482 431
483static bool 432static inline void
484hash_ipportnet6_data_tlist(struct sk_buff *skb, 433hash_ipportnet6_data_next(struct hash_ipportnet4_elem *next,
485 const struct hash_ipportnet6_elem *data) 434 const struct hash_ipportnet6_elem *d)
486{ 435{
487 const struct hash_ipportnet6_telem *e = 436 next->port = d->port;
488 (const struct hash_ipportnet6_telem *)data;
489 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
490
491 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
492 nla_put_ipaddr6(skb, IPSET_ATTR_IP2, &data->ip2.in6) ||
493 nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
494 nla_put_u8(skb, IPSET_ATTR_CIDR2, data->cidr + 1) ||
495 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
496 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
497 htonl(ip_set_timeout_get(e->timeout))) ||
498 (flags &&
499 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
500 goto nla_put_failure;
501 return 0;
502
503nla_put_failure:
504 return 1;
505} 437}
506 438
439#undef MTYPE
507#undef PF 440#undef PF
508#undef HOST_MASK 441#undef HOST_MASK
509 442
443#define MTYPE hash_ipportnet6
510#define PF 6 444#define PF 6
511#define HOST_MASK 128 445#define HOST_MASK 128
512#include <linux/netfilter/ipset/ip_set_ahash.h> 446#define IP_SET_EMIT_CREATE
513 447#include "ip_set_hash_gen.h"
514static inline void
515hash_ipportnet6_data_next(struct ip_set_hash *h,
516 const struct hash_ipportnet6_elem *d)
517{
518 h->next.port = d->port;
519}
520 448
521static int 449static int
522hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb, 450hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
523 const struct xt_action_param *par, 451 const struct xt_action_param *par,
524 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 452 enum ipset_adt adt, struct ip_set_adt_opt *opt)
525{ 453{
526 const struct ip_set_hash *h = set->data; 454 const struct hash_ipportnet *h = set->data;
527 ipset_adtfn adtfn = set->variant->adt[adt]; 455 ipset_adtfn adtfn = set->variant->adt[adt];
528 struct hash_ipportnet6_elem data = { 456 struct hash_ipportnet6_elem e = {
529 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 457 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1
530 }; 458 };
459 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
531 460
532 if (adt == IPSET_TEST) 461 if (adt == IPSET_TEST)
533 data.cidr = HOST_MASK - 1; 462 e.cidr = HOST_MASK - 1;
534 463
535 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 464 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
536 &data.port, &data.proto)) 465 &e.port, &e.proto))
537 return -EINVAL; 466 return -EINVAL;
538 467
539 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); 468 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
540 ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &data.ip2.in6); 469 ip6addrptr(skb, opt->flags & IPSET_DIM_THREE_SRC, &e.ip2.in6);
541 ip6_netmask(&data.ip2, data.cidr + 1); 470 ip6_netmask(&e.ip2, e.cidr + 1);
542 471
543 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 472 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
544} 473}
545 474
546static int 475static int
547hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], 476hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
548 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 477 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
549{ 478{
550 const struct ip_set_hash *h = set->data; 479 const struct hash_ipportnet *h = set->data;
551 ipset_adtfn adtfn = set->variant->adt[adt]; 480 ipset_adtfn adtfn = set->variant->adt[adt];
552 struct hash_ipportnet6_elem data = { .cidr = HOST_MASK - 1 }; 481 struct hash_ipportnet6_elem e = { .cidr = HOST_MASK - 1 };
482 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
553 u32 port, port_to; 483 u32 port, port_to;
554 u32 timeout = h->timeout;
555 bool with_ports = false; 484 bool with_ports = false;
556 u8 cidr; 485 u8 cidr;
557 int ret; 486 int ret;
@@ -561,6 +490,8 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
561 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 490 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
562 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 491 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
563 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) || 492 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
493 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
494 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
564 tb[IPSET_ATTR_IP_TO] || 495 tb[IPSET_ATTR_IP_TO] ||
565 tb[IPSET_ATTR_CIDR])) 496 tb[IPSET_ATTR_CIDR]))
566 return -IPSET_ERR_PROTOCOL; 497 return -IPSET_ERR_PROTOCOL;
@@ -570,11 +501,12 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
570 if (tb[IPSET_ATTR_LINENO]) 501 if (tb[IPSET_ATTR_LINENO])
571 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 502 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
572 503
573 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); 504 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
505 ip_set_get_extensions(set, tb, &ext);
574 if (ret) 506 if (ret)
575 return ret; 507 return ret;
576 508
577 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &data.ip2); 509 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP2], &e.ip2);
578 if (ret) 510 if (ret)
579 return ret; 511 return ret;
580 512
@@ -582,46 +514,41 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
582 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]); 514 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR2]);
583 if (!cidr || cidr > HOST_MASK) 515 if (!cidr || cidr > HOST_MASK)
584 return -IPSET_ERR_INVALID_CIDR; 516 return -IPSET_ERR_INVALID_CIDR;
585 data.cidr = cidr - 1; 517 e.cidr = cidr - 1;
586 } 518 }
587 519
588 ip6_netmask(&data.ip2, data.cidr + 1); 520 ip6_netmask(&e.ip2, e.cidr + 1);
589 521
590 if (tb[IPSET_ATTR_PORT]) 522 if (tb[IPSET_ATTR_PORT])
591 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 523 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
592 else 524 else
593 return -IPSET_ERR_PROTOCOL; 525 return -IPSET_ERR_PROTOCOL;
594 526
595 if (tb[IPSET_ATTR_PROTO]) { 527 if (tb[IPSET_ATTR_PROTO]) {
596 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 528 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
597 with_ports = ip_set_proto_with_ports(data.proto); 529 with_ports = ip_set_proto_with_ports(e.proto);
598 530
599 if (data.proto == 0) 531 if (e.proto == 0)
600 return -IPSET_ERR_INVALID_PROTO; 532 return -IPSET_ERR_INVALID_PROTO;
601 } else 533 } else
602 return -IPSET_ERR_MISSING_PROTO; 534 return -IPSET_ERR_MISSING_PROTO;
603 535
604 if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 536 if (!(with_ports || e.proto == IPPROTO_ICMPV6))
605 data.port = 0; 537 e.port = 0;
606
607 if (tb[IPSET_ATTR_TIMEOUT]) {
608 if (!with_timeout(h->timeout))
609 return -IPSET_ERR_TIMEOUT;
610 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
611 }
612 538
613 if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { 539 if (tb[IPSET_ATTR_CADT_FLAGS]) {
614 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 540 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
615 if (cadt_flags & IPSET_FLAG_NOMATCH) 541 if (cadt_flags & IPSET_FLAG_NOMATCH)
616 flags |= (cadt_flags << 16); 542 flags |= (IPSET_FLAG_NOMATCH << 16);
617 } 543 }
618 544
619 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 545 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
620 ret = adtfn(set, &data, timeout, flags); 546 ret = adtfn(set, &e, &ext, &ext, flags);
621 return ip_set_eexist(ret, flags) ? 0 : ret; 547 return ip_set_enomatch(ret, flags, adt) ? 1 :
548 ip_set_eexist(ret, flags) ? 0 : ret;
622 } 549 }
623 550
624 port = ntohs(data.port); 551 port = ntohs(e.port);
625 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 552 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
626 if (port > port_to) 553 if (port > port_to)
627 swap(port, port_to); 554 swap(port, port_to);
@@ -629,8 +556,8 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
629 if (retried) 556 if (retried)
630 port = ntohs(h->next.port); 557 port = ntohs(h->next.port);
631 for (; port <= port_to; port++) { 558 for (; port <= port_to; port++) {
632 data.port = htons(port); 559 e.port = htons(port);
633 ret = adtfn(set, &data, timeout, flags); 560 ret = adtfn(set, &e, &ext, &ext, flags);
634 561
635 if (ret && !ip_set_eexist(ret, flags)) 562 if (ret && !ip_set_eexist(ret, flags))
636 return ret; 563 return ret;
@@ -640,81 +567,6 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
640 return ret; 567 return ret;
641} 568}
642 569
643/* Create hash:ip type of sets */
644
645static int
646hash_ipportnet_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
647{
648 struct ip_set_hash *h;
649 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
650 u8 hbits;
651 size_t hsize;
652
653 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
654 return -IPSET_ERR_INVALID_FAMILY;
655
656 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
657 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
658 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
659 return -IPSET_ERR_PROTOCOL;
660
661 if (tb[IPSET_ATTR_HASHSIZE]) {
662 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
663 if (hashsize < IPSET_MIMINAL_HASHSIZE)
664 hashsize = IPSET_MIMINAL_HASHSIZE;
665 }
666
667 if (tb[IPSET_ATTR_MAXELEM])
668 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
669
670 h = kzalloc(sizeof(*h)
671 + sizeof(struct ip_set_hash_nets)
672 * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
673 if (!h)
674 return -ENOMEM;
675
676 h->maxelem = maxelem;
677 get_random_bytes(&h->initval, sizeof(h->initval));
678 h->timeout = IPSET_NO_TIMEOUT;
679
680 hbits = htable_bits(hashsize);
681 hsize = htable_size(hbits);
682 if (hsize == 0) {
683 kfree(h);
684 return -ENOMEM;
685 }
686 h->table = ip_set_alloc(hsize);
687 if (!h->table) {
688 kfree(h);
689 return -ENOMEM;
690 }
691 h->table->htable_bits = hbits;
692
693 set->data = h;
694
695 if (tb[IPSET_ATTR_TIMEOUT]) {
696 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
697
698 set->variant = set->family == NFPROTO_IPV4
699 ? &hash_ipportnet4_tvariant
700 : &hash_ipportnet6_tvariant;
701
702 if (set->family == NFPROTO_IPV4)
703 hash_ipportnet4_gc_init(set);
704 else
705 hash_ipportnet6_gc_init(set);
706 } else {
707 set->variant = set->family == NFPROTO_IPV4
708 ? &hash_ipportnet4_variant : &hash_ipportnet6_variant;
709 }
710
711 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
712 set->name, jhash_size(h->table->htable_bits),
713 h->table->htable_bits, h->maxelem, set->data, h->table);
714
715 return 0;
716}
717
718static struct ip_set_type hash_ipportnet_type __read_mostly = { 570static struct ip_set_type hash_ipportnet_type __read_mostly = {
719 .name = "hash:ip,port,net", 571 .name = "hash:ip,port,net",
720 .protocol = IPSET_PROTOCOL, 572 .protocol = IPSET_PROTOCOL,
@@ -731,6 +583,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
731 [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, 583 [IPSET_ATTR_PROBES] = { .type = NLA_U8 },
732 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 584 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
733 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 585 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
586 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
734 }, 587 },
735 .adt_policy = { 588 .adt_policy = {
736 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 589 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -745,6 +598,8 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
745 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 598 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
746 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 599 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
747 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 600 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
601 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
602 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
748 }, 603 },
749 .me = THIS_MODULE, 604 .me = THIS_MODULE,
750}; 605};
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index d6a59154d710..da740ceb56ae 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -20,12 +20,12 @@
20#include <linux/netfilter.h> 20#include <linux/netfilter.h>
21#include <linux/netfilter/ipset/pfxlen.h> 21#include <linux/netfilter/ipset/pfxlen.h>
22#include <linux/netfilter/ipset/ip_set.h> 22#include <linux/netfilter/ipset/ip_set.h>
23#include <linux/netfilter/ipset/ip_set_timeout.h>
24#include <linux/netfilter/ipset/ip_set_hash.h> 23#include <linux/netfilter/ipset/ip_set_hash.h>
25 24
26#define REVISION_MIN 0 25#define REVISION_MIN 0
27/* 1 Range as input support for IPv4 added */ 26/* 1 Range as input support for IPv4 added */
28#define REVISION_MAX 2 /* nomatch flag support added */ 27/* 2 nomatch flag support added */
28#define REVISION_MAX 3 /* Counters support added */
29 29
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 31MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -33,33 +33,46 @@ IP_SET_MODULE_DESC("hash:net", REVISION_MIN, REVISION_MAX);
33MODULE_ALIAS("ip_set_hash:net"); 33MODULE_ALIAS("ip_set_hash:net");
34 34
35/* Type specific function prefix */ 35/* Type specific function prefix */
36#define TYPE hash_net 36#define HTYPE hash_net
37#define IP_SET_HASH_WITH_NETS
37 38
38static bool 39/* IPv4 variants */
39hash_net_same_set(const struct ip_set *a, const struct ip_set *b);
40 40
41#define hash_net4_same_set hash_net_same_set 41/* Member elements */
42#define hash_net6_same_set hash_net_same_set 42struct hash_net4_elem {
43 __be32 ip;
44 u16 padding0;
45 u8 nomatch;
46 u8 cidr;
47};
43 48
44/* The type variant functions: IPv4 */ 49struct hash_net4t_elem {
50 __be32 ip;
51 u16 padding0;
52 u8 nomatch;
53 u8 cidr;
54 unsigned long timeout;
55};
45 56
46/* Member elements without timeout */ 57struct hash_net4c_elem {
47struct hash_net4_elem {
48 __be32 ip; 58 __be32 ip;
49 u16 padding0; 59 u16 padding0;
50 u8 nomatch; 60 u8 nomatch;
51 u8 cidr; 61 u8 cidr;
62 struct ip_set_counter counter;
52}; 63};
53 64
54/* Member elements with timeout support */ 65struct hash_net4ct_elem {
55struct hash_net4_telem {
56 __be32 ip; 66 __be32 ip;
57 u16 padding0; 67 u16 padding0;
58 u8 nomatch; 68 u8 nomatch;
59 u8 cidr; 69 u8 cidr;
70 struct ip_set_counter counter;
60 unsigned long timeout; 71 unsigned long timeout;
61}; 72};
62 73
74/* Common functions */
75
63static inline bool 76static inline bool
64hash_net4_data_equal(const struct hash_net4_elem *ip1, 77hash_net4_data_equal(const struct hash_net4_elem *ip1,
65 const struct hash_net4_elem *ip2, 78 const struct hash_net4_elem *ip2,
@@ -69,40 +82,22 @@ hash_net4_data_equal(const struct hash_net4_elem *ip1,
69 ip1->cidr == ip2->cidr; 82 ip1->cidr == ip2->cidr;
70} 83}
71 84
72static inline bool 85static inline int
73hash_net4_data_isnull(const struct hash_net4_elem *elem) 86hash_net4_do_data_match(const struct hash_net4_elem *elem)
74{
75 return elem->cidr == 0;
76}
77
78static inline void
79hash_net4_data_copy(struct hash_net4_elem *dst,
80 const struct hash_net4_elem *src)
81{ 87{
82 dst->ip = src->ip; 88 return elem->nomatch ? -ENOTEMPTY : 1;
83 dst->cidr = src->cidr;
84 dst->nomatch = src->nomatch;
85} 89}
86 90
87static inline void 91static inline void
88hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags) 92hash_net4_data_set_flags(struct hash_net4_elem *elem, u32 flags)
89{ 93{
90 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); 94 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
91} 95}
92 96
93static inline void 97static inline void
94hash_net4_data_reset_flags(struct hash_net4_elem *dst, u32 *flags) 98hash_net4_data_reset_flags(struct hash_net4_elem *elem, u8 *flags)
95{ 99{
96 if (dst->nomatch) { 100 swap(*flags, elem->nomatch);
97 *flags = IPSET_FLAG_NOMATCH;
98 dst->nomatch = 0;
99 }
100}
101
102static inline int
103hash_net4_data_match(const struct hash_net4_elem *elem)
104{
105 return elem->nomatch ? -ENOTEMPTY : 1;
106} 101}
107 102
108static inline void 103static inline void
@@ -112,13 +107,6 @@ hash_net4_data_netmask(struct hash_net4_elem *elem, u8 cidr)
112 elem->cidr = cidr; 107 elem->cidr = cidr;
113} 108}
114 109
115/* Zero CIDR values cannot be stored */
116static inline void
117hash_net4_data_zero_out(struct hash_net4_elem *elem)
118{
119 elem->cidr = 0;
120}
121
122static bool 110static bool
123hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data) 111hash_net4_data_list(struct sk_buff *skb, const struct hash_net4_elem *data)
124{ 112{
@@ -135,106 +123,84 @@ nla_put_failure:
135 return 1; 123 return 1;
136} 124}
137 125
138static bool 126static inline void
139hash_net4_data_tlist(struct sk_buff *skb, const struct hash_net4_elem *data) 127hash_net4_data_next(struct hash_net4_elem *next,
128 const struct hash_net4_elem *d)
140{ 129{
141 const struct hash_net4_telem *tdata = 130 next->ip = d->ip;
142 (const struct hash_net4_telem *)data;
143 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
144
145 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
146 nla_put_u8(skb, IPSET_ATTR_CIDR, tdata->cidr) ||
147 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
148 htonl(ip_set_timeout_get(tdata->timeout))) ||
149 (flags &&
150 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
151 goto nla_put_failure;
152 return 0;
153
154nla_put_failure:
155 return 1;
156} 131}
157 132
158#define IP_SET_HASH_WITH_NETS 133#define MTYPE hash_net4
159
160#define PF 4 134#define PF 4
161#define HOST_MASK 32 135#define HOST_MASK 32
162#include <linux/netfilter/ipset/ip_set_ahash.h> 136#include "ip_set_hash_gen.h"
163
164static inline void
165hash_net4_data_next(struct ip_set_hash *h,
166 const struct hash_net4_elem *d)
167{
168 h->next.ip = d->ip;
169}
170 137
171static int 138static int
172hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb, 139hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
173 const struct xt_action_param *par, 140 const struct xt_action_param *par,
174 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 141 enum ipset_adt adt, struct ip_set_adt_opt *opt)
175{ 142{
176 const struct ip_set_hash *h = set->data; 143 const struct hash_net *h = set->data;
177 ipset_adtfn adtfn = set->variant->adt[adt]; 144 ipset_adtfn adtfn = set->variant->adt[adt];
178 struct hash_net4_elem data = { 145 struct hash_net4_elem e = {
179 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK 146 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
180 }; 147 };
148 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
181 149
182 if (data.cidr == 0) 150 if (e.cidr == 0)
183 return -EINVAL; 151 return -EINVAL;
184 if (adt == IPSET_TEST) 152 if (adt == IPSET_TEST)
185 data.cidr = HOST_MASK; 153 e.cidr = HOST_MASK;
186 154
187 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); 155 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
188 data.ip &= ip_set_netmask(data.cidr); 156 e.ip &= ip_set_netmask(e.cidr);
189 157
190 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 158 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
191} 159}
192 160
193static int 161static int
194hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], 162hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
195 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 163 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
196{ 164{
197 const struct ip_set_hash *h = set->data; 165 const struct hash_net *h = set->data;
198 ipset_adtfn adtfn = set->variant->adt[adt]; 166 ipset_adtfn adtfn = set->variant->adt[adt];
199 struct hash_net4_elem data = { .cidr = HOST_MASK }; 167 struct hash_net4_elem e = { .cidr = HOST_MASK };
200 u32 timeout = h->timeout; 168 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
201 u32 ip = 0, ip_to, last; 169 u32 ip = 0, ip_to, last;
202 int ret; 170 int ret;
203 171
204 if (unlikely(!tb[IPSET_ATTR_IP] || 172 if (unlikely(!tb[IPSET_ATTR_IP] ||
205 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 173 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
206 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 174 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
175 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
176 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
207 return -IPSET_ERR_PROTOCOL; 177 return -IPSET_ERR_PROTOCOL;
208 178
209 if (tb[IPSET_ATTR_LINENO]) 179 if (tb[IPSET_ATTR_LINENO])
210 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 180 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
211 181
212 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 182 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
183 ip_set_get_extensions(set, tb, &ext);
213 if (ret) 184 if (ret)
214 return ret; 185 return ret;
215 186
216 if (tb[IPSET_ATTR_CIDR]) { 187 if (tb[IPSET_ATTR_CIDR]) {
217 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 188 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
218 if (!data.cidr || data.cidr > HOST_MASK) 189 if (!e.cidr || e.cidr > HOST_MASK)
219 return -IPSET_ERR_INVALID_CIDR; 190 return -IPSET_ERR_INVALID_CIDR;
220 } 191 }
221 192
222 if (tb[IPSET_ATTR_TIMEOUT]) { 193 if (tb[IPSET_ATTR_CADT_FLAGS]) {
223 if (!with_timeout(h->timeout))
224 return -IPSET_ERR_TIMEOUT;
225 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
226 }
227
228 if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
229 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 194 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
230 if (cadt_flags & IPSET_FLAG_NOMATCH) 195 if (cadt_flags & IPSET_FLAG_NOMATCH)
231 flags |= (cadt_flags << 16); 196 flags |= (IPSET_FLAG_NOMATCH << 16);
232 } 197 }
233 198
234 if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { 199 if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
235 data.ip = htonl(ip & ip_set_hostmask(data.cidr)); 200 e.ip = htonl(ip & ip_set_hostmask(e.cidr));
236 ret = adtfn(set, &data, timeout, flags); 201 ret = adtfn(set, &e, &ext, &ext, flags);
237 return ip_set_eexist(ret, flags) ? 0 : ret; 202 return ip_set_enomatch(ret, flags, adt) ? 1 :
203 ip_set_eexist(ret, flags) ? 0 : ret;
238 } 204 }
239 205
240 ip_to = ip; 206 ip_to = ip;
@@ -250,9 +216,9 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
250 if (retried) 216 if (retried)
251 ip = ntohl(h->next.ip); 217 ip = ntohl(h->next.ip);
252 while (!after(ip, ip_to)) { 218 while (!after(ip, ip_to)) {
253 data.ip = htonl(ip); 219 e.ip = htonl(ip);
254 last = ip_set_range_to_cidr(ip, ip_to, &data.cidr); 220 last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
255 ret = adtfn(set, &data, timeout, flags); 221 ret = adtfn(set, &e, &ext, &ext, flags);
256 if (ret && !ip_set_eexist(ret, flags)) 222 if (ret && !ip_set_eexist(ret, flags))
257 return ret; 223 return ret;
258 else 224 else
@@ -262,34 +228,42 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
262 return ret; 228 return ret;
263} 229}
264 230
265static bool 231/* IPv6 variants */
266hash_net_same_set(const struct ip_set *a, const struct ip_set *b)
267{
268 const struct ip_set_hash *x = a->data;
269 const struct ip_set_hash *y = b->data;
270 232
271 /* Resizing changes htable_bits, so we ignore it */ 233struct hash_net6_elem {
272 return x->maxelem == y->maxelem && 234 union nf_inet_addr ip;
273 x->timeout == y->timeout; 235 u16 padding0;
274} 236 u8 nomatch;
237 u8 cidr;
238};
275 239
276/* The type variant functions: IPv6 */ 240struct hash_net6t_elem {
241 union nf_inet_addr ip;
242 u16 padding0;
243 u8 nomatch;
244 u8 cidr;
245 unsigned long timeout;
246};
277 247
278struct hash_net6_elem { 248struct hash_net6c_elem {
279 union nf_inet_addr ip; 249 union nf_inet_addr ip;
280 u16 padding0; 250 u16 padding0;
281 u8 nomatch; 251 u8 nomatch;
282 u8 cidr; 252 u8 cidr;
253 struct ip_set_counter counter;
283}; 254};
284 255
285struct hash_net6_telem { 256struct hash_net6ct_elem {
286 union nf_inet_addr ip; 257 union nf_inet_addr ip;
287 u16 padding0; 258 u16 padding0;
288 u8 nomatch; 259 u8 nomatch;
289 u8 cidr; 260 u8 cidr;
261 struct ip_set_counter counter;
290 unsigned long timeout; 262 unsigned long timeout;
291}; 263};
292 264
265/* Common functions */
266
293static inline bool 267static inline bool
294hash_net6_data_equal(const struct hash_net6_elem *ip1, 268hash_net6_data_equal(const struct hash_net6_elem *ip1,
295 const struct hash_net6_elem *ip2, 269 const struct hash_net6_elem *ip2,
@@ -299,55 +273,22 @@ hash_net6_data_equal(const struct hash_net6_elem *ip1,
299 ip1->cidr == ip2->cidr; 273 ip1->cidr == ip2->cidr;
300} 274}
301 275
302static inline bool
303hash_net6_data_isnull(const struct hash_net6_elem *elem)
304{
305 return elem->cidr == 0;
306}
307
308static inline void
309hash_net6_data_copy(struct hash_net6_elem *dst,
310 const struct hash_net6_elem *src)
311{
312 dst->ip.in6 = src->ip.in6;
313 dst->cidr = src->cidr;
314 dst->nomatch = src->nomatch;
315}
316
317static inline void
318hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags)
319{
320 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
321}
322
323static inline void
324hash_net6_data_reset_flags(struct hash_net6_elem *dst, u32 *flags)
325{
326 if (dst->nomatch) {
327 *flags = IPSET_FLAG_NOMATCH;
328 dst->nomatch = 0;
329 }
330}
331
332static inline int 276static inline int
333hash_net6_data_match(const struct hash_net6_elem *elem) 277hash_net6_do_data_match(const struct hash_net6_elem *elem)
334{ 278{
335 return elem->nomatch ? -ENOTEMPTY : 1; 279 return elem->nomatch ? -ENOTEMPTY : 1;
336} 280}
337 281
338static inline void 282static inline void
339hash_net6_data_zero_out(struct hash_net6_elem *elem) 283hash_net6_data_set_flags(struct hash_net6_elem *elem, u32 flags)
340{ 284{
341 elem->cidr = 0; 285 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
342} 286}
343 287
344static inline void 288static inline void
345ip6_netmask(union nf_inet_addr *ip, u8 prefix) 289hash_net6_data_reset_flags(struct hash_net6_elem *elem, u8 *flags)
346{ 290{
347 ip->ip6[0] &= ip_set_netmask6(prefix)[0]; 291 swap(*flags, elem->nomatch);
348 ip->ip6[1] &= ip_set_netmask6(prefix)[1];
349 ip->ip6[2] &= ip_set_netmask6(prefix)[2];
350 ip->ip6[3] &= ip_set_netmask6(prefix)[3];
351} 292}
352 293
353static inline void 294static inline void
@@ -373,74 +314,60 @@ nla_put_failure:
373 return 1; 314 return 1;
374} 315}
375 316
376static bool 317static inline void
377hash_net6_data_tlist(struct sk_buff *skb, const struct hash_net6_elem *data) 318hash_net6_data_next(struct hash_net4_elem *next,
319 const struct hash_net6_elem *d)
378{ 320{
379 const struct hash_net6_telem *e =
380 (const struct hash_net6_telem *)data;
381 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
382
383 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
384 nla_put_u8(skb, IPSET_ATTR_CIDR, e->cidr) ||
385 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
386 htonl(ip_set_timeout_get(e->timeout))) ||
387 (flags &&
388 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
389 goto nla_put_failure;
390 return 0;
391
392nla_put_failure:
393 return 1;
394} 321}
395 322
323#undef MTYPE
396#undef PF 324#undef PF
397#undef HOST_MASK 325#undef HOST_MASK
398 326
327#define MTYPE hash_net6
399#define PF 6 328#define PF 6
400#define HOST_MASK 128 329#define HOST_MASK 128
401#include <linux/netfilter/ipset/ip_set_ahash.h> 330#define IP_SET_EMIT_CREATE
402 331#include "ip_set_hash_gen.h"
403static inline void
404hash_net6_data_next(struct ip_set_hash *h,
405 const struct hash_net6_elem *d)
406{
407}
408 332
409static int 333static int
410hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb, 334hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
411 const struct xt_action_param *par, 335 const struct xt_action_param *par,
412 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 336 enum ipset_adt adt, struct ip_set_adt_opt *opt)
413{ 337{
414 const struct ip_set_hash *h = set->data; 338 const struct hash_net *h = set->data;
415 ipset_adtfn adtfn = set->variant->adt[adt]; 339 ipset_adtfn adtfn = set->variant->adt[adt];
416 struct hash_net6_elem data = { 340 struct hash_net6_elem e = {
417 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK 341 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK
418 }; 342 };
343 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
419 344
420 if (data.cidr == 0) 345 if (e.cidr == 0)
421 return -EINVAL; 346 return -EINVAL;
422 if (adt == IPSET_TEST) 347 if (adt == IPSET_TEST)
423 data.cidr = HOST_MASK; 348 e.cidr = HOST_MASK;
424 349
425 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); 350 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
426 ip6_netmask(&data.ip, data.cidr); 351 ip6_netmask(&e.ip, e.cidr);
427 352
428 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 353 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
429} 354}
430 355
431static int 356static int
432hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], 357hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
433 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 358 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
434{ 359{
435 const struct ip_set_hash *h = set->data; 360 const struct hash_net *h = set->data;
436 ipset_adtfn adtfn = set->variant->adt[adt]; 361 ipset_adtfn adtfn = set->variant->adt[adt];
437 struct hash_net6_elem data = { .cidr = HOST_MASK }; 362 struct hash_net6_elem e = { .cidr = HOST_MASK };
438 u32 timeout = h->timeout; 363 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
439 int ret; 364 int ret;
440 365
441 if (unlikely(!tb[IPSET_ATTR_IP] || 366 if (unlikely(!tb[IPSET_ATTR_IP] ||
442 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 367 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
443 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 368 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
369 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
370 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
444 return -IPSET_ERR_PROTOCOL; 371 return -IPSET_ERR_PROTOCOL;
445 if (unlikely(tb[IPSET_ATTR_IP_TO])) 372 if (unlikely(tb[IPSET_ATTR_IP_TO]))
446 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; 373 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
@@ -448,107 +375,29 @@ hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
448 if (tb[IPSET_ATTR_LINENO]) 375 if (tb[IPSET_ATTR_LINENO])
449 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 376 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
450 377
451 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); 378 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
379 ip_set_get_extensions(set, tb, &ext);
452 if (ret) 380 if (ret)
453 return ret; 381 return ret;
454 382
455 if (tb[IPSET_ATTR_CIDR]) 383 if (tb[IPSET_ATTR_CIDR])
456 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 384 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
457 385
458 if (!data.cidr || data.cidr > HOST_MASK) 386 if (!e.cidr || e.cidr > HOST_MASK)
459 return -IPSET_ERR_INVALID_CIDR; 387 return -IPSET_ERR_INVALID_CIDR;
460 388
461 ip6_netmask(&data.ip, data.cidr); 389 ip6_netmask(&e.ip, e.cidr);
462 390
463 if (tb[IPSET_ATTR_TIMEOUT]) { 391 if (tb[IPSET_ATTR_CADT_FLAGS]) {
464 if (!with_timeout(h->timeout))
465 return -IPSET_ERR_TIMEOUT;
466 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
467 }
468
469 if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
470 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 392 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
471 if (cadt_flags & IPSET_FLAG_NOMATCH) 393 if (cadt_flags & IPSET_FLAG_NOMATCH)
472 flags |= (cadt_flags << 16); 394 flags |= (IPSET_FLAG_NOMATCH << 16);
473 } 395 }
474 396
475 ret = adtfn(set, &data, timeout, flags); 397 ret = adtfn(set, &e, &ext, &ext, flags);
476 398
477 return ip_set_eexist(ret, flags) ? 0 : ret; 399 return ip_set_enomatch(ret, flags, adt) ? 1 :
478} 400 ip_set_eexist(ret, flags) ? 0 : ret;
479
480/* Create hash:ip type of sets */
481
482static int
483hash_net_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
484{
485 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
486 struct ip_set_hash *h;
487 u8 hbits;
488 size_t hsize;
489
490 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
491 return -IPSET_ERR_INVALID_FAMILY;
492
493 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
494 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
495 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
496 return -IPSET_ERR_PROTOCOL;
497
498 if (tb[IPSET_ATTR_HASHSIZE]) {
499 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
500 if (hashsize < IPSET_MIMINAL_HASHSIZE)
501 hashsize = IPSET_MIMINAL_HASHSIZE;
502 }
503
504 if (tb[IPSET_ATTR_MAXELEM])
505 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
506
507 h = kzalloc(sizeof(*h)
508 + sizeof(struct ip_set_hash_nets)
509 * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
510 if (!h)
511 return -ENOMEM;
512
513 h->maxelem = maxelem;
514 get_random_bytes(&h->initval, sizeof(h->initval));
515 h->timeout = IPSET_NO_TIMEOUT;
516
517 hbits = htable_bits(hashsize);
518 hsize = htable_size(hbits);
519 if (hsize == 0) {
520 kfree(h);
521 return -ENOMEM;
522 }
523 h->table = ip_set_alloc(hsize);
524 if (!h->table) {
525 kfree(h);
526 return -ENOMEM;
527 }
528 h->table->htable_bits = hbits;
529
530 set->data = h;
531
532 if (tb[IPSET_ATTR_TIMEOUT]) {
533 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
534
535 set->variant = set->family == NFPROTO_IPV4
536 ? &hash_net4_tvariant : &hash_net6_tvariant;
537
538 if (set->family == NFPROTO_IPV4)
539 hash_net4_gc_init(set);
540 else
541 hash_net6_gc_init(set);
542 } else {
543 set->variant = set->family == NFPROTO_IPV4
544 ? &hash_net4_variant : &hash_net6_variant;
545 }
546
547 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
548 set->name, jhash_size(h->table->htable_bits),
549 h->table->htable_bits, h->maxelem, set->data, h->table);
550
551 return 0;
552} 401}
553 402
554static struct ip_set_type hash_net_type __read_mostly = { 403static struct ip_set_type hash_net_type __read_mostly = {
@@ -566,6 +415,7 @@ static struct ip_set_type hash_net_type __read_mostly = {
566 [IPSET_ATTR_PROBES] = { .type = NLA_U8 }, 415 [IPSET_ATTR_PROBES] = { .type = NLA_U8 },
567 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 416 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
568 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 417 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
418 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
569 }, 419 },
570 .adt_policy = { 420 .adt_policy = {
571 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 421 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -573,6 +423,8 @@ static struct ip_set_type hash_net_type __read_mostly = {
573 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 423 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
574 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 424 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
575 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 425 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
426 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
427 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
576 }, 428 },
577 .me = THIS_MODULE, 429 .me = THIS_MODULE,
578}; 430};
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index f2b0a3c30130..84ae6f6ce624 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2011-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -21,12 +21,12 @@
21#include <linux/netfilter.h> 21#include <linux/netfilter.h>
22#include <linux/netfilter/ipset/pfxlen.h> 22#include <linux/netfilter/ipset/pfxlen.h>
23#include <linux/netfilter/ipset/ip_set.h> 23#include <linux/netfilter/ipset/ip_set.h>
24#include <linux/netfilter/ipset/ip_set_timeout.h>
25#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
26 25
27#define REVISION_MIN 0 26#define REVISION_MIN 0
28/* 1 nomatch flag support added */ 27/* 1 nomatch flag support added */
29#define REVISION_MAX 2 /* /0 support added */ 28/* 2 /0 support added */
29#define REVISION_MAX 3 /* Counters support added */
30 30
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -127,17 +127,14 @@ iface_add(struct rb_root *root, const char **iface)
127} 127}
128 128
129/* Type specific function prefix */ 129/* Type specific function prefix */
130#define TYPE hash_netiface 130#define HTYPE hash_netiface
131 131#define IP_SET_HASH_WITH_NETS
132static bool 132#define IP_SET_HASH_WITH_RBTREE
133hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b); 133#define IP_SET_HASH_WITH_MULTI
134
135#define hash_netiface4_same_set hash_netiface_same_set
136#define hash_netiface6_same_set hash_netiface_same_set
137 134
138#define STREQ(a, b) (strcmp(a, b) == 0) 135#define STREQ(a, b) (strcmp(a, b) == 0)
139 136
140/* The type variant functions: IPv4 */ 137/* IPv4 variants */
141 138
142struct hash_netiface4_elem_hashed { 139struct hash_netiface4_elem_hashed {
143 __be32 ip; 140 __be32 ip;
@@ -147,8 +144,6 @@ struct hash_netiface4_elem_hashed {
147 u8 elem; 144 u8 elem;
148}; 145};
149 146
150#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed)
151
152/* Member elements without timeout */ 147/* Member elements without timeout */
153struct hash_netiface4_elem { 148struct hash_netiface4_elem {
154 __be32 ip; 149 __be32 ip;
@@ -159,17 +154,39 @@ struct hash_netiface4_elem {
159 const char *iface; 154 const char *iface;
160}; 155};
161 156
162/* Member elements with timeout support */ 157struct hash_netiface4t_elem {
163struct hash_netiface4_telem { 158 __be32 ip;
159 u8 physdev;
160 u8 cidr;
161 u8 nomatch;
162 u8 elem;
163 const char *iface;
164 unsigned long timeout;
165};
166
167struct hash_netiface4c_elem {
168 __be32 ip;
169 u8 physdev;
170 u8 cidr;
171 u8 nomatch;
172 u8 elem;
173 const char *iface;
174 struct ip_set_counter counter;
175};
176
177struct hash_netiface4ct_elem {
164 __be32 ip; 178 __be32 ip;
165 u8 physdev; 179 u8 physdev;
166 u8 cidr; 180 u8 cidr;
167 u8 nomatch; 181 u8 nomatch;
168 u8 elem; 182 u8 elem;
169 const char *iface; 183 const char *iface;
184 struct ip_set_counter counter;
170 unsigned long timeout; 185 unsigned long timeout;
171}; 186};
172 187
188/* Common functions */
189
173static inline bool 190static inline bool
174hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1, 191hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
175 const struct hash_netiface4_elem *ip2, 192 const struct hash_netiface4_elem *ip2,
@@ -182,38 +199,22 @@ hash_netiface4_data_equal(const struct hash_netiface4_elem *ip1,
182 ip1->iface == ip2->iface; 199 ip1->iface == ip2->iface;
183} 200}
184 201
185static inline bool 202static inline int
186hash_netiface4_data_isnull(const struct hash_netiface4_elem *elem) 203hash_netiface4_do_data_match(const struct hash_netiface4_elem *elem)
187{
188 return elem->elem == 0;
189}
190
191static inline void
192hash_netiface4_data_copy(struct hash_netiface4_elem *dst,
193 const struct hash_netiface4_elem *src)
194{ 204{
195 memcpy(dst, src, sizeof(*dst)); 205 return elem->nomatch ? -ENOTEMPTY : 1;
196} 206}
197 207
198static inline void 208static inline void
199hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags) 209hash_netiface4_data_set_flags(struct hash_netiface4_elem *elem, u32 flags)
200{ 210{
201 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); 211 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
202} 212}
203 213
204static inline void 214static inline void
205hash_netiface4_data_reset_flags(struct hash_netiface4_elem *dst, u32 *flags) 215hash_netiface4_data_reset_flags(struct hash_netiface4_elem *elem, u8 *flags)
206{
207 if (dst->nomatch) {
208 *flags = IPSET_FLAG_NOMATCH;
209 dst->nomatch = 0;
210 }
211}
212
213static inline int
214hash_netiface4_data_match(const struct hash_netiface4_elem *elem)
215{ 216{
216 return elem->nomatch ? -ENOTEMPTY : 1; 217 swap(*flags, elem->nomatch);
217} 218}
218 219
219static inline void 220static inline void
@@ -223,12 +224,6 @@ hash_netiface4_data_netmask(struct hash_netiface4_elem *elem, u8 cidr)
223 elem->cidr = cidr; 224 elem->cidr = cidr;
224} 225}
225 226
226static inline void
227hash_netiface4_data_zero_out(struct hash_netiface4_elem *elem)
228{
229 elem->elem = 0;
230}
231
232static bool 227static bool
233hash_netiface4_data_list(struct sk_buff *skb, 228hash_netiface4_data_list(struct sk_buff *skb,
234 const struct hash_netiface4_elem *data) 229 const struct hash_netiface4_elem *data)
@@ -249,66 +244,40 @@ nla_put_failure:
249 return 1; 244 return 1;
250} 245}
251 246
252static bool 247static inline void
253hash_netiface4_data_tlist(struct sk_buff *skb, 248hash_netiface4_data_next(struct hash_netiface4_elem *next,
254 const struct hash_netiface4_elem *data) 249 const struct hash_netiface4_elem *d)
255{ 250{
256 const struct hash_netiface4_telem *tdata = 251 next->ip = d->ip;
257 (const struct hash_netiface4_telem *)data;
258 u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
259
260 if (data->nomatch)
261 flags |= IPSET_FLAG_NOMATCH;
262 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
263 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
264 nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
265 (flags &&
266 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))) ||
267 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
268 htonl(ip_set_timeout_get(tdata->timeout))))
269 goto nla_put_failure;
270
271 return 0;
272
273nla_put_failure:
274 return 1;
275} 252}
276 253
277#define IP_SET_HASH_WITH_NETS 254#define MTYPE hash_netiface4
278#define IP_SET_HASH_WITH_RBTREE
279#define IP_SET_HASH_WITH_MULTI
280
281#define PF 4 255#define PF 4
282#define HOST_MASK 32 256#define HOST_MASK 32
283#include <linux/netfilter/ipset/ip_set_ahash.h> 257#define HKEY_DATALEN sizeof(struct hash_netiface4_elem_hashed)
284 258#include "ip_set_hash_gen.h"
285static inline void
286hash_netiface4_data_next(struct ip_set_hash *h,
287 const struct hash_netiface4_elem *d)
288{
289 h->next.ip = d->ip;
290}
291 259
292static int 260static int
293hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, 261hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
294 const struct xt_action_param *par, 262 const struct xt_action_param *par,
295 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 263 enum ipset_adt adt, struct ip_set_adt_opt *opt)
296{ 264{
297 struct ip_set_hash *h = set->data; 265 struct hash_netiface *h = set->data;
298 ipset_adtfn adtfn = set->variant->adt[adt]; 266 ipset_adtfn adtfn = set->variant->adt[adt];
299 struct hash_netiface4_elem data = { 267 struct hash_netiface4_elem e = {
300 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK, 268 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK,
301 .elem = 1, 269 .elem = 1,
302 }; 270 };
271 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
303 int ret; 272 int ret;
304 273
305 if (data.cidr == 0) 274 if (e.cidr == 0)
306 return -EINVAL; 275 return -EINVAL;
307 if (adt == IPSET_TEST) 276 if (adt == IPSET_TEST)
308 data.cidr = HOST_MASK; 277 e.cidr = HOST_MASK;
309 278
310 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); 279 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
311 data.ip &= ip_set_netmask(data.cidr); 280 e.ip &= ip_set_netmask(e.cidr);
312 281
313#define IFACE(dir) (par->dir ? par->dir->name : NULL) 282#define IFACE(dir) (par->dir ? par->dir->name : NULL)
314#define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : NULL) 283#define PHYSDEV(dir) (nf_bridge->dir ? nf_bridge->dir->name : NULL)
@@ -320,72 +289,69 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
320 289
321 if (!nf_bridge) 290 if (!nf_bridge)
322 return -EINVAL; 291 return -EINVAL;
323 data.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); 292 e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
324 data.physdev = 1; 293 e.physdev = 1;
325#else 294#else
326 data.iface = NULL; 295 e.iface = NULL;
327#endif 296#endif
328 } else 297 } else
329 data.iface = SRCDIR ? IFACE(in) : IFACE(out); 298 e.iface = SRCDIR ? IFACE(in) : IFACE(out);
330 299
331 if (!data.iface) 300 if (!e.iface)
332 return -EINVAL; 301 return -EINVAL;
333 ret = iface_test(&h->rbtree, &data.iface); 302 ret = iface_test(&h->rbtree, &e.iface);
334 if (adt == IPSET_ADD) { 303 if (adt == IPSET_ADD) {
335 if (!ret) { 304 if (!ret) {
336 ret = iface_add(&h->rbtree, &data.iface); 305 ret = iface_add(&h->rbtree, &e.iface);
337 if (ret) 306 if (ret)
338 return ret; 307 return ret;
339 } 308 }
340 } else if (!ret) 309 } else if (!ret)
341 return ret; 310 return ret;
342 311
343 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 312 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
344} 313}
345 314
346static int 315static int
347hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], 316hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
348 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 317 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
349{ 318{
350 struct ip_set_hash *h = set->data; 319 struct hash_netiface *h = set->data;
351 ipset_adtfn adtfn = set->variant->adt[adt]; 320 ipset_adtfn adtfn = set->variant->adt[adt];
352 struct hash_netiface4_elem data = { .cidr = HOST_MASK, .elem = 1 }; 321 struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
322 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
353 u32 ip = 0, ip_to, last; 323 u32 ip = 0, ip_to, last;
354 u32 timeout = h->timeout;
355 char iface[IFNAMSIZ]; 324 char iface[IFNAMSIZ];
356 int ret; 325 int ret;
357 326
358 if (unlikely(!tb[IPSET_ATTR_IP] || 327 if (unlikely(!tb[IPSET_ATTR_IP] ||
359 !tb[IPSET_ATTR_IFACE] || 328 !tb[IPSET_ATTR_IFACE] ||
360 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 329 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
361 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 330 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
331 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
332 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
362 return -IPSET_ERR_PROTOCOL; 333 return -IPSET_ERR_PROTOCOL;
363 334
364 if (tb[IPSET_ATTR_LINENO]) 335 if (tb[IPSET_ATTR_LINENO])
365 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 336 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
366 337
367 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 338 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
339 ip_set_get_extensions(set, tb, &ext);
368 if (ret) 340 if (ret)
369 return ret; 341 return ret;
370 342
371 if (tb[IPSET_ATTR_CIDR]) { 343 if (tb[IPSET_ATTR_CIDR]) {
372 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 344 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
373 if (data.cidr > HOST_MASK) 345 if (e.cidr > HOST_MASK)
374 return -IPSET_ERR_INVALID_CIDR; 346 return -IPSET_ERR_INVALID_CIDR;
375 } 347 }
376 348
377 if (tb[IPSET_ATTR_TIMEOUT]) {
378 if (!with_timeout(h->timeout))
379 return -IPSET_ERR_TIMEOUT;
380 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
381 }
382
383 strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE])); 349 strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE]));
384 data.iface = iface; 350 e.iface = iface;
385 ret = iface_test(&h->rbtree, &data.iface); 351 ret = iface_test(&h->rbtree, &e.iface);
386 if (adt == IPSET_ADD) { 352 if (adt == IPSET_ADD) {
387 if (!ret) { 353 if (!ret) {
388 ret = iface_add(&h->rbtree, &data.iface); 354 ret = iface_add(&h->rbtree, &e.iface);
389 if (ret) 355 if (ret)
390 return ret; 356 return ret;
391 } 357 }
@@ -395,14 +361,15 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
395 if (tb[IPSET_ATTR_CADT_FLAGS]) { 361 if (tb[IPSET_ATTR_CADT_FLAGS]) {
396 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 362 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
397 if (cadt_flags & IPSET_FLAG_PHYSDEV) 363 if (cadt_flags & IPSET_FLAG_PHYSDEV)
398 data.physdev = 1; 364 e.physdev = 1;
399 if (adt == IPSET_ADD && (cadt_flags & IPSET_FLAG_NOMATCH)) 365 if (cadt_flags & IPSET_FLAG_NOMATCH)
400 flags |= (cadt_flags << 16); 366 flags |= (IPSET_FLAG_NOMATCH << 16);
401 } 367 }
402 if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) { 368 if (adt == IPSET_TEST || !tb[IPSET_ATTR_IP_TO]) {
403 data.ip = htonl(ip & ip_set_hostmask(data.cidr)); 369 e.ip = htonl(ip & ip_set_hostmask(e.cidr));
404 ret = adtfn(set, &data, timeout, flags); 370 ret = adtfn(set, &e, &ext, &ext, flags);
405 return ip_set_eexist(ret, flags) ? 0 : ret; 371 return ip_set_enomatch(ret, flags, adt) ? 1 :
372 ip_set_eexist(ret, flags) ? 0 : ret;
406 } 373 }
407 374
408 if (tb[IPSET_ATTR_IP_TO]) { 375 if (tb[IPSET_ATTR_IP_TO]) {
@@ -413,16 +380,15 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
413 swap(ip, ip_to); 380 swap(ip, ip_to);
414 if (ip + UINT_MAX == ip_to) 381 if (ip + UINT_MAX == ip_to)
415 return -IPSET_ERR_HASH_RANGE; 382 return -IPSET_ERR_HASH_RANGE;
416 } else { 383 } else
417 ip_set_mask_from_to(ip, ip_to, data.cidr); 384 ip_set_mask_from_to(ip, ip_to, e.cidr);
418 }
419 385
420 if (retried) 386 if (retried)
421 ip = ntohl(h->next.ip); 387 ip = ntohl(h->next.ip);
422 while (!after(ip, ip_to)) { 388 while (!after(ip, ip_to)) {
423 data.ip = htonl(ip); 389 e.ip = htonl(ip);
424 last = ip_set_range_to_cidr(ip, ip_to, &data.cidr); 390 last = ip_set_range_to_cidr(ip, ip_to, &e.cidr);
425 ret = adtfn(set, &data, timeout, flags); 391 ret = adtfn(set, &e, &ext, &ext, flags);
426 392
427 if (ret && !ip_set_eexist(ret, flags)) 393 if (ret && !ip_set_eexist(ret, flags))
428 return ret; 394 return ret;
@@ -433,18 +399,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
433 return ret; 399 return ret;
434} 400}
435 401
436static bool 402/* IPv6 variants */
437hash_netiface_same_set(const struct ip_set *a, const struct ip_set *b)
438{
439 const struct ip_set_hash *x = a->data;
440 const struct ip_set_hash *y = b->data;
441
442 /* Resizing changes htable_bits, so we ignore it */
443 return x->maxelem == y->maxelem &&
444 x->timeout == y->timeout;
445}
446
447/* The type variant functions: IPv6 */
448 403
449struct hash_netiface6_elem_hashed { 404struct hash_netiface6_elem_hashed {
450 union nf_inet_addr ip; 405 union nf_inet_addr ip;
@@ -454,8 +409,6 @@ struct hash_netiface6_elem_hashed {
454 u8 elem; 409 u8 elem;
455}; 410};
456 411
457#define HKEY_DATALEN sizeof(struct hash_netiface6_elem_hashed)
458
459struct hash_netiface6_elem { 412struct hash_netiface6_elem {
460 union nf_inet_addr ip; 413 union nf_inet_addr ip;
461 u8 physdev; 414 u8 physdev;
@@ -465,16 +418,39 @@ struct hash_netiface6_elem {
465 const char *iface; 418 const char *iface;
466}; 419};
467 420
468struct hash_netiface6_telem { 421struct hash_netiface6t_elem {
422 union nf_inet_addr ip;
423 u8 physdev;
424 u8 cidr;
425 u8 nomatch;
426 u8 elem;
427 const char *iface;
428 unsigned long timeout;
429};
430
431struct hash_netiface6c_elem {
469 union nf_inet_addr ip; 432 union nf_inet_addr ip;
470 u8 physdev; 433 u8 physdev;
471 u8 cidr; 434 u8 cidr;
472 u8 nomatch; 435 u8 nomatch;
473 u8 elem; 436 u8 elem;
474 const char *iface; 437 const char *iface;
438 struct ip_set_counter counter;
439};
440
441struct hash_netiface6ct_elem {
442 union nf_inet_addr ip;
443 u8 physdev;
444 u8 cidr;
445 u8 nomatch;
446 u8 elem;
447 const char *iface;
448 struct ip_set_counter counter;
475 unsigned long timeout; 449 unsigned long timeout;
476}; 450};
477 451
452/* Common functions */
453
478static inline bool 454static inline bool
479hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1, 455hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
480 const struct hash_netiface6_elem *ip2, 456 const struct hash_netiface6_elem *ip2,
@@ -487,53 +463,22 @@ hash_netiface6_data_equal(const struct hash_netiface6_elem *ip1,
487 ip1->iface == ip2->iface; 463 ip1->iface == ip2->iface;
488} 464}
489 465
490static inline bool
491hash_netiface6_data_isnull(const struct hash_netiface6_elem *elem)
492{
493 return elem->elem == 0;
494}
495
496static inline void
497hash_netiface6_data_copy(struct hash_netiface6_elem *dst,
498 const struct hash_netiface6_elem *src)
499{
500 memcpy(dst, src, sizeof(*dst));
501}
502
503static inline void
504hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags)
505{
506 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
507}
508
509static inline int 466static inline int
510hash_netiface6_data_match(const struct hash_netiface6_elem *elem) 467hash_netiface6_do_data_match(const struct hash_netiface6_elem *elem)
511{ 468{
512 return elem->nomatch ? -ENOTEMPTY : 1; 469 return elem->nomatch ? -ENOTEMPTY : 1;
513} 470}
514 471
515static inline void 472static inline void
516hash_netiface6_data_reset_flags(struct hash_netiface6_elem *dst, u32 *flags) 473hash_netiface6_data_set_flags(struct hash_netiface6_elem *elem, u32 flags)
517{
518 if (dst->nomatch) {
519 *flags = IPSET_FLAG_NOMATCH;
520 dst->nomatch = 0;
521 }
522}
523
524static inline void
525hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem)
526{ 474{
527 elem->elem = 0; 475 elem->nomatch = (flags >> 16) & IPSET_FLAG_NOMATCH;
528} 476}
529 477
530static inline void 478static inline void
531ip6_netmask(union nf_inet_addr *ip, u8 prefix) 479hash_netiface6_data_reset_flags(struct hash_netiface6_elem *elem, u8 *flags)
532{ 480{
533 ip->ip6[0] &= ip_set_netmask6(prefix)[0]; 481 swap(*flags, elem->nomatch);
534 ip->ip6[1] &= ip_set_netmask6(prefix)[1];
535 ip->ip6[2] &= ip_set_netmask6(prefix)[2];
536 ip->ip6[3] &= ip_set_netmask6(prefix)[3];
537} 482}
538 483
539static inline void 484static inline void
@@ -563,63 +508,45 @@ nla_put_failure:
563 return 1; 508 return 1;
564} 509}
565 510
566static bool 511static inline void
567hash_netiface6_data_tlist(struct sk_buff *skb, 512hash_netiface6_data_next(struct hash_netiface4_elem *next,
568 const struct hash_netiface6_elem *data) 513 const struct hash_netiface6_elem *d)
569{ 514{
570 const struct hash_netiface6_telem *e =
571 (const struct hash_netiface6_telem *)data;
572 u32 flags = data->physdev ? IPSET_FLAG_PHYSDEV : 0;
573
574 if (data->nomatch)
575 flags |= IPSET_FLAG_NOMATCH;
576 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
577 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr) ||
578 nla_put_string(skb, IPSET_ATTR_IFACE, data->iface) ||
579 (flags &&
580 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))) ||
581 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
582 htonl(ip_set_timeout_get(e->timeout))))
583 goto nla_put_failure;
584 return 0;
585
586nla_put_failure:
587 return 1;
588} 515}
589 516
517#undef MTYPE
590#undef PF 518#undef PF
591#undef HOST_MASK 519#undef HOST_MASK
520#undef HKEY_DATALEN
592 521
522#define MTYPE hash_netiface6
593#define PF 6 523#define PF 6
594#define HOST_MASK 128 524#define HOST_MASK 128
595#include <linux/netfilter/ipset/ip_set_ahash.h> 525#define HKEY_DATALEN sizeof(struct hash_netiface6_elem_hashed)
596 526#define IP_SET_EMIT_CREATE
597static inline void 527#include "ip_set_hash_gen.h"
598hash_netiface6_data_next(struct ip_set_hash *h,
599 const struct hash_netiface6_elem *d)
600{
601}
602 528
603static int 529static int
604hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb, 530hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
605 const struct xt_action_param *par, 531 const struct xt_action_param *par,
606 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 532 enum ipset_adt adt, struct ip_set_adt_opt *opt)
607{ 533{
608 struct ip_set_hash *h = set->data; 534 struct hash_netiface *h = set->data;
609 ipset_adtfn adtfn = set->variant->adt[adt]; 535 ipset_adtfn adtfn = set->variant->adt[adt];
610 struct hash_netiface6_elem data = { 536 struct hash_netiface6_elem e = {
611 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK, 537 .cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK,
612 .elem = 1, 538 .elem = 1,
613 }; 539 };
540 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
614 int ret; 541 int ret;
615 542
616 if (data.cidr == 0) 543 if (e.cidr == 0)
617 return -EINVAL; 544 return -EINVAL;
618 if (adt == IPSET_TEST) 545 if (adt == IPSET_TEST)
619 data.cidr = HOST_MASK; 546 e.cidr = HOST_MASK;
620 547
621 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); 548 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
622 ip6_netmask(&data.ip, data.cidr); 549 ip6_netmask(&e.ip, e.cidr);
623 550
624 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) { 551 if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
625#ifdef CONFIG_BRIDGE_NETFILTER 552#ifdef CONFIG_BRIDGE_NETFILTER
@@ -627,44 +554,46 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
627 554
628 if (!nf_bridge) 555 if (!nf_bridge)
629 return -EINVAL; 556 return -EINVAL;
630 data.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev); 557 e.iface = SRCDIR ? PHYSDEV(physindev) : PHYSDEV(physoutdev);
631 data.physdev = 1; 558 e.physdev = 1;
632#else 559#else
633 data.iface = NULL; 560 e.iface = NULL;
634#endif 561#endif
635 } else 562 } else
636 data.iface = SRCDIR ? IFACE(in) : IFACE(out); 563 e.iface = SRCDIR ? IFACE(in) : IFACE(out);
637 564
638 if (!data.iface) 565 if (!e.iface)
639 return -EINVAL; 566 return -EINVAL;
640 ret = iface_test(&h->rbtree, &data.iface); 567 ret = iface_test(&h->rbtree, &e.iface);
641 if (adt == IPSET_ADD) { 568 if (adt == IPSET_ADD) {
642 if (!ret) { 569 if (!ret) {
643 ret = iface_add(&h->rbtree, &data.iface); 570 ret = iface_add(&h->rbtree, &e.iface);
644 if (ret) 571 if (ret)
645 return ret; 572 return ret;
646 } 573 }
647 } else if (!ret) 574 } else if (!ret)
648 return ret; 575 return ret;
649 576
650 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 577 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
651} 578}
652 579
653static int 580static int
654hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], 581hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
655 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 582 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
656{ 583{
657 struct ip_set_hash *h = set->data; 584 struct hash_netiface *h = set->data;
658 ipset_adtfn adtfn = set->variant->adt[adt]; 585 ipset_adtfn adtfn = set->variant->adt[adt];
659 struct hash_netiface6_elem data = { .cidr = HOST_MASK, .elem = 1 }; 586 struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 };
660 u32 timeout = h->timeout; 587 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
661 char iface[IFNAMSIZ]; 588 char iface[IFNAMSIZ];
662 int ret; 589 int ret;
663 590
664 if (unlikely(!tb[IPSET_ATTR_IP] || 591 if (unlikely(!tb[IPSET_ATTR_IP] ||
665 !tb[IPSET_ATTR_IFACE] || 592 !tb[IPSET_ATTR_IFACE] ||
666 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 593 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
667 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 594 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
595 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
596 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
668 return -IPSET_ERR_PROTOCOL; 597 return -IPSET_ERR_PROTOCOL;
669 if (unlikely(tb[IPSET_ATTR_IP_TO])) 598 if (unlikely(tb[IPSET_ATTR_IP_TO]))
670 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; 599 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
@@ -672,28 +601,23 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
672 if (tb[IPSET_ATTR_LINENO]) 601 if (tb[IPSET_ATTR_LINENO])
673 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 602 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
674 603
675 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); 604 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
605 ip_set_get_extensions(set, tb, &ext);
676 if (ret) 606 if (ret)
677 return ret; 607 return ret;
678 608
679 if (tb[IPSET_ATTR_CIDR]) 609 if (tb[IPSET_ATTR_CIDR])
680 data.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 610 e.cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
681 if (data.cidr > HOST_MASK) 611 if (e.cidr > HOST_MASK)
682 return -IPSET_ERR_INVALID_CIDR; 612 return -IPSET_ERR_INVALID_CIDR;
683 ip6_netmask(&data.ip, data.cidr); 613 ip6_netmask(&e.ip, e.cidr);
684
685 if (tb[IPSET_ATTR_TIMEOUT]) {
686 if (!with_timeout(h->timeout))
687 return -IPSET_ERR_TIMEOUT;
688 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
689 }
690 614
691 strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE])); 615 strcpy(iface, nla_data(tb[IPSET_ATTR_IFACE]));
692 data.iface = iface; 616 e.iface = iface;
693 ret = iface_test(&h->rbtree, &data.iface); 617 ret = iface_test(&h->rbtree, &e.iface);
694 if (adt == IPSET_ADD) { 618 if (adt == IPSET_ADD) {
695 if (!ret) { 619 if (!ret) {
696 ret = iface_add(&h->rbtree, &data.iface); 620 ret = iface_add(&h->rbtree, &e.iface);
697 if (ret) 621 if (ret)
698 return ret; 622 return ret;
699 } 623 }
@@ -703,90 +627,15 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
703 if (tb[IPSET_ATTR_CADT_FLAGS]) { 627 if (tb[IPSET_ATTR_CADT_FLAGS]) {
704 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 628 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
705 if (cadt_flags & IPSET_FLAG_PHYSDEV) 629 if (cadt_flags & IPSET_FLAG_PHYSDEV)
706 data.physdev = 1; 630 e.physdev = 1;
707 if (adt == IPSET_ADD && (cadt_flags & IPSET_FLAG_NOMATCH)) 631 if (cadt_flags & IPSET_FLAG_NOMATCH)
708 flags |= (cadt_flags << 16); 632 flags |= (IPSET_FLAG_NOMATCH << 16);
709 }
710
711 ret = adtfn(set, &data, timeout, flags);
712
713 return ip_set_eexist(ret, flags) ? 0 : ret;
714}
715
716/* Create hash:ip type of sets */
717
718static int
719hash_netiface_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
720{
721 struct ip_set_hash *h;
722 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
723 u8 hbits;
724 size_t hsize;
725
726 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
727 return -IPSET_ERR_INVALID_FAMILY;
728
729 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
730 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
731 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
732 return -IPSET_ERR_PROTOCOL;
733
734 if (tb[IPSET_ATTR_HASHSIZE]) {
735 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
736 if (hashsize < IPSET_MIMINAL_HASHSIZE)
737 hashsize = IPSET_MIMINAL_HASHSIZE;
738 } 633 }
739 634
740 if (tb[IPSET_ATTR_MAXELEM]) 635 ret = adtfn(set, &e, &ext, &ext, flags);
741 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
742
743 h = kzalloc(sizeof(*h)
744 + sizeof(struct ip_set_hash_nets)
745 * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
746 if (!h)
747 return -ENOMEM;
748 636
749 h->maxelem = maxelem; 637 return ip_set_enomatch(ret, flags, adt) ? 1 :
750 get_random_bytes(&h->initval, sizeof(h->initval)); 638 ip_set_eexist(ret, flags) ? 0 : ret;
751 h->timeout = IPSET_NO_TIMEOUT;
752 h->ahash_max = AHASH_MAX_SIZE;
753
754 hbits = htable_bits(hashsize);
755 hsize = htable_size(hbits);
756 if (hsize == 0) {
757 kfree(h);
758 return -ENOMEM;
759 }
760 h->table = ip_set_alloc(hsize);
761 if (!h->table) {
762 kfree(h);
763 return -ENOMEM;
764 }
765 h->table->htable_bits = hbits;
766 h->rbtree = RB_ROOT;
767
768 set->data = h;
769
770 if (tb[IPSET_ATTR_TIMEOUT]) {
771 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
772
773 set->variant = set->family == NFPROTO_IPV4
774 ? &hash_netiface4_tvariant : &hash_netiface6_tvariant;
775
776 if (set->family == NFPROTO_IPV4)
777 hash_netiface4_gc_init(set);
778 else
779 hash_netiface6_gc_init(set);
780 } else {
781 set->variant = set->family == NFPROTO_IPV4
782 ? &hash_netiface4_variant : &hash_netiface6_variant;
783 }
784
785 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
786 set->name, jhash_size(h->table->htable_bits),
787 h->table->htable_bits, h->maxelem, set->data, h->table);
788
789 return 0;
790} 639}
791 640
792static struct ip_set_type hash_netiface_type __read_mostly = { 641static struct ip_set_type hash_netiface_type __read_mostly = {
@@ -806,6 +655,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
806 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 655 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
807 [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, 656 [IPSET_ATTR_PROTO] = { .type = NLA_U8 },
808 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 657 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
658 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
809 }, 659 },
810 .adt_policy = { 660 .adt_policy = {
811 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 661 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -816,6 +666,8 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
816 [IPSET_ATTR_CIDR] = { .type = NLA_U8 }, 666 [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
817 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 667 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
818 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 668 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
669 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
670 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
819 }, 671 },
820 .me = THIS_MODULE, 672 .me = THIS_MODULE,
821}; 673};
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index 349deb672a2d..9a0869853be5 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -20,14 +20,14 @@
20#include <linux/netfilter.h> 20#include <linux/netfilter.h>
21#include <linux/netfilter/ipset/pfxlen.h> 21#include <linux/netfilter/ipset/pfxlen.h>
22#include <linux/netfilter/ipset/ip_set.h> 22#include <linux/netfilter/ipset/ip_set.h>
23#include <linux/netfilter/ipset/ip_set_timeout.h>
24#include <linux/netfilter/ipset/ip_set_getport.h> 23#include <linux/netfilter/ipset/ip_set_getport.h>
25#include <linux/netfilter/ipset/ip_set_hash.h> 24#include <linux/netfilter/ipset/ip_set_hash.h>
26 25
27#define REVISION_MIN 0 26#define REVISION_MIN 0
28/* 1 SCTP and UDPLITE support added */ 27/* 1 SCTP and UDPLITE support added */
29/* 2 Range as input support for IPv4 added */ 28/* 2 Range as input support for IPv4 added */
30#define REVISION_MAX 3 /* nomatch flag support added */ 29/* 3 nomatch flag support added */
30#define REVISION_MAX 4 /* Counters support added */
31 31
32MODULE_LICENSE("GPL"); 32MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
@@ -35,15 +35,9 @@ IP_SET_MODULE_DESC("hash:net,port", REVISION_MIN, REVISION_MAX);
35MODULE_ALIAS("ip_set_hash:net,port"); 35MODULE_ALIAS("ip_set_hash:net,port");
36 36
37/* Type specific function prefix */ 37/* Type specific function prefix */
38#define TYPE hash_netport 38#define HTYPE hash_netport
39 39#define IP_SET_HASH_WITH_PROTO
40static bool 40#define IP_SET_HASH_WITH_NETS
41hash_netport_same_set(const struct ip_set *a, const struct ip_set *b);
42
43#define hash_netport4_same_set hash_netport_same_set
44#define hash_netport6_same_set hash_netport_same_set
45
46/* The type variant functions: IPv4 */
47 41
48/* We squeeze the "nomatch" flag into cidr: we don't support cidr == 0 42/* We squeeze the "nomatch" flag into cidr: we don't support cidr == 0
49 * However this way we have to store internally cidr - 1, 43 * However this way we have to store internally cidr - 1,
@@ -51,7 +45,9 @@ hash_netport_same_set(const struct ip_set *a, const struct ip_set *b);
51 */ 45 */
52#define IP_SET_HASH_WITH_NETS_PACKED 46#define IP_SET_HASH_WITH_NETS_PACKED
53 47
54/* Member elements without timeout */ 48/* IPv4 variants */
49
50/* Member elements */
55struct hash_netport4_elem { 51struct hash_netport4_elem {
56 __be32 ip; 52 __be32 ip;
57 __be16 port; 53 __be16 port;
@@ -60,16 +56,36 @@ struct hash_netport4_elem {
60 u8 nomatch:1; 56 u8 nomatch:1;
61}; 57};
62 58
63/* Member elements with timeout support */ 59struct hash_netport4t_elem {
64struct hash_netport4_telem { 60 __be32 ip;
61 __be16 port;
62 u8 proto;
63 u8 cidr:7;
64 u8 nomatch:1;
65 unsigned long timeout;
66};
67
68struct hash_netport4c_elem {
69 __be32 ip;
70 __be16 port;
71 u8 proto;
72 u8 cidr:7;
73 u8 nomatch:1;
74 struct ip_set_counter counter;
75};
76
77struct hash_netport4ct_elem {
65 __be32 ip; 78 __be32 ip;
66 __be16 port; 79 __be16 port;
67 u8 proto; 80 u8 proto;
68 u8 cidr:7; 81 u8 cidr:7;
69 u8 nomatch:1; 82 u8 nomatch:1;
83 struct ip_set_counter counter;
70 unsigned long timeout; 84 unsigned long timeout;
71}; 85};
72 86
87/* Common functions */
88
73static inline bool 89static inline bool
74hash_netport4_data_equal(const struct hash_netport4_elem *ip1, 90hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
75 const struct hash_netport4_elem *ip2, 91 const struct hash_netport4_elem *ip2,
@@ -81,42 +97,22 @@ hash_netport4_data_equal(const struct hash_netport4_elem *ip1,
81 ip1->cidr == ip2->cidr; 97 ip1->cidr == ip2->cidr;
82} 98}
83 99
84static inline bool 100static inline int
85hash_netport4_data_isnull(const struct hash_netport4_elem *elem) 101hash_netport4_do_data_match(const struct hash_netport4_elem *elem)
86{
87 return elem->proto == 0;
88}
89
90static inline void
91hash_netport4_data_copy(struct hash_netport4_elem *dst,
92 const struct hash_netport4_elem *src)
93{ 102{
94 dst->ip = src->ip; 103 return elem->nomatch ? -ENOTEMPTY : 1;
95 dst->port = src->port;
96 dst->proto = src->proto;
97 dst->cidr = src->cidr;
98 dst->nomatch = src->nomatch;
99} 104}
100 105
101static inline void 106static inline void
102hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags) 107hash_netport4_data_set_flags(struct hash_netport4_elem *elem, u32 flags)
103{ 108{
104 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); 109 elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
105} 110}
106 111
107static inline void 112static inline void
108hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags) 113hash_netport4_data_reset_flags(struct hash_netport4_elem *elem, u8 *flags)
109{ 114{
110 if (dst->nomatch) { 115 swap(*flags, elem->nomatch);
111 *flags = IPSET_FLAG_NOMATCH;
112 dst->nomatch = 0;
113 }
114}
115
116static inline int
117hash_netport4_data_match(const struct hash_netport4_elem *elem)
118{
119 return elem->nomatch ? -ENOTEMPTY : 1;
120} 116}
121 117
122static inline void 118static inline void
@@ -126,12 +122,6 @@ hash_netport4_data_netmask(struct hash_netport4_elem *elem, u8 cidr)
126 elem->cidr = cidr - 1; 122 elem->cidr = cidr - 1;
127} 123}
128 124
129static inline void
130hash_netport4_data_zero_out(struct hash_netport4_elem *elem)
131{
132 elem->proto = 0;
133}
134
135static bool 125static bool
136hash_netport4_data_list(struct sk_buff *skb, 126hash_netport4_data_list(struct sk_buff *skb,
137 const struct hash_netport4_elem *data) 127 const struct hash_netport4_elem *data)
@@ -151,77 +141,53 @@ nla_put_failure:
151 return 1; 141 return 1;
152} 142}
153 143
154static bool 144static inline void
155hash_netport4_data_tlist(struct sk_buff *skb, 145hash_netport4_data_next(struct hash_netport4_elem *next,
156 const struct hash_netport4_elem *data) 146 const struct hash_netport4_elem *d)
157{ 147{
158 const struct hash_netport4_telem *tdata = 148 next->ip = d->ip;
159 (const struct hash_netport4_telem *)data; 149 next->port = d->port;
160 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
161
162 if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, tdata->ip) ||
163 nla_put_net16(skb, IPSET_ATTR_PORT, tdata->port) ||
164 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
165 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
166 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
167 htonl(ip_set_timeout_get(tdata->timeout))) ||
168 (flags &&
169 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
170 goto nla_put_failure;
171 return 0;
172
173nla_put_failure:
174 return 1;
175} 150}
176 151
177#define IP_SET_HASH_WITH_PROTO 152#define MTYPE hash_netport4
178#define IP_SET_HASH_WITH_NETS
179
180#define PF 4 153#define PF 4
181#define HOST_MASK 32 154#define HOST_MASK 32
182#include <linux/netfilter/ipset/ip_set_ahash.h> 155#include "ip_set_hash_gen.h"
183
184static inline void
185hash_netport4_data_next(struct ip_set_hash *h,
186 const struct hash_netport4_elem *d)
187{
188 h->next.ip = d->ip;
189 h->next.port = d->port;
190}
191 156
192static int 157static int
193hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb, 158hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
194 const struct xt_action_param *par, 159 const struct xt_action_param *par,
195 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 160 enum ipset_adt adt, struct ip_set_adt_opt *opt)
196{ 161{
197 const struct ip_set_hash *h = set->data; 162 const struct hash_netport *h = set->data;
198 ipset_adtfn adtfn = set->variant->adt[adt]; 163 ipset_adtfn adtfn = set->variant->adt[adt];
199 struct hash_netport4_elem data = { 164 struct hash_netport4_elem e = {
200 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 165 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1
201 }; 166 };
167 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
202 168
203 if (adt == IPSET_TEST) 169 if (adt == IPSET_TEST)
204 data.cidr = HOST_MASK - 1; 170 e.cidr = HOST_MASK - 1;
205 171
206 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 172 if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
207 &data.port, &data.proto)) 173 &e.port, &e.proto))
208 return -EINVAL; 174 return -EINVAL;
209 175
210 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip); 176 ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
211 data.ip &= ip_set_netmask(data.cidr + 1); 177 e.ip &= ip_set_netmask(e.cidr + 1);
212 178
213 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 179 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
214} 180}
215 181
216static int 182static int
217hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], 183hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
218 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 184 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
219{ 185{
220 const struct ip_set_hash *h = set->data; 186 const struct hash_netport *h = set->data;
221 ipset_adtfn adtfn = set->variant->adt[adt]; 187 ipset_adtfn adtfn = set->variant->adt[adt];
222 struct hash_netport4_elem data = { .cidr = HOST_MASK - 1 }; 188 struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
189 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
223 u32 port, port_to, p = 0, ip = 0, ip_to, last; 190 u32 port, port_to, p = 0, ip = 0, ip_to, last;
224 u32 timeout = h->timeout;
225 bool with_ports = false; 191 bool with_ports = false;
226 u8 cidr; 192 u8 cidr;
227 int ret; 193 int ret;
@@ -230,13 +196,16 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
230 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 196 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
231 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 197 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
232 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 198 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
233 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 199 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
200 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
201 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
234 return -IPSET_ERR_PROTOCOL; 202 return -IPSET_ERR_PROTOCOL;
235 203
236 if (tb[IPSET_ATTR_LINENO]) 204 if (tb[IPSET_ATTR_LINENO])
237 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 205 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
238 206
239 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip); 207 ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP], &ip) ||
208 ip_set_get_extensions(set, tb, &ext);
240 if (ret) 209 if (ret)
241 return ret; 210 return ret;
242 211
@@ -244,47 +213,42 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
244 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 213 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
245 if (!cidr || cidr > HOST_MASK) 214 if (!cidr || cidr > HOST_MASK)
246 return -IPSET_ERR_INVALID_CIDR; 215 return -IPSET_ERR_INVALID_CIDR;
247 data.cidr = cidr - 1; 216 e.cidr = cidr - 1;
248 } 217 }
249 218
250 if (tb[IPSET_ATTR_PORT]) 219 if (tb[IPSET_ATTR_PORT])
251 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 220 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
252 else 221 else
253 return -IPSET_ERR_PROTOCOL; 222 return -IPSET_ERR_PROTOCOL;
254 223
255 if (tb[IPSET_ATTR_PROTO]) { 224 if (tb[IPSET_ATTR_PROTO]) {
256 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 225 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
257 with_ports = ip_set_proto_with_ports(data.proto); 226 with_ports = ip_set_proto_with_ports(e.proto);
258 227
259 if (data.proto == 0) 228 if (e.proto == 0)
260 return -IPSET_ERR_INVALID_PROTO; 229 return -IPSET_ERR_INVALID_PROTO;
261 } else 230 } else
262 return -IPSET_ERR_MISSING_PROTO; 231 return -IPSET_ERR_MISSING_PROTO;
263 232
264 if (!(with_ports || data.proto == IPPROTO_ICMP)) 233 if (!(with_ports || e.proto == IPPROTO_ICMP))
265 data.port = 0; 234 e.port = 0;
266
267 if (tb[IPSET_ATTR_TIMEOUT]) {
268 if (!with_timeout(h->timeout))
269 return -IPSET_ERR_TIMEOUT;
270 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
271 }
272 235
273 with_ports = with_ports && tb[IPSET_ATTR_PORT_TO]; 236 with_ports = with_ports && tb[IPSET_ATTR_PORT_TO];
274 237
275 if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) { 238 if (tb[IPSET_ATTR_CADT_FLAGS]) {
276 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 239 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
277 if (cadt_flags & IPSET_FLAG_NOMATCH) 240 if (cadt_flags & IPSET_FLAG_NOMATCH)
278 flags |= (cadt_flags << 16); 241 flags |= (IPSET_FLAG_NOMATCH << 16);
279 } 242 }
280 243
281 if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) { 244 if (adt == IPSET_TEST || !(with_ports || tb[IPSET_ATTR_IP_TO])) {
282 data.ip = htonl(ip & ip_set_hostmask(data.cidr + 1)); 245 e.ip = htonl(ip & ip_set_hostmask(e.cidr + 1));
283 ret = adtfn(set, &data, timeout, flags); 246 ret = adtfn(set, &e, &ext, &ext, flags);
284 return ip_set_eexist(ret, flags) ? 0 : ret; 247 return ip_set_enomatch(ret, flags, adt) ? 1 :
248 ip_set_eexist(ret, flags) ? 0 : ret;
285 } 249 }
286 250
287 port = port_to = ntohs(data.port); 251 port = port_to = ntohs(e.port);
288 if (tb[IPSET_ATTR_PORT_TO]) { 252 if (tb[IPSET_ATTR_PORT_TO]) {
289 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 253 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
290 if (port_to < port) 254 if (port_to < port)
@@ -298,21 +262,20 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
298 swap(ip, ip_to); 262 swap(ip, ip_to);
299 if (ip + UINT_MAX == ip_to) 263 if (ip + UINT_MAX == ip_to)
300 return -IPSET_ERR_HASH_RANGE; 264 return -IPSET_ERR_HASH_RANGE;
301 } else { 265 } else
302 ip_set_mask_from_to(ip, ip_to, data.cidr + 1); 266 ip_set_mask_from_to(ip, ip_to, e.cidr + 1);
303 }
304 267
305 if (retried) 268 if (retried)
306 ip = ntohl(h->next.ip); 269 ip = ntohl(h->next.ip);
307 while (!after(ip, ip_to)) { 270 while (!after(ip, ip_to)) {
308 data.ip = htonl(ip); 271 e.ip = htonl(ip);
309 last = ip_set_range_to_cidr(ip, ip_to, &cidr); 272 last = ip_set_range_to_cidr(ip, ip_to, &cidr);
310 data.cidr = cidr - 1; 273 e.cidr = cidr - 1;
311 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port) 274 p = retried && ip == ntohl(h->next.ip) ? ntohs(h->next.port)
312 : port; 275 : port;
313 for (; p <= port_to; p++) { 276 for (; p <= port_to; p++) {
314 data.port = htons(p); 277 e.port = htons(p);
315 ret = adtfn(set, &data, timeout, flags); 278 ret = adtfn(set, &e, &ext, &ext, flags);
316 279
317 if (ret && !ip_set_eexist(ret, flags)) 280 if (ret && !ip_set_eexist(ret, flags))
318 return ret; 281 return ret;
@@ -324,36 +287,46 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
324 return ret; 287 return ret;
325} 288}
326 289
327static bool 290/* IPv6 variants */
328hash_netport_same_set(const struct ip_set *a, const struct ip_set *b)
329{
330 const struct ip_set_hash *x = a->data;
331 const struct ip_set_hash *y = b->data;
332 291
333 /* Resizing changes htable_bits, so we ignore it */ 292struct hash_netport6_elem {
334 return x->maxelem == y->maxelem && 293 union nf_inet_addr ip;
335 x->timeout == y->timeout; 294 __be16 port;
336} 295 u8 proto;
296 u8 cidr:7;
297 u8 nomatch:1;
298};
337 299
338/* The type variant functions: IPv6 */ 300struct hash_netport6t_elem {
301 union nf_inet_addr ip;
302 __be16 port;
303 u8 proto;
304 u8 cidr:7;
305 u8 nomatch:1;
306 unsigned long timeout;
307};
339 308
340struct hash_netport6_elem { 309struct hash_netport6c_elem {
341 union nf_inet_addr ip; 310 union nf_inet_addr ip;
342 __be16 port; 311 __be16 port;
343 u8 proto; 312 u8 proto;
344 u8 cidr:7; 313 u8 cidr:7;
345 u8 nomatch:1; 314 u8 nomatch:1;
315 struct ip_set_counter counter;
346}; 316};
347 317
348struct hash_netport6_telem { 318struct hash_netport6ct_elem {
349 union nf_inet_addr ip; 319 union nf_inet_addr ip;
350 __be16 port; 320 __be16 port;
351 u8 proto; 321 u8 proto;
352 u8 cidr:7; 322 u8 cidr:7;
353 u8 nomatch:1; 323 u8 nomatch:1;
324 struct ip_set_counter counter;
354 unsigned long timeout; 325 unsigned long timeout;
355}; 326};
356 327
328/* Common functions */
329
357static inline bool 330static inline bool
358hash_netport6_data_equal(const struct hash_netport6_elem *ip1, 331hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
359 const struct hash_netport6_elem *ip2, 332 const struct hash_netport6_elem *ip2,
@@ -365,53 +338,22 @@ hash_netport6_data_equal(const struct hash_netport6_elem *ip1,
365 ip1->cidr == ip2->cidr; 338 ip1->cidr == ip2->cidr;
366} 339}
367 340
368static inline bool
369hash_netport6_data_isnull(const struct hash_netport6_elem *elem)
370{
371 return elem->proto == 0;
372}
373
374static inline void
375hash_netport6_data_copy(struct hash_netport6_elem *dst,
376 const struct hash_netport6_elem *src)
377{
378 memcpy(dst, src, sizeof(*dst));
379}
380
381static inline void
382hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags)
383{
384 dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH);
385}
386
387static inline void
388hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags)
389{
390 if (dst->nomatch) {
391 *flags = IPSET_FLAG_NOMATCH;
392 dst->nomatch = 0;
393 }
394}
395
396static inline int 341static inline int
397hash_netport6_data_match(const struct hash_netport6_elem *elem) 342hash_netport6_do_data_match(const struct hash_netport6_elem *elem)
398{ 343{
399 return elem->nomatch ? -ENOTEMPTY : 1; 344 return elem->nomatch ? -ENOTEMPTY : 1;
400} 345}
401 346
402static inline void 347static inline void
403hash_netport6_data_zero_out(struct hash_netport6_elem *elem) 348hash_netport6_data_set_flags(struct hash_netport6_elem *elem, u32 flags)
404{ 349{
405 elem->proto = 0; 350 elem->nomatch = !!((flags >> 16) & IPSET_FLAG_NOMATCH);
406} 351}
407 352
408static inline void 353static inline void
409ip6_netmask(union nf_inet_addr *ip, u8 prefix) 354hash_netport6_data_reset_flags(struct hash_netport6_elem *elem, u8 *flags)
410{ 355{
411 ip->ip6[0] &= ip_set_netmask6(prefix)[0]; 356 swap(*flags, elem->nomatch);
412 ip->ip6[1] &= ip_set_netmask6(prefix)[1];
413 ip->ip6[2] &= ip_set_netmask6(prefix)[2];
414 ip->ip6[3] &= ip_set_netmask6(prefix)[3];
415} 357}
416 358
417static inline void 359static inline void
@@ -440,76 +382,57 @@ nla_put_failure:
440 return 1; 382 return 1;
441} 383}
442 384
443static bool 385static inline void
444hash_netport6_data_tlist(struct sk_buff *skb, 386hash_netport6_data_next(struct hash_netport4_elem *next,
445 const struct hash_netport6_elem *data) 387 const struct hash_netport6_elem *d)
446{ 388{
447 const struct hash_netport6_telem *e = 389 next->port = d->port;
448 (const struct hash_netport6_telem *)data;
449 u32 flags = data->nomatch ? IPSET_FLAG_NOMATCH : 0;
450
451 if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &e->ip.in6) ||
452 nla_put_net16(skb, IPSET_ATTR_PORT, data->port) ||
453 nla_put_u8(skb, IPSET_ATTR_CIDR, data->cidr + 1) ||
454 nla_put_u8(skb, IPSET_ATTR_PROTO, data->proto) ||
455 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
456 htonl(ip_set_timeout_get(e->timeout))) ||
457 (flags &&
458 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
459 goto nla_put_failure;
460 return 0;
461
462nla_put_failure:
463 return 1;
464} 390}
465 391
392#undef MTYPE
466#undef PF 393#undef PF
467#undef HOST_MASK 394#undef HOST_MASK
468 395
396#define MTYPE hash_netport6
469#define PF 6 397#define PF 6
470#define HOST_MASK 128 398#define HOST_MASK 128
471#include <linux/netfilter/ipset/ip_set_ahash.h> 399#define IP_SET_EMIT_CREATE
472 400#include "ip_set_hash_gen.h"
473static inline void
474hash_netport6_data_next(struct ip_set_hash *h,
475 const struct hash_netport6_elem *d)
476{
477 h->next.port = d->port;
478}
479 401
480static int 402static int
481hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb, 403hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
482 const struct xt_action_param *par, 404 const struct xt_action_param *par,
483 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 405 enum ipset_adt adt, struct ip_set_adt_opt *opt)
484{ 406{
485 const struct ip_set_hash *h = set->data; 407 const struct hash_netport *h = set->data;
486 ipset_adtfn adtfn = set->variant->adt[adt]; 408 ipset_adtfn adtfn = set->variant->adt[adt];
487 struct hash_netport6_elem data = { 409 struct hash_netport6_elem e = {
488 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1, 410 .cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1,
489 }; 411 };
412 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h);
490 413
491 if (adt == IPSET_TEST) 414 if (adt == IPSET_TEST)
492 data.cidr = HOST_MASK - 1; 415 e.cidr = HOST_MASK - 1;
493 416
494 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, 417 if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
495 &data.port, &data.proto)) 418 &e.port, &e.proto))
496 return -EINVAL; 419 return -EINVAL;
497 420
498 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &data.ip.in6); 421 ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
499 ip6_netmask(&data.ip, data.cidr + 1); 422 ip6_netmask(&e.ip, e.cidr + 1);
500 423
501 return adtfn(set, &data, opt_timeout(opt, h), opt->cmdflags); 424 return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
502} 425}
503 426
504static int 427static int
505hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], 428hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
506 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 429 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
507{ 430{
508 const struct ip_set_hash *h = set->data; 431 const struct hash_netport *h = set->data;
509 ipset_adtfn adtfn = set->variant->adt[adt]; 432 ipset_adtfn adtfn = set->variant->adt[adt];
510 struct hash_netport6_elem data = { .cidr = HOST_MASK - 1 }; 433 struct hash_netport6_elem e = { .cidr = HOST_MASK - 1 };
434 struct ip_set_ext ext = IP_SET_INIT_UEXT(h);
511 u32 port, port_to; 435 u32 port, port_to;
512 u32 timeout = h->timeout;
513 bool with_ports = false; 436 bool with_ports = false;
514 u8 cidr; 437 u8 cidr;
515 int ret; 438 int ret;
@@ -518,7 +441,9 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
518 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || 441 !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
519 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) || 442 !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
520 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 443 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
521 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 444 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
445 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
446 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
522 return -IPSET_ERR_PROTOCOL; 447 return -IPSET_ERR_PROTOCOL;
523 if (unlikely(tb[IPSET_ATTR_IP_TO])) 448 if (unlikely(tb[IPSET_ATTR_IP_TO]))
524 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED; 449 return -IPSET_ERR_HASH_RANGE_UNSUPPORTED;
@@ -526,7 +451,8 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
526 if (tb[IPSET_ATTR_LINENO]) 451 if (tb[IPSET_ATTR_LINENO])
527 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 452 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
528 453
529 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &data.ip); 454 ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
455 ip_set_get_extensions(set, tb, &ext);
530 if (ret) 456 if (ret)
531 return ret; 457 return ret;
532 458
@@ -534,45 +460,40 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
534 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); 460 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
535 if (!cidr || cidr > HOST_MASK) 461 if (!cidr || cidr > HOST_MASK)
536 return -IPSET_ERR_INVALID_CIDR; 462 return -IPSET_ERR_INVALID_CIDR;
537 data.cidr = cidr - 1; 463 e.cidr = cidr - 1;
538 } 464 }
539 ip6_netmask(&data.ip, data.cidr + 1); 465 ip6_netmask(&e.ip, e.cidr + 1);
540 466
541 if (tb[IPSET_ATTR_PORT]) 467 if (tb[IPSET_ATTR_PORT])
542 data.port = nla_get_be16(tb[IPSET_ATTR_PORT]); 468 e.port = nla_get_be16(tb[IPSET_ATTR_PORT]);
543 else 469 else
544 return -IPSET_ERR_PROTOCOL; 470 return -IPSET_ERR_PROTOCOL;
545 471
546 if (tb[IPSET_ATTR_PROTO]) { 472 if (tb[IPSET_ATTR_PROTO]) {
547 data.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]); 473 e.proto = nla_get_u8(tb[IPSET_ATTR_PROTO]);
548 with_ports = ip_set_proto_with_ports(data.proto); 474 with_ports = ip_set_proto_with_ports(e.proto);
549 475
550 if (data.proto == 0) 476 if (e.proto == 0)
551 return -IPSET_ERR_INVALID_PROTO; 477 return -IPSET_ERR_INVALID_PROTO;
552 } else 478 } else
553 return -IPSET_ERR_MISSING_PROTO; 479 return -IPSET_ERR_MISSING_PROTO;
554 480
555 if (!(with_ports || data.proto == IPPROTO_ICMPV6)) 481 if (!(with_ports || e.proto == IPPROTO_ICMPV6))
556 data.port = 0; 482 e.port = 0;
557 483
558 if (tb[IPSET_ATTR_TIMEOUT]) { 484 if (tb[IPSET_ATTR_CADT_FLAGS]) {
559 if (!with_timeout(h->timeout))
560 return -IPSET_ERR_TIMEOUT;
561 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
562 }
563
564 if (tb[IPSET_ATTR_CADT_FLAGS] && adt == IPSET_ADD) {
565 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 485 u32 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
566 if (cadt_flags & IPSET_FLAG_NOMATCH) 486 if (cadt_flags & IPSET_FLAG_NOMATCH)
567 flags |= (cadt_flags << 16); 487 flags |= (IPSET_FLAG_NOMATCH << 16);
568 } 488 }
569 489
570 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) { 490 if (adt == IPSET_TEST || !with_ports || !tb[IPSET_ATTR_PORT_TO]) {
571 ret = adtfn(set, &data, timeout, flags); 491 ret = adtfn(set, &e, &ext, &ext, flags);
572 return ip_set_eexist(ret, flags) ? 0 : ret; 492 return ip_set_enomatch(ret, flags, adt) ? 1 :
493 ip_set_eexist(ret, flags) ? 0 : ret;
573 } 494 }
574 495
575 port = ntohs(data.port); 496 port = ntohs(e.port);
576 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]); 497 port_to = ip_set_get_h16(tb[IPSET_ATTR_PORT_TO]);
577 if (port > port_to) 498 if (port > port_to)
578 swap(port, port_to); 499 swap(port, port_to);
@@ -580,8 +501,8 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
580 if (retried) 501 if (retried)
581 port = ntohs(h->next.port); 502 port = ntohs(h->next.port);
582 for (; port <= port_to; port++) { 503 for (; port <= port_to; port++) {
583 data.port = htons(port); 504 e.port = htons(port);
584 ret = adtfn(set, &data, timeout, flags); 505 ret = adtfn(set, &e, &ext, &ext, flags);
585 506
586 if (ret && !ip_set_eexist(ret, flags)) 507 if (ret && !ip_set_eexist(ret, flags))
587 return ret; 508 return ret;
@@ -591,80 +512,6 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
591 return ret; 512 return ret;
592} 513}
593 514
594/* Create hash:ip type of sets */
595
596static int
597hash_netport_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
598{
599 struct ip_set_hash *h;
600 u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
601 u8 hbits;
602 size_t hsize;
603
604 if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
605 return -IPSET_ERR_INVALID_FAMILY;
606
607 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
608 !ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
609 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT)))
610 return -IPSET_ERR_PROTOCOL;
611
612 if (tb[IPSET_ATTR_HASHSIZE]) {
613 hashsize = ip_set_get_h32(tb[IPSET_ATTR_HASHSIZE]);
614 if (hashsize < IPSET_MIMINAL_HASHSIZE)
615 hashsize = IPSET_MIMINAL_HASHSIZE;
616 }
617
618 if (tb[IPSET_ATTR_MAXELEM])
619 maxelem = ip_set_get_h32(tb[IPSET_ATTR_MAXELEM]);
620
621 h = kzalloc(sizeof(*h)
622 + sizeof(struct ip_set_hash_nets)
623 * (set->family == NFPROTO_IPV4 ? 32 : 128), GFP_KERNEL);
624 if (!h)
625 return -ENOMEM;
626
627 h->maxelem = maxelem;
628 get_random_bytes(&h->initval, sizeof(h->initval));
629 h->timeout = IPSET_NO_TIMEOUT;
630
631 hbits = htable_bits(hashsize);
632 hsize = htable_size(hbits);
633 if (hsize == 0) {
634 kfree(h);
635 return -ENOMEM;
636 }
637 h->table = ip_set_alloc(hsize);
638 if (!h->table) {
639 kfree(h);
640 return -ENOMEM;
641 }
642 h->table->htable_bits = hbits;
643
644 set->data = h;
645
646 if (tb[IPSET_ATTR_TIMEOUT]) {
647 h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
648
649 set->variant = set->family == NFPROTO_IPV4
650 ? &hash_netport4_tvariant : &hash_netport6_tvariant;
651
652 if (set->family == NFPROTO_IPV4)
653 hash_netport4_gc_init(set);
654 else
655 hash_netport6_gc_init(set);
656 } else {
657 set->variant = set->family == NFPROTO_IPV4
658 ? &hash_netport4_variant : &hash_netport6_variant;
659 }
660
661 pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
662 set->name, jhash_size(h->table->htable_bits),
663 h->table->htable_bits, h->maxelem, set->data, h->table);
664
665 return 0;
666}
667
668static struct ip_set_type hash_netport_type __read_mostly = { 515static struct ip_set_type hash_netport_type __read_mostly = {
669 .name = "hash:net,port", 516 .name = "hash:net,port",
670 .protocol = IPSET_PROTOCOL, 517 .protocol = IPSET_PROTOCOL,
@@ -681,6 +528,7 @@ static struct ip_set_type hash_netport_type __read_mostly = {
681 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 }, 528 [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
682 [IPSET_ATTR_PROTO] = { .type = NLA_U8 }, 529 [IPSET_ATTR_PROTO] = { .type = NLA_U8 },
683 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 530 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
531 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
684 }, 532 },
685 .adt_policy = { 533 .adt_policy = {
686 [IPSET_ATTR_IP] = { .type = NLA_NESTED }, 534 [IPSET_ATTR_IP] = { .type = NLA_NESTED },
@@ -692,6 +540,8 @@ static struct ip_set_type hash_netport_type __read_mostly = {
692 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 540 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
693 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 541 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
694 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 542 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
543 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
544 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
695 }, 545 },
696 .me = THIS_MODULE, 546 .me = THIS_MODULE,
697}; 547};
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c
index 09c744aa8982..979b8c90e422 100644
--- a/net/netfilter/ipset/ip_set_list_set.c
+++ b/net/netfilter/ipset/ip_set_list_set.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2008-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 1/* Copyright (C) 2008-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
@@ -13,30 +13,53 @@
13#include <linux/errno.h> 13#include <linux/errno.h>
14 14
15#include <linux/netfilter/ipset/ip_set.h> 15#include <linux/netfilter/ipset/ip_set.h>
16#include <linux/netfilter/ipset/ip_set_timeout.h>
17#include <linux/netfilter/ipset/ip_set_list.h> 16#include <linux/netfilter/ipset/ip_set_list.h>
18 17
19#define REVISION_MIN 0 18#define REVISION_MIN 0
20#define REVISION_MAX 0 19#define REVISION_MAX 1 /* Counters support added */
21 20
22MODULE_LICENSE("GPL"); 21MODULE_LICENSE("GPL");
23MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 22MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
24IP_SET_MODULE_DESC("list:set", REVISION_MIN, REVISION_MAX); 23IP_SET_MODULE_DESC("list:set", REVISION_MIN, REVISION_MAX);
25MODULE_ALIAS("ip_set_list:set"); 24MODULE_ALIAS("ip_set_list:set");
26 25
27/* Member elements without and with timeout */ 26/* Member elements */
28struct set_elem { 27struct set_elem {
29 ip_set_id_t id; 28 ip_set_id_t id;
30}; 29};
31 30
32struct set_telem { 31struct sett_elem {
33 ip_set_id_t id; 32 struct {
33 ip_set_id_t id;
34 } __attribute__ ((aligned));
35 unsigned long timeout;
36};
37
38struct setc_elem {
39 struct {
40 ip_set_id_t id;
41 } __attribute__ ((aligned));
42 struct ip_set_counter counter;
43};
44
45struct setct_elem {
46 struct {
47 ip_set_id_t id;
48 } __attribute__ ((aligned));
49 struct ip_set_counter counter;
34 unsigned long timeout; 50 unsigned long timeout;
35}; 51};
36 52
53struct set_adt_elem {
54 ip_set_id_t id;
55 ip_set_id_t refid;
56 int before;
57};
58
37/* Type structure */ 59/* Type structure */
38struct list_set { 60struct list_set {
39 size_t dsize; /* element size */ 61 size_t dsize; /* element size */
62 size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
40 u32 size; /* size of set list array */ 63 u32 size; /* size of set list array */
41 u32 timeout; /* timeout value */ 64 u32 timeout; /* timeout value */
42 struct timer_list gc; /* garbage collection */ 65 struct timer_list gc; /* garbage collection */
@@ -49,179 +72,311 @@ list_set_elem(const struct list_set *map, u32 id)
49 return (struct set_elem *)((void *)map->members + id * map->dsize); 72 return (struct set_elem *)((void *)map->members + id * map->dsize);
50} 73}
51 74
52static inline struct set_telem * 75#define ext_timeout(e, m) \
53list_set_telem(const struct list_set *map, u32 id) 76(unsigned long *)((void *)(e) + (m)->offset[IPSET_OFFSET_TIMEOUT])
54{ 77#define ext_counter(e, m) \
55 return (struct set_telem *)((void *)map->members + id * map->dsize); 78(struct ip_set_counter *)((void *)(e) + (m)->offset[IPSET_OFFSET_COUNTER])
56}
57 79
58static inline bool 80static int
59list_set_timeout(const struct list_set *map, u32 id) 81list_set_ktest(struct ip_set *set, const struct sk_buff *skb,
82 const struct xt_action_param *par,
83 struct ip_set_adt_opt *opt, const struct ip_set_ext *ext)
60{ 84{
61 const struct set_telem *elem = list_set_telem(map, id); 85 struct list_set *map = set->data;
86 struct set_elem *e;
87 u32 i, cmdflags = opt->cmdflags;
88 int ret;
62 89
63 return ip_set_timeout_test(elem->timeout); 90 /* Don't lookup sub-counters at all */
91 opt->cmdflags &= ~IPSET_FLAG_MATCH_COUNTERS;
92 if (opt->cmdflags & IPSET_FLAG_SKIP_SUBCOUNTER_UPDATE)
93 opt->cmdflags &= ~IPSET_FLAG_SKIP_COUNTER_UPDATE;
94 for (i = 0; i < map->size; i++) {
95 e = list_set_elem(map, i);
96 if (e->id == IPSET_INVALID_ID)
97 return 0;
98 if (SET_WITH_TIMEOUT(set) &&
99 ip_set_timeout_expired(ext_timeout(e, map)))
100 continue;
101 ret = ip_set_test(e->id, skb, par, opt);
102 if (ret > 0) {
103 if (SET_WITH_COUNTER(set))
104 ip_set_update_counter(ext_counter(e, map),
105 ext, &opt->ext,
106 cmdflags);
107 return ret;
108 }
109 }
110 return 0;
64} 111}
65 112
66static inline bool 113static int
67list_set_expired(const struct list_set *map, u32 id) 114list_set_kadd(struct ip_set *set, const struct sk_buff *skb,
115 const struct xt_action_param *par,
116 struct ip_set_adt_opt *opt, const struct ip_set_ext *ext)
68{ 117{
69 const struct set_telem *elem = list_set_telem(map, id); 118 struct list_set *map = set->data;
119 struct set_elem *e;
120 u32 i;
121 int ret;
70 122
71 return ip_set_timeout_expired(elem->timeout); 123 for (i = 0; i < map->size; i++) {
124 e = list_set_elem(map, i);
125 if (e->id == IPSET_INVALID_ID)
126 return 0;
127 if (SET_WITH_TIMEOUT(set) &&
128 ip_set_timeout_expired(ext_timeout(e, map)))
129 continue;
130 ret = ip_set_add(e->id, skb, par, opt);
131 if (ret == 0)
132 return ret;
133 }
134 return 0;
72} 135}
73 136
74/* Set list without and with timeout */
75
76static int 137static int
77list_set_kadt(struct ip_set *set, const struct sk_buff *skb, 138list_set_kdel(struct ip_set *set, const struct sk_buff *skb,
78 const struct xt_action_param *par, 139 const struct xt_action_param *par,
79 enum ipset_adt adt, const struct ip_set_adt_opt *opt) 140 struct ip_set_adt_opt *opt, const struct ip_set_ext *ext)
80{ 141{
81 struct list_set *map = set->data; 142 struct list_set *map = set->data;
82 struct set_elem *elem; 143 struct set_elem *e;
83 u32 i; 144 u32 i;
84 int ret; 145 int ret;
85 146
86 for (i = 0; i < map->size; i++) { 147 for (i = 0; i < map->size; i++) {
87 elem = list_set_elem(map, i); 148 e = list_set_elem(map, i);
88 if (elem->id == IPSET_INVALID_ID) 149 if (e->id == IPSET_INVALID_ID)
89 return 0; 150 return 0;
90 if (with_timeout(map->timeout) && list_set_expired(map, i)) 151 if (SET_WITH_TIMEOUT(set) &&
152 ip_set_timeout_expired(ext_timeout(e, map)))
91 continue; 153 continue;
92 switch (adt) { 154 ret = ip_set_del(e->id, skb, par, opt);
93 case IPSET_TEST: 155 if (ret == 0)
94 ret = ip_set_test(elem->id, skb, par, opt); 156 return ret;
95 if (ret > 0) 157 }
96 return ret; 158 return 0;
97 break; 159}
98 case IPSET_ADD: 160
99 ret = ip_set_add(elem->id, skb, par, opt); 161static int
100 if (ret == 0) 162list_set_kadt(struct ip_set *set, const struct sk_buff *skb,
101 return ret; 163 const struct xt_action_param *par,
102 break; 164 enum ipset_adt adt, struct ip_set_adt_opt *opt)
103 case IPSET_DEL: 165{
104 ret = ip_set_del(elem->id, skb, par, opt); 166 struct list_set *map = set->data;
105 if (ret == 0) 167 struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map);
106 return ret; 168
107 break; 169 switch (adt) {
108 default: 170 case IPSET_TEST:
109 break; 171 return list_set_ktest(set, skb, par, opt, &ext);
110 } 172 case IPSET_ADD:
173 return list_set_kadd(set, skb, par, opt, &ext);
174 case IPSET_DEL:
175 return list_set_kdel(set, skb, par, opt, &ext);
176 default:
177 break;
111 } 178 }
112 return -EINVAL; 179 return -EINVAL;
113} 180}
114 181
115static bool 182static bool
116id_eq(const struct list_set *map, u32 i, ip_set_id_t id) 183id_eq(const struct ip_set *set, u32 i, ip_set_id_t id)
117{ 184{
118 const struct set_elem *elem; 185 const struct list_set *map = set->data;
186 const struct set_elem *e;
119 187
120 if (i < map->size) { 188 if (i >= map->size)
121 elem = list_set_elem(map, i); 189 return 0;
122 return elem->id == id; 190
191 e = list_set_elem(map, i);
192 return !!(e->id == id &&
193 !(SET_WITH_TIMEOUT(set) &&
194 ip_set_timeout_expired(ext_timeout(e, map))));
195}
196
197static int
198list_set_add(struct ip_set *set, u32 i, struct set_adt_elem *d,
199 const struct ip_set_ext *ext)
200{
201 struct list_set *map = set->data;
202 struct set_elem *e = list_set_elem(map, i);
203
204 if (e->id != IPSET_INVALID_ID) {
205 if (i == map->size - 1)
206 /* Last element replaced: e.g. add new,before,last */
207 ip_set_put_byindex(e->id);
208 else {
209 struct set_elem *x = list_set_elem(map, map->size - 1);
210
211 /* Last element pushed off */
212 if (x->id != IPSET_INVALID_ID)
213 ip_set_put_byindex(x->id);
214 memmove(list_set_elem(map, i + 1), e,
215 map->dsize * (map->size - (i + 1)));
216 }
123 } 217 }
124 218
219 e->id = d->id;
220 if (SET_WITH_TIMEOUT(set))
221 ip_set_timeout_set(ext_timeout(e, map), ext->timeout);
222 if (SET_WITH_COUNTER(set))
223 ip_set_init_counter(ext_counter(e, map), ext);
125 return 0; 224 return 0;
126} 225}
127 226
128static bool 227static int
129id_eq_timeout(const struct list_set *map, u32 i, ip_set_id_t id) 228list_set_del(struct ip_set *set, u32 i)
130{ 229{
131 const struct set_elem *elem; 230 struct list_set *map = set->data;
231 struct set_elem *e = list_set_elem(map, i);
132 232
133 if (i < map->size) { 233 ip_set_put_byindex(e->id);
134 elem = list_set_elem(map, i);
135 return !!(elem->id == id &&
136 !(with_timeout(map->timeout) &&
137 list_set_expired(map, i)));
138 }
139 234
235 if (i < map->size - 1)
236 memmove(e, list_set_elem(map, i + 1),
237 map->dsize * (map->size - (i + 1)));
238
239 /* Last element */
240 e = list_set_elem(map, map->size - 1);
241 e->id = IPSET_INVALID_ID;
140 return 0; 242 return 0;
141} 243}
142 244
143static void 245static void
144list_elem_add(struct list_set *map, u32 i, ip_set_id_t id) 246set_cleanup_entries(struct ip_set *set)
145{ 247{
248 struct list_set *map = set->data;
146 struct set_elem *e; 249 struct set_elem *e;
250 u32 i;
147 251
148 for (; i < map->size; i++) { 252 for (i = 0; i < map->size; i++) {
149 e = list_set_elem(map, i); 253 e = list_set_elem(map, i);
150 swap(e->id, id); 254 if (e->id != IPSET_INVALID_ID &&
151 if (e->id == IPSET_INVALID_ID) 255 ip_set_timeout_expired(ext_timeout(e, map)))
152 break; 256 list_set_del(set, i);
153 } 257 }
154} 258}
155 259
156static void 260static int
157list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id, 261list_set_utest(struct ip_set *set, void *value, const struct ip_set_ext *ext,
158 unsigned long timeout) 262 struct ip_set_ext *mext, u32 flags)
159{ 263{
160 struct set_telem *e; 264 struct list_set *map = set->data;
265 struct set_adt_elem *d = value;
266 struct set_elem *e;
267 u32 i;
268 int ret;
161 269
162 for (; i < map->size; i++) { 270 for (i = 0; i < map->size; i++) {
163 e = list_set_telem(map, i); 271 e = list_set_elem(map, i);
164 swap(e->id, id);
165 swap(e->timeout, timeout);
166 if (e->id == IPSET_INVALID_ID) 272 if (e->id == IPSET_INVALID_ID)
167 break; 273 return 0;
274 else if (SET_WITH_TIMEOUT(set) &&
275 ip_set_timeout_expired(ext_timeout(e, map)))
276 continue;
277 else if (e->id != d->id)
278 continue;
279
280 if (d->before == 0)
281 return 1;
282 else if (d->before > 0)
283 ret = id_eq(set, i + 1, d->refid);
284 else
285 ret = i > 0 && id_eq(set, i - 1, d->refid);
286 return ret;
168 } 287 }
288 return 0;
169} 289}
170 290
291
171static int 292static int
172list_set_add(struct list_set *map, u32 i, ip_set_id_t id, 293list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
173 unsigned long timeout) 294 struct ip_set_ext *mext, u32 flags)
174{ 295{
175 const struct set_elem *e = list_set_elem(map, i); 296 struct list_set *map = set->data;
297 struct set_adt_elem *d = value;
298 struct set_elem *e;
299 bool flag_exist = flags & IPSET_FLAG_EXIST;
300 u32 i, ret = 0;
176 301
177 if (e->id != IPSET_INVALID_ID) { 302 /* Check already added element */
178 const struct set_elem *x = list_set_elem(map, map->size - 1); 303 for (i = 0; i < map->size; i++) {
304 e = list_set_elem(map, i);
305 if (e->id == IPSET_INVALID_ID)
306 goto insert;
307 else if (SET_WITH_TIMEOUT(set) &&
308 ip_set_timeout_expired(ext_timeout(e, map)))
309 continue;
310 else if (e->id != d->id)
311 continue;
179 312
180 /* Last element replaced or pushed off */ 313 if ((d->before > 1 && !id_eq(set, i + 1, d->refid)) ||
181 if (x->id != IPSET_INVALID_ID) 314 (d->before < 0 &&
182 ip_set_put_byindex(x->id); 315 (i == 0 || !id_eq(set, i - 1, d->refid))))
316 /* Before/after doesn't match */
317 return -IPSET_ERR_REF_EXIST;
318 if (!flag_exist)
319 /* Can't re-add */
320 return -IPSET_ERR_EXIST;
321 /* Update extensions */
322 if (SET_WITH_TIMEOUT(set))
323 ip_set_timeout_set(ext_timeout(e, map), ext->timeout);
324 if (SET_WITH_COUNTER(set))
325 ip_set_init_counter(ext_counter(e, map), ext);
326 /* Set is already added to the list */
327 ip_set_put_byindex(d->id);
328 return 0;
329 }
330insert:
331 ret = -IPSET_ERR_LIST_FULL;
332 for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) {
333 e = list_set_elem(map, i);
334 if (e->id == IPSET_INVALID_ID)
335 ret = d->before != 0 ? -IPSET_ERR_REF_EXIST
336 : list_set_add(set, i, d, ext);
337 else if (e->id != d->refid)
338 continue;
339 else if (d->before > 0)
340 ret = list_set_add(set, i, d, ext);
341 else if (i + 1 < map->size)
342 ret = list_set_add(set, i + 1, d, ext);
183 } 343 }
184 if (with_timeout(map->timeout))
185 list_elem_tadd(map, i, id, ip_set_timeout_set(timeout));
186 else
187 list_elem_add(map, i, id);
188 344
189 return 0; 345 return ret;
190} 346}
191 347
192static int 348static int
193list_set_del(struct list_set *map, u32 i) 349list_set_udel(struct ip_set *set, void *value, const struct ip_set_ext *ext,
350 struct ip_set_ext *mext, u32 flags)
194{ 351{
195 struct set_elem *a = list_set_elem(map, i), *b; 352 struct list_set *map = set->data;
196 353 struct set_adt_elem *d = value;
197 ip_set_put_byindex(a->id); 354 struct set_elem *e;
198
199 for (; i < map->size - 1; i++) {
200 b = list_set_elem(map, i + 1);
201 a->id = b->id;
202 if (with_timeout(map->timeout))
203 ((struct set_telem *)a)->timeout =
204 ((struct set_telem *)b)->timeout;
205 a = b;
206 if (a->id == IPSET_INVALID_ID)
207 break;
208 }
209 /* Last element */
210 a->id = IPSET_INVALID_ID;
211 return 0;
212}
213
214static void
215cleanup_entries(struct list_set *map)
216{
217 struct set_telem *e;
218 u32 i; 355 u32 i;
219 356
220 for (i = 0; i < map->size; i++) { 357 for (i = 0; i < map->size; i++) {
221 e = list_set_telem(map, i); 358 e = list_set_elem(map, i);
222 if (e->id != IPSET_INVALID_ID && list_set_expired(map, i)) 359 if (e->id == IPSET_INVALID_ID)
223 list_set_del(map, i); 360 return d->before != 0 ? -IPSET_ERR_REF_EXIST
361 : -IPSET_ERR_EXIST;
362 else if (SET_WITH_TIMEOUT(set) &&
363 ip_set_timeout_expired(ext_timeout(e, map)))
364 continue;
365 else if (e->id != d->id)
366 continue;
367
368 if (d->before == 0)
369 return list_set_del(set, i);
370 else if (d->before > 0) {
371 if (!id_eq(set, i + 1, d->refid))
372 return -IPSET_ERR_REF_EXIST;
373 return list_set_del(set, i);
374 } else if (i == 0 || !id_eq(set, i - 1, d->refid))
375 return -IPSET_ERR_REF_EXIST;
376 else
377 return list_set_del(set, i);
224 } 378 }
379 return -IPSET_ERR_EXIST;
225} 380}
226 381
227static int 382static int
@@ -229,26 +384,27 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
229 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) 384 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
230{ 385{
231 struct list_set *map = set->data; 386 struct list_set *map = set->data;
232 bool with_timeout = with_timeout(map->timeout); 387 ipset_adtfn adtfn = set->variant->adt[adt];
233 bool flag_exist = flags & IPSET_FLAG_EXIST; 388 struct set_adt_elem e = { .refid = IPSET_INVALID_ID };
234 int before = 0; 389 struct ip_set_ext ext = IP_SET_INIT_UEXT(map);
235 u32 timeout = map->timeout;
236 ip_set_id_t id, refid = IPSET_INVALID_ID;
237 const struct set_elem *elem;
238 struct ip_set *s; 390 struct ip_set *s;
239 u32 i;
240 int ret = 0; 391 int ret = 0;
241 392
242 if (unlikely(!tb[IPSET_ATTR_NAME] || 393 if (unlikely(!tb[IPSET_ATTR_NAME] ||
243 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) || 394 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
244 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS))) 395 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS) ||
396 !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
397 !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
245 return -IPSET_ERR_PROTOCOL; 398 return -IPSET_ERR_PROTOCOL;
246 399
247 if (tb[IPSET_ATTR_LINENO]) 400 if (tb[IPSET_ATTR_LINENO])
248 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]); 401 *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
249 402
250 id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s); 403 ret = ip_set_get_extensions(set, tb, &ext);
251 if (id == IPSET_INVALID_ID) 404 if (ret)
405 return ret;
406 e.id = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAME]), &s);
407 if (e.id == IPSET_INVALID_ID)
252 return -IPSET_ERR_NAME; 408 return -IPSET_ERR_NAME;
253 /* "Loop detection" */ 409 /* "Loop detection" */
254 if (s->type->features & IPSET_TYPE_NAME) { 410 if (s->type->features & IPSET_TYPE_NAME) {
@@ -258,115 +414,34 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
258 414
259 if (tb[IPSET_ATTR_CADT_FLAGS]) { 415 if (tb[IPSET_ATTR_CADT_FLAGS]) {
260 u32 f = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); 416 u32 f = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
261 before = f & IPSET_FLAG_BEFORE; 417 e.before = f & IPSET_FLAG_BEFORE;
262 } 418 }
263 419
264 if (before && !tb[IPSET_ATTR_NAMEREF]) { 420 if (e.before && !tb[IPSET_ATTR_NAMEREF]) {
265 ret = -IPSET_ERR_BEFORE; 421 ret = -IPSET_ERR_BEFORE;
266 goto finish; 422 goto finish;
267 } 423 }
268 424
269 if (tb[IPSET_ATTR_NAMEREF]) { 425 if (tb[IPSET_ATTR_NAMEREF]) {
270 refid = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAMEREF]), 426 e.refid = ip_set_get_byname(nla_data(tb[IPSET_ATTR_NAMEREF]),
271 &s); 427 &s);
272 if (refid == IPSET_INVALID_ID) { 428 if (e.refid == IPSET_INVALID_ID) {
273 ret = -IPSET_ERR_NAMEREF; 429 ret = -IPSET_ERR_NAMEREF;
274 goto finish; 430 goto finish;
275 } 431 }
276 if (!before) 432 if (!e.before)
277 before = -1; 433 e.before = -1;
278 }
279 if (tb[IPSET_ATTR_TIMEOUT]) {
280 if (!with_timeout) {
281 ret = -IPSET_ERR_TIMEOUT;
282 goto finish;
283 }
284 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
285 } 434 }
286 if (with_timeout && adt != IPSET_TEST) 435 if (adt != IPSET_TEST && SET_WITH_TIMEOUT(set))
287 cleanup_entries(map); 436 set_cleanup_entries(set);
288 437
289 switch (adt) { 438 ret = adtfn(set, &e, &ext, &ext, flags);
290 case IPSET_TEST:
291 for (i = 0; i < map->size && !ret; i++) {
292 elem = list_set_elem(map, i);
293 if (elem->id == IPSET_INVALID_ID ||
294 (before != 0 && i + 1 >= map->size))
295 break;
296 else if (with_timeout && list_set_expired(map, i))
297 continue;
298 else if (before > 0 && elem->id == id)
299 ret = id_eq_timeout(map, i + 1, refid);
300 else if (before < 0 && elem->id == refid)
301 ret = id_eq_timeout(map, i + 1, id);
302 else if (before == 0 && elem->id == id)
303 ret = 1;
304 }
305 break;
306 case IPSET_ADD:
307 for (i = 0; i < map->size; i++) {
308 elem = list_set_elem(map, i);
309 if (elem->id != id)
310 continue;
311 if (!(with_timeout && flag_exist)) {
312 ret = -IPSET_ERR_EXIST;
313 goto finish;
314 } else {
315 struct set_telem *e = list_set_telem(map, i);
316
317 if ((before > 1 &&
318 !id_eq(map, i + 1, refid)) ||
319 (before < 0 &&
320 (i == 0 || !id_eq(map, i - 1, refid)))) {
321 ret = -IPSET_ERR_EXIST;
322 goto finish;
323 }
324 e->timeout = ip_set_timeout_set(timeout);
325 ip_set_put_byindex(id);
326 ret = 0;
327 goto finish;
328 }
329 }
330 ret = -IPSET_ERR_LIST_FULL;
331 for (i = 0; i < map->size && ret == -IPSET_ERR_LIST_FULL; i++) {
332 elem = list_set_elem(map, i);
333 if (elem->id == IPSET_INVALID_ID)
334 ret = before != 0 ? -IPSET_ERR_REF_EXIST
335 : list_set_add(map, i, id, timeout);
336 else if (elem->id != refid)
337 continue;
338 else if (before > 0)
339 ret = list_set_add(map, i, id, timeout);
340 else if (i + 1 < map->size)
341 ret = list_set_add(map, i + 1, id, timeout);
342 }
343 break;
344 case IPSET_DEL:
345 ret = -IPSET_ERR_EXIST;
346 for (i = 0; i < map->size && ret == -IPSET_ERR_EXIST; i++) {
347 elem = list_set_elem(map, i);
348 if (elem->id == IPSET_INVALID_ID) {
349 ret = before != 0 ? -IPSET_ERR_REF_EXIST
350 : -IPSET_ERR_EXIST;
351 break;
352 } else if (elem->id == id &&
353 (before == 0 ||
354 (before > 0 && id_eq(map, i + 1, refid))))
355 ret = list_set_del(map, i);
356 else if (elem->id == refid &&
357 before < 0 && id_eq(map, i + 1, id))
358 ret = list_set_del(map, i + 1);
359 }
360 break;
361 default:
362 break;
363 }
364 439
365finish: 440finish:
366 if (refid != IPSET_INVALID_ID) 441 if (e.refid != IPSET_INVALID_ID)
367 ip_set_put_byindex(refid); 442 ip_set_put_byindex(e.refid);
368 if (adt != IPSET_ADD || ret) 443 if (adt != IPSET_ADD || ret)
369 ip_set_put_byindex(id); 444 ip_set_put_byindex(e.id);
370 445
371 return ip_set_eexist(ret, flags) ? 0 : ret; 446 return ip_set_eexist(ret, flags) ? 0 : ret;
372} 447}
@@ -375,14 +450,14 @@ static void
375list_set_flush(struct ip_set *set) 450list_set_flush(struct ip_set *set)
376{ 451{
377 struct list_set *map = set->data; 452 struct list_set *map = set->data;
378 struct set_elem *elem; 453 struct set_elem *e;
379 u32 i; 454 u32 i;
380 455
381 for (i = 0; i < map->size; i++) { 456 for (i = 0; i < map->size; i++) {
382 elem = list_set_elem(map, i); 457 e = list_set_elem(map, i);
383 if (elem->id != IPSET_INVALID_ID) { 458 if (e->id != IPSET_INVALID_ID) {
384 ip_set_put_byindex(elem->id); 459 ip_set_put_byindex(e->id);
385 elem->id = IPSET_INVALID_ID; 460 e->id = IPSET_INVALID_ID;
386 } 461 }
387 } 462 }
388} 463}
@@ -392,7 +467,7 @@ list_set_destroy(struct ip_set *set)
392{ 467{
393 struct list_set *map = set->data; 468 struct list_set *map = set->data;
394 469
395 if (with_timeout(map->timeout)) 470 if (SET_WITH_TIMEOUT(set))
396 del_timer_sync(&map->gc); 471 del_timer_sync(&map->gc);
397 list_set_flush(set); 472 list_set_flush(set);
398 kfree(map); 473 kfree(map);
@@ -410,8 +485,11 @@ list_set_head(struct ip_set *set, struct sk_buff *skb)
410 if (!nested) 485 if (!nested)
411 goto nla_put_failure; 486 goto nla_put_failure;
412 if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) || 487 if (nla_put_net32(skb, IPSET_ATTR_SIZE, htonl(map->size)) ||
413 (with_timeout(map->timeout) && 488 (SET_WITH_TIMEOUT(set) &&
414 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) || 489 nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) ||
490 (SET_WITH_COUNTER(set) &&
491 nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
492 htonl(IPSET_FLAG_WITH_COUNTERS))) ||
415 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || 493 nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
416 nla_put_net32(skb, IPSET_ATTR_MEMSIZE, 494 nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
417 htonl(sizeof(*map) + map->size * map->dsize))) 495 htonl(sizeof(*map) + map->size * map->dsize)))
@@ -440,7 +518,8 @@ list_set_list(const struct ip_set *set,
440 e = list_set_elem(map, i); 518 e = list_set_elem(map, i);
441 if (e->id == IPSET_INVALID_ID) 519 if (e->id == IPSET_INVALID_ID)
442 goto finish; 520 goto finish;
443 if (with_timeout(map->timeout) && list_set_expired(map, i)) 521 if (SET_WITH_TIMEOUT(set) &&
522 ip_set_timeout_expired(ext_timeout(e, map)))
444 continue; 523 continue;
445 nested = ipset_nest_start(skb, IPSET_ATTR_DATA); 524 nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
446 if (!nested) { 525 if (!nested) {
@@ -453,13 +532,14 @@ list_set_list(const struct ip_set *set,
453 if (nla_put_string(skb, IPSET_ATTR_NAME, 532 if (nla_put_string(skb, IPSET_ATTR_NAME,
454 ip_set_name_byindex(e->id))) 533 ip_set_name_byindex(e->id)))
455 goto nla_put_failure; 534 goto nla_put_failure;
456 if (with_timeout(map->timeout)) { 535 if (SET_WITH_TIMEOUT(set) &&
457 const struct set_telem *te = 536 nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
458 (const struct set_telem *) e; 537 htonl(ip_set_timeout_get(
459 __be32 to = htonl(ip_set_timeout_get(te->timeout)); 538 ext_timeout(e, map)))))
460 if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT, to)) 539 goto nla_put_failure;
461 goto nla_put_failure; 540 if (SET_WITH_COUNTER(set) &&
462 } 541 ip_set_put_counter(skb, ext_counter(e, map)))
542 goto nla_put_failure;
463 ipset_nest_end(skb, nested); 543 ipset_nest_end(skb, nested);
464 } 544 }
465finish: 545finish:
@@ -485,12 +565,18 @@ list_set_same_set(const struct ip_set *a, const struct ip_set *b)
485 const struct list_set *y = b->data; 565 const struct list_set *y = b->data;
486 566
487 return x->size == y->size && 567 return x->size == y->size &&
488 x->timeout == y->timeout; 568 x->timeout == y->timeout &&
569 a->extensions == b->extensions;
489} 570}
490 571
491static const struct ip_set_type_variant list_set = { 572static const struct ip_set_type_variant set_variant = {
492 .kadt = list_set_kadt, 573 .kadt = list_set_kadt,
493 .uadt = list_set_uadt, 574 .uadt = list_set_uadt,
575 .adt = {
576 [IPSET_ADD] = list_set_uadd,
577 [IPSET_DEL] = list_set_udel,
578 [IPSET_TEST] = list_set_utest,
579 },
494 .destroy = list_set_destroy, 580 .destroy = list_set_destroy,
495 .flush = list_set_flush, 581 .flush = list_set_flush,
496 .head = list_set_head, 582 .head = list_set_head,
@@ -505,7 +591,7 @@ list_set_gc(unsigned long ul_set)
505 struct list_set *map = set->data; 591 struct list_set *map = set->data;
506 592
507 write_lock_bh(&set->lock); 593 write_lock_bh(&set->lock);
508 cleanup_entries(map); 594 set_cleanup_entries(set);
509 write_unlock_bh(&set->lock); 595 write_unlock_bh(&set->lock);
510 596
511 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 597 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
@@ -513,20 +599,20 @@ list_set_gc(unsigned long ul_set)
513} 599}
514 600
515static void 601static void
516list_set_gc_init(struct ip_set *set) 602list_set_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
517{ 603{
518 struct list_set *map = set->data; 604 struct list_set *map = set->data;
519 605
520 init_timer(&map->gc); 606 init_timer(&map->gc);
521 map->gc.data = (unsigned long) set; 607 map->gc.data = (unsigned long) set;
522 map->gc.function = list_set_gc; 608 map->gc.function = gc;
523 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; 609 map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
524 add_timer(&map->gc); 610 add_timer(&map->gc);
525} 611}
526 612
527/* Create list:set type of sets */ 613/* Create list:set type of sets */
528 614
529static bool 615static struct list_set *
530init_list_set(struct ip_set *set, u32 size, size_t dsize, 616init_list_set(struct ip_set *set, u32 size, size_t dsize,
531 unsigned long timeout) 617 unsigned long timeout)
532{ 618{
@@ -536,7 +622,7 @@ init_list_set(struct ip_set *set, u32 size, size_t dsize,
536 622
537 map = kzalloc(sizeof(*map) + size * dsize, GFP_KERNEL); 623 map = kzalloc(sizeof(*map) + size * dsize, GFP_KERNEL);
538 if (!map) 624 if (!map)
539 return false; 625 return NULL;
540 626
541 map->size = size; 627 map->size = size;
542 map->dsize = dsize; 628 map->dsize = dsize;
@@ -548,16 +634,19 @@ init_list_set(struct ip_set *set, u32 size, size_t dsize,
548 e->id = IPSET_INVALID_ID; 634 e->id = IPSET_INVALID_ID;
549 } 635 }
550 636
551 return true; 637 return map;
552} 638}
553 639
554static int 640static int
555list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags) 641list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
556{ 642{
557 u32 size = IP_SET_LIST_DEFAULT_SIZE; 643 struct list_set *map;
644 u32 size = IP_SET_LIST_DEFAULT_SIZE, cadt_flags = 0;
645 unsigned long timeout = 0;
558 646
559 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) || 647 if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_SIZE) ||
560 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT))) 648 !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
649 !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
561 return -IPSET_ERR_PROTOCOL; 650 return -IPSET_ERR_PROTOCOL;
562 651
563 if (tb[IPSET_ATTR_SIZE]) 652 if (tb[IPSET_ATTR_SIZE])
@@ -565,18 +654,46 @@ list_set_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
565 if (size < IP_SET_LIST_MIN_SIZE) 654 if (size < IP_SET_LIST_MIN_SIZE)
566 size = IP_SET_LIST_MIN_SIZE; 655 size = IP_SET_LIST_MIN_SIZE;
567 656
568 if (tb[IPSET_ATTR_TIMEOUT]) { 657 if (tb[IPSET_ATTR_CADT_FLAGS])
569 if (!init_list_set(set, size, sizeof(struct set_telem), 658 cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
570 ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]))) 659 if (tb[IPSET_ATTR_TIMEOUT])
660 timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
661 set->variant = &set_variant;
662 if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
663 set->extensions |= IPSET_EXT_COUNTER;
664 if (tb[IPSET_ATTR_TIMEOUT]) {
665 map = init_list_set(set, size,
666 sizeof(struct setct_elem), timeout);
667 if (!map)
668 return -ENOMEM;
669 set->extensions |= IPSET_EXT_TIMEOUT;
670 map->offset[IPSET_OFFSET_TIMEOUT] =
671 offsetof(struct setct_elem, timeout);
672 map->offset[IPSET_OFFSET_COUNTER] =
673 offsetof(struct setct_elem, counter);
674 list_set_gc_init(set, list_set_gc);
675 } else {
676 map = init_list_set(set, size,
677 sizeof(struct setc_elem), 0);
678 if (!map)
679 return -ENOMEM;
680 map->offset[IPSET_OFFSET_COUNTER] =
681 offsetof(struct setc_elem, counter);
682 }
683 } else if (tb[IPSET_ATTR_TIMEOUT]) {
684 map = init_list_set(set, size,
685 sizeof(struct sett_elem), timeout);
686 if (!map)
571 return -ENOMEM; 687 return -ENOMEM;
572 688 set->extensions |= IPSET_EXT_TIMEOUT;
573 list_set_gc_init(set); 689 map->offset[IPSET_OFFSET_TIMEOUT] =
690 offsetof(struct sett_elem, timeout);
691 list_set_gc_init(set, list_set_gc);
574 } else { 692 } else {
575 if (!init_list_set(set, size, sizeof(struct set_elem), 693 map = init_list_set(set, size, sizeof(struct set_elem), 0);
576 IPSET_NO_TIMEOUT)) 694 if (!map)
577 return -ENOMEM; 695 return -ENOMEM;
578 } 696 }
579 set->variant = &list_set;
580 return 0; 697 return 0;
581} 698}
582 699
@@ -592,6 +709,7 @@ static struct ip_set_type list_set_type __read_mostly = {
592 .create_policy = { 709 .create_policy = {
593 [IPSET_ATTR_SIZE] = { .type = NLA_U32 }, 710 [IPSET_ATTR_SIZE] = { .type = NLA_U32 },
594 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 711 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
712 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
595 }, 713 },
596 .adt_policy = { 714 .adt_policy = {
597 [IPSET_ATTR_NAME] = { .type = NLA_STRING, 715 [IPSET_ATTR_NAME] = { .type = NLA_STRING,
@@ -601,6 +719,8 @@ static struct ip_set_type list_set_type __read_mostly = {
601 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 }, 719 [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
602 [IPSET_ATTR_LINENO] = { .type = NLA_U32 }, 720 [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
603 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, 721 [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
722 [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
723 [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
604 }, 724 },
605 .me = THIS_MODULE, 725 .me = THIS_MODULE,
606}; 726};
diff --git a/net/netfilter/nf_nat_proto_sctp.c b/net/netfilter/nf_nat_proto_sctp.c
index e64faa5ca893..396e55d46f90 100644
--- a/net/netfilter/nf_nat_proto_sctp.c
+++ b/net/netfilter/nf_nat_proto_sctp.c
@@ -36,7 +36,7 @@ sctp_manip_pkt(struct sk_buff *skb,
36{ 36{
37 struct sk_buff *frag; 37 struct sk_buff *frag;
38 sctp_sctphdr_t *hdr; 38 sctp_sctphdr_t *hdr;
39 __be32 crc32; 39 __u32 crc32;
40 40
41 if (!skb_make_writable(skb, hdroff + sizeof(*hdr))) 41 if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
42 return false; 42 return false;
@@ -55,8 +55,7 @@ sctp_manip_pkt(struct sk_buff *skb,
55 skb_walk_frags(skb, frag) 55 skb_walk_frags(skb, frag)
56 crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag), 56 crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag),
57 crc32); 57 crc32);
58 crc32 = sctp_end_cksum(crc32); 58 hdr->checksum = sctp_end_cksum(crc32);
59 hdr->checksum = crc32;
60 59
61 return true; 60 return true;
62} 61}
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 5ccf01e35390..5d24b1fdb593 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -45,7 +45,7 @@ void nf_unregister_queue_handler(void)
45} 45}
46EXPORT_SYMBOL(nf_unregister_queue_handler); 46EXPORT_SYMBOL(nf_unregister_queue_handler);
47 47
48static void nf_queue_entry_release_refs(struct nf_queue_entry *entry) 48void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
49{ 49{
50 /* Release those devices we held, or Alexey will kill me. */ 50 /* Release those devices we held, or Alexey will kill me. */
51 if (entry->indev) 51 if (entry->indev)
@@ -65,12 +65,41 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
65 /* Drop reference to owner of hook which queued us. */ 65 /* Drop reference to owner of hook which queued us. */
66 module_put(entry->elem->owner); 66 module_put(entry->elem->owner);
67} 67}
68EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
69
70/* Bump dev refs so they don't vanish while packet is out */
71bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
72{
73 if (!try_module_get(entry->elem->owner))
74 return false;
75
76 if (entry->indev)
77 dev_hold(entry->indev);
78 if (entry->outdev)
79 dev_hold(entry->outdev);
80#ifdef CONFIG_BRIDGE_NETFILTER
81 if (entry->skb->nf_bridge) {
82 struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
83 struct net_device *physdev;
84
85 physdev = nf_bridge->physindev;
86 if (physdev)
87 dev_hold(physdev);
88 physdev = nf_bridge->physoutdev;
89 if (physdev)
90 dev_hold(physdev);
91 }
92#endif
93
94 return true;
95}
96EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
68 97
69/* 98/*
70 * Any packet that leaves via this function must come back 99 * Any packet that leaves via this function must come back
71 * through nf_reinject(). 100 * through nf_reinject().
72 */ 101 */
73static int __nf_queue(struct sk_buff *skb, 102int nf_queue(struct sk_buff *skb,
74 struct nf_hook_ops *elem, 103 struct nf_hook_ops *elem,
75 u_int8_t pf, unsigned int hook, 104 u_int8_t pf, unsigned int hook,
76 struct net_device *indev, 105 struct net_device *indev,
@@ -80,10 +109,6 @@ static int __nf_queue(struct sk_buff *skb,
80{ 109{
81 int status = -ENOENT; 110 int status = -ENOENT;
82 struct nf_queue_entry *entry = NULL; 111 struct nf_queue_entry *entry = NULL;
83#ifdef CONFIG_BRIDGE_NETFILTER
84 struct net_device *physindev;
85 struct net_device *physoutdev;
86#endif
87 const struct nf_afinfo *afinfo; 112 const struct nf_afinfo *afinfo;
88 const struct nf_queue_handler *qh; 113 const struct nf_queue_handler *qh;
89 114
@@ -114,28 +139,13 @@ static int __nf_queue(struct sk_buff *skb,
114 .indev = indev, 139 .indev = indev,
115 .outdev = outdev, 140 .outdev = outdev,
116 .okfn = okfn, 141 .okfn = okfn,
142 .size = sizeof(*entry) + afinfo->route_key_size,
117 }; 143 };
118 144
119 /* If it's going away, ignore hook. */ 145 if (!nf_queue_entry_get_refs(entry)) {
120 if (!try_module_get(entry->elem->owner)) {
121 status = -ECANCELED; 146 status = -ECANCELED;
122 goto err_unlock; 147 goto err_unlock;
123 } 148 }
124 /* Bump dev refs so they don't vanish while packet is out */
125 if (indev)
126 dev_hold(indev);
127 if (outdev)
128 dev_hold(outdev);
129#ifdef CONFIG_BRIDGE_NETFILTER
130 if (skb->nf_bridge) {
131 physindev = skb->nf_bridge->physindev;
132 if (physindev)
133 dev_hold(physindev);
134 physoutdev = skb->nf_bridge->physoutdev;
135 if (physoutdev)
136 dev_hold(physoutdev);
137 }
138#endif
139 skb_dst_force(skb); 149 skb_dst_force(skb);
140 afinfo->saveroute(skb, entry); 150 afinfo->saveroute(skb, entry);
141 status = qh->outfn(entry, queuenum); 151 status = qh->outfn(entry, queuenum);
@@ -156,87 +166,6 @@ err:
156 return status; 166 return status;
157} 167}
158 168
159#ifdef CONFIG_BRIDGE_NETFILTER
160/* When called from bridge netfilter, skb->data must point to MAC header
161 * before calling skb_gso_segment(). Else, original MAC header is lost
162 * and segmented skbs will be sent to wrong destination.
163 */
164static void nf_bridge_adjust_skb_data(struct sk_buff *skb)
165{
166 if (skb->nf_bridge)
167 __skb_push(skb, skb->network_header - skb->mac_header);
168}
169
170static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
171{
172 if (skb->nf_bridge)
173 __skb_pull(skb, skb->network_header - skb->mac_header);
174}
175#else
176#define nf_bridge_adjust_skb_data(s) do {} while (0)
177#define nf_bridge_adjust_segmented_data(s) do {} while (0)
178#endif
179
180int nf_queue(struct sk_buff *skb,
181 struct nf_hook_ops *elem,
182 u_int8_t pf, unsigned int hook,
183 struct net_device *indev,
184 struct net_device *outdev,
185 int (*okfn)(struct sk_buff *),
186 unsigned int queuenum)
187{
188 struct sk_buff *segs;
189 int err = -EINVAL;
190 unsigned int queued;
191
192 if (!skb_is_gso(skb))
193 return __nf_queue(skb, elem, pf, hook, indev, outdev, okfn,
194 queuenum);
195
196 switch (pf) {
197 case NFPROTO_IPV4:
198 skb->protocol = htons(ETH_P_IP);
199 break;
200 case NFPROTO_IPV6:
201 skb->protocol = htons(ETH_P_IPV6);
202 break;
203 }
204
205 nf_bridge_adjust_skb_data(skb);
206 segs = skb_gso_segment(skb, 0);
207 /* Does not use PTR_ERR to limit the number of error codes that can be
208 * returned by nf_queue. For instance, callers rely on -ECANCELED to mean
209 * 'ignore this hook'.
210 */
211 if (IS_ERR(segs))
212 goto out_err;
213 queued = 0;
214 err = 0;
215 do {
216 struct sk_buff *nskb = segs->next;
217
218 segs->next = NULL;
219 if (err == 0) {
220 nf_bridge_adjust_segmented_data(segs);
221 err = __nf_queue(segs, elem, pf, hook, indev,
222 outdev, okfn, queuenum);
223 }
224 if (err == 0)
225 queued++;
226 else
227 kfree_skb(segs);
228 segs = nskb;
229 } while (segs);
230
231 if (queued) {
232 kfree_skb(skb);
233 return 0;
234 }
235 out_err:
236 nf_bridge_adjust_segmented_data(skb);
237 return err;
238}
239
240void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 169void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
241{ 170{
242 struct sk_buff *skb = entry->skb; 171 struct sk_buff *skb = entry->skb;
@@ -276,9 +205,9 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
276 local_bh_enable(); 205 local_bh_enable();
277 break; 206 break;
278 case NF_QUEUE: 207 case NF_QUEUE:
279 err = __nf_queue(skb, elem, entry->pf, entry->hook, 208 err = nf_queue(skb, elem, entry->pf, entry->hook,
280 entry->indev, entry->outdev, entry->okfn, 209 entry->indev, entry->outdev, entry->okfn,
281 verdict >> NF_VERDICT_QBITS); 210 verdict >> NF_VERDICT_QBITS);
282 if (err < 0) { 211 if (err < 0) {
283 if (err == -ECANCELED) 212 if (err == -ECANCELED)
284 goto next_hook; 213 goto next_hook;
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index ef3cdb4bfeea..2e0e835baf72 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -272,6 +272,18 @@ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
272 skb_shinfo(to)->nr_frags = j; 272 skb_shinfo(to)->nr_frags = j;
273} 273}
274 274
275static int nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet)
276{
277 __u32 flags = 0;
278
279 if (packet->ip_summed == CHECKSUM_PARTIAL)
280 flags = NFQA_SKB_CSUMNOTREADY;
281 if (skb_is_gso(packet))
282 flags |= NFQA_SKB_GSO;
283
284 return flags ? nla_put_be32(nlskb, NFQA_SKB_INFO, htonl(flags)) : 0;
285}
286
275static struct sk_buff * 287static struct sk_buff *
276nfqnl_build_packet_message(struct nfqnl_instance *queue, 288nfqnl_build_packet_message(struct nfqnl_instance *queue,
277 struct nf_queue_entry *entry, 289 struct nf_queue_entry *entry,
@@ -301,6 +313,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
301#endif 313#endif
302 + nla_total_size(sizeof(u_int32_t)) /* mark */ 314 + nla_total_size(sizeof(u_int32_t)) /* mark */
303 + nla_total_size(sizeof(struct nfqnl_msg_packet_hw)) 315 + nla_total_size(sizeof(struct nfqnl_msg_packet_hw))
316 + nla_total_size(sizeof(u_int32_t)) /* skbinfo */
304 + nla_total_size(sizeof(u_int32_t)); /* cap_len */ 317 + nla_total_size(sizeof(u_int32_t)); /* cap_len */
305 318
306 if (entskb->tstamp.tv64) 319 if (entskb->tstamp.tv64)
@@ -314,7 +327,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
314 break; 327 break;
315 328
316 case NFQNL_COPY_PACKET: 329 case NFQNL_COPY_PACKET:
317 if (entskb->ip_summed == CHECKSUM_PARTIAL && 330 if (!(queue->flags & NFQA_CFG_F_GSO) &&
331 entskb->ip_summed == CHECKSUM_PARTIAL &&
318 skb_checksum_help(entskb)) 332 skb_checksum_help(entskb))
319 return NULL; 333 return NULL;
320 334
@@ -454,6 +468,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
454 if (cap_len > 0 && nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len))) 468 if (cap_len > 0 && nla_put_be32(skb, NFQA_CAP_LEN, htonl(cap_len)))
455 goto nla_put_failure; 469 goto nla_put_failure;
456 470
471 if (nfqnl_put_packet_info(skb, entskb))
472 goto nla_put_failure;
473
457 if (data_len) { 474 if (data_len) {
458 struct nlattr *nla; 475 struct nlattr *nla;
459 476
@@ -477,28 +494,13 @@ nla_put_failure:
477} 494}
478 495
479static int 496static int
480nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) 497__nfqnl_enqueue_packet(struct net *net, struct nfqnl_instance *queue,
498 struct nf_queue_entry *entry)
481{ 499{
482 struct sk_buff *nskb; 500 struct sk_buff *nskb;
483 struct nfqnl_instance *queue;
484 int err = -ENOBUFS; 501 int err = -ENOBUFS;
485 __be32 *packet_id_ptr; 502 __be32 *packet_id_ptr;
486 int failopen = 0; 503 int failopen = 0;
487 struct net *net = dev_net(entry->indev ?
488 entry->indev : entry->outdev);
489 struct nfnl_queue_net *q = nfnl_queue_pernet(net);
490
491 /* rcu_read_lock()ed by nf_hook_slow() */
492 queue = instance_lookup(q, queuenum);
493 if (!queue) {
494 err = -ESRCH;
495 goto err_out;
496 }
497
498 if (queue->copy_mode == NFQNL_COPY_NONE) {
499 err = -EINVAL;
500 goto err_out;
501 }
502 504
503 nskb = nfqnl_build_packet_message(queue, entry, &packet_id_ptr); 505 nskb = nfqnl_build_packet_message(queue, entry, &packet_id_ptr);
504 if (nskb == NULL) { 506 if (nskb == NULL) {
@@ -547,6 +549,141 @@ err_out:
547 return err; 549 return err;
548} 550}
549 551
552static struct nf_queue_entry *
553nf_queue_entry_dup(struct nf_queue_entry *e)
554{
555 struct nf_queue_entry *entry = kmemdup(e, e->size, GFP_ATOMIC);
556 if (entry) {
557 if (nf_queue_entry_get_refs(entry))
558 return entry;
559 kfree(entry);
560 }
561 return NULL;
562}
563
564#ifdef CONFIG_BRIDGE_NETFILTER
565/* When called from bridge netfilter, skb->data must point to MAC header
566 * before calling skb_gso_segment(). Else, original MAC header is lost
567 * and segmented skbs will be sent to wrong destination.
568 */
569static void nf_bridge_adjust_skb_data(struct sk_buff *skb)
570{
571 if (skb->nf_bridge)
572 __skb_push(skb, skb->network_header - skb->mac_header);
573}
574
575static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
576{
577 if (skb->nf_bridge)
578 __skb_pull(skb, skb->network_header - skb->mac_header);
579}
580#else
581#define nf_bridge_adjust_skb_data(s) do {} while (0)
582#define nf_bridge_adjust_segmented_data(s) do {} while (0)
583#endif
584
585static void free_entry(struct nf_queue_entry *entry)
586{
587 nf_queue_entry_release_refs(entry);
588 kfree(entry);
589}
590
591static int
592__nfqnl_enqueue_packet_gso(struct net *net, struct nfqnl_instance *queue,
593 struct sk_buff *skb, struct nf_queue_entry *entry)
594{
595 int ret = -ENOMEM;
596 struct nf_queue_entry *entry_seg;
597
598 nf_bridge_adjust_segmented_data(skb);
599
600 if (skb->next == NULL) { /* last packet, no need to copy entry */
601 struct sk_buff *gso_skb = entry->skb;
602 entry->skb = skb;
603 ret = __nfqnl_enqueue_packet(net, queue, entry);
604 if (ret)
605 entry->skb = gso_skb;
606 return ret;
607 }
608
609 skb->next = NULL;
610
611 entry_seg = nf_queue_entry_dup(entry);
612 if (entry_seg) {
613 entry_seg->skb = skb;
614 ret = __nfqnl_enqueue_packet(net, queue, entry_seg);
615 if (ret)
616 free_entry(entry_seg);
617 }
618 return ret;
619}
620
621static int
622nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
623{
624 unsigned int queued;
625 struct nfqnl_instance *queue;
626 struct sk_buff *skb, *segs;
627 int err = -ENOBUFS;
628 struct net *net = dev_net(entry->indev ?
629 entry->indev : entry->outdev);
630 struct nfnl_queue_net *q = nfnl_queue_pernet(net);
631
632 /* rcu_read_lock()ed by nf_hook_slow() */
633 queue = instance_lookup(q, queuenum);
634 if (!queue)
635 return -ESRCH;
636
637 if (queue->copy_mode == NFQNL_COPY_NONE)
638 return -EINVAL;
639
640 if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(entry->skb))
641 return __nfqnl_enqueue_packet(net, queue, entry);
642
643 skb = entry->skb;
644
645 switch (entry->pf) {
646 case NFPROTO_IPV4:
647 skb->protocol = htons(ETH_P_IP);
648 break;
649 case NFPROTO_IPV6:
650 skb->protocol = htons(ETH_P_IPV6);
651 break;
652 }
653
654 nf_bridge_adjust_skb_data(skb);
655 segs = skb_gso_segment(skb, 0);
656 /* Does not use PTR_ERR to limit the number of error codes that can be
657 * returned by nf_queue. For instance, callers rely on -ECANCELED to
658 * mean 'ignore this hook'.
659 */
660 if (IS_ERR(segs))
661 goto out_err;
662 queued = 0;
663 err = 0;
664 do {
665 struct sk_buff *nskb = segs->next;
666 if (err == 0)
667 err = __nfqnl_enqueue_packet_gso(net, queue,
668 segs, entry);
669 if (err == 0)
670 queued++;
671 else
672 kfree_skb(segs);
673 segs = nskb;
674 } while (segs);
675
676 if (queued) {
677 if (err) /* some segments are already queued */
678 free_entry(entry);
679 kfree_skb(skb);
680 return 0;
681 }
682 out_err:
683 nf_bridge_adjust_segmented_data(skb);
684 return err;
685}
686
550static int 687static int
551nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e, int diff) 688nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e, int diff)
552{ 689{
diff --git a/net/netfilter/xt_set.c b/net/netfilter/xt_set.c
index 865a9e54f3ad..31790e789e22 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 */
@@ -197,6 +189,9 @@ set_match_v1(const struct sk_buff *skb, struct xt_action_param *par)
197 ADT_OPT(opt, par->family, info->match_set.dim, 189 ADT_OPT(opt, par->family, info->match_set.dim,
198 info->match_set.flags, 0, UINT_MAX); 190 info->match_set.flags, 0, UINT_MAX);
199 191
192 if (opt.flags & IPSET_RETURN_NOMATCH)
193 opt.cmdflags |= IPSET_FLAG_RETURN_NOMATCH;
194
200 return match_set(info->match_set.index, skb, par, &opt, 195 return match_set(info->match_set.index, skb, par, &opt,
201 info->match_set.flags & IPSET_INV_MATCH); 196 info->match_set.flags & IPSET_INV_MATCH);
202} 197}
@@ -305,15 +300,15 @@ static unsigned int
305set_target_v2(struct sk_buff *skb, const struct xt_action_param *par) 300set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
306{ 301{
307 const struct xt_set_info_target_v2 *info = par->targinfo; 302 const struct xt_set_info_target_v2 *info = par->targinfo;
308 ADT_MOPT(add_opt, par->family, info->add_set.dim, 303 ADT_OPT(add_opt, par->family, info->add_set.dim,
309 info->add_set.flags, info->flags, info->timeout); 304 info->add_set.flags, info->flags, info->timeout);
310 ADT_OPT(del_opt, par->family, info->del_set.dim, 305 ADT_OPT(del_opt, par->family, info->del_set.dim,
311 info->del_set.flags, 0, UINT_MAX); 306 info->del_set.flags, 0, UINT_MAX);
312 307
313 /* Normalize to fit into jiffies */ 308 /* Normalize to fit into jiffies */
314 if (add_opt.timeout != IPSET_NO_TIMEOUT && 309 if (add_opt.ext.timeout != IPSET_NO_TIMEOUT &&
315 add_opt.timeout > UINT_MAX/MSEC_PER_SEC) 310 add_opt.ext.timeout > UINT_MAX/MSEC_PER_SEC)
316 add_opt.timeout = UINT_MAX/MSEC_PER_SEC; 311 add_opt.ext.timeout = UINT_MAX/MSEC_PER_SEC;
317 if (info->add_set.index != IPSET_INVALID_ID) 312 if (info->add_set.index != IPSET_INVALID_ID)
318 ip_set_add(info->add_set.index, skb, par, &add_opt); 313 ip_set_add(info->add_set.index, skb, par, &add_opt);
319 if (info->del_set.index != IPSET_INVALID_ID) 314 if (info->del_set.index != IPSET_INVALID_ID)
@@ -325,6 +320,52 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
325#define set_target_v2_checkentry set_target_v1_checkentry 320#define set_target_v2_checkentry set_target_v1_checkentry
326#define set_target_v2_destroy set_target_v1_destroy 321#define set_target_v2_destroy set_target_v1_destroy
327 322
323/* Revision 3 match */
324
325static bool
326match_counter(u64 counter, const struct ip_set_counter_match *info)
327{
328 switch (info->op) {
329 case IPSET_COUNTER_NONE:
330 return true;
331 case IPSET_COUNTER_EQ:
332 return counter == info->value;
333 case IPSET_COUNTER_NE:
334 return counter != info->value;
335 case IPSET_COUNTER_LT:
336 return counter < info->value;
337 case IPSET_COUNTER_GT:
338 return counter > info->value;
339 }
340 return false;
341}
342
343static bool
344set_match_v3(const struct sk_buff *skb, struct xt_action_param *par)
345{
346 const struct xt_set_info_match_v3 *info = par->matchinfo;
347 ADT_OPT(opt, par->family, info->match_set.dim,
348 info->match_set.flags, info->flags, UINT_MAX);
349 int ret;
350
351 if (info->packets.op != IPSET_COUNTER_NONE ||
352 info->bytes.op != IPSET_COUNTER_NONE)
353 opt.cmdflags |= IPSET_FLAG_MATCH_COUNTERS;
354
355 ret = match_set(info->match_set.index, skb, par, &opt,
356 info->match_set.flags & IPSET_INV_MATCH);
357
358 if (!(ret && opt.cmdflags & IPSET_FLAG_MATCH_COUNTERS))
359 return ret;
360
361 if (!match_counter(opt.ext.packets, &info->packets))
362 return 0;
363 return match_counter(opt.ext.bytes, &info->bytes);
364}
365
366#define set_match_v3_checkentry set_match_v1_checkentry
367#define set_match_v3_destroy set_match_v1_destroy
368
328static struct xt_match set_matches[] __read_mostly = { 369static struct xt_match set_matches[] __read_mostly = {
329 { 370 {
330 .name = "set", 371 .name = "set",
@@ -377,6 +418,27 @@ static struct xt_match set_matches[] __read_mostly = {
377 .destroy = set_match_v1_destroy, 418 .destroy = set_match_v1_destroy,
378 .me = THIS_MODULE 419 .me = THIS_MODULE
379 }, 420 },
421 /* counters support: update, match */
422 {
423 .name = "set",
424 .family = NFPROTO_IPV4,
425 .revision = 3,
426 .match = set_match_v3,
427 .matchsize = sizeof(struct xt_set_info_match_v3),
428 .checkentry = set_match_v3_checkentry,
429 .destroy = set_match_v3_destroy,
430 .me = THIS_MODULE
431 },
432 {
433 .name = "set",
434 .family = NFPROTO_IPV6,
435 .revision = 3,
436 .match = set_match_v3,
437 .matchsize = sizeof(struct xt_set_info_match_v3),
438 .checkentry = set_match_v3_checkentry,
439 .destroy = set_match_v3_destroy,
440 .me = THIS_MODULE
441 },
380}; 442};
381 443
382static struct xt_target set_targets[] __read_mostly = { 444static struct xt_target set_targets[] __read_mostly = {
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);